android h5 input file 的適配和小米手機調起系統相冊無效的Bug

適配h5中 < input file>調起相機和相冊的功能代碼:




    private ValueCallback<Uri> uploadMessage;
    private ValueCallback<Uri[]> uploadMessageAboveL;
    private String mCurrentPhotoPath;
    private String mLastPhothPath;
    private Thread mThread;
    
    .......
    
public class MyWebChromeClient extends WebChromeClient
    {

        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result)
        {
            Log.i(TAG, "onJsAlert: " + message);
            return super.onJsAlert(view, url, message, result);
        }

        @Override
        public boolean onJsConfirm(WebView view, String url, String message, JsResult result)
        {
            Log.i(TAG, "onJsConfirm: " + message);
            return super.onJsConfirm(view, url, message, result);
        }

        @Override
        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)
        {
            Log.i(TAG, "onJsPrompt: " + message);
            return super.onJsPrompt(view, url, message, defaultValue, result);
        }

        @Override
        public void onReceivedTitle(WebView view, String title)
        {
            super.onReceivedTitle(view, title);
        }

        @Override
        public void onProgressChanged(WebView view, int newProgress)
        {
            if (newProgress == 100)
            {
                progressBar.setVisibility(View.GONE);
            }
            else
            {
                if (progressBar.getVisibility() == View.GONE)
                    progressBar.setVisibility(View.VISIBLE);
                progressBar.setProgress(newProgress);
            }

            super.onProgressChanged(view, newProgress);
        }

        //For Android  >= 5.0
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams)
        {

            uploadMessageAboveL = filePathCallback;
            uploadPicture();
            return true;
        }


        //For Android  >= 4.1
        public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture)
        {

            uploadMessage = valueCallback;
            uploadPicture();

        }

    }

    Handler mHandler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            super.handleMessage(msg);
            takePhoto();
        }
    };




 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {

        if (requestCode == REQUEST_CODE_ALBUM || requestCode == REQUEST_CODE_CAMERA)
        {

            if (uploadMessage == null && uploadMessageAboveL == null)
            {
                return;
            }

            //取消拍照或者圖片選擇時,返回null,否則<input file> 就是沒有反應
            if (resultCode != RESULT_OK)
            {
                if (uploadMessage != null)
                {
                    uploadMessage.onReceiveValue(null);
                    uploadMessage = null;
                }
                if (uploadMessageAboveL != null)
                {
                    uploadMessageAboveL.onReceiveValue(null);
                    uploadMessageAboveL = null;

                }
            }

            //拍照成功和選取照片時
            if (resultCode == RESULT_OK)
            {
                Uri imageUri = null;

                switch (requestCode)
                {
                    case REQUEST_CODE_ALBUM:

                        if (data != null)
                        {
                            imageUri = data.getData();
                        }

                        break;
                    case REQUEST_CODE_CAMERA:

                        if (!TextUtils.isEmpty(mCurrentPhotoPath))
                        {
                            File file = new File(mCurrentPhotoPath);
                            Uri localUri = Uri.fromFile(file);
                            Intent localIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, localUri);
                            sendBroadcast(localIntent);
                            imageUri = Uri.fromFile(file);
                            mLastPhothPath = mCurrentPhotoPath;
                        }
                        break;
                }


                //上傳文件
                if (uploadMessage != null)
                {
                    uploadMessage.onReceiveValue(imageUri);
                    uploadMessage = null;
                }
                if (uploadMessageAboveL != null)
                {
                    uploadMessageAboveL.onReceiveValue(new Uri[]{imageUri});
                    uploadMessageAboveL = null;

                }

            }
        }
    }
  @Override
    public void onRequestPermissionsResult(int requestCode, 
    @NonNull String[] permissions, @NonNull int[] grantResults)
    {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (grantResults == null && grantResults.length == 0)
        {
            return;
        }

        if (requestCode == REQUEST_CODE_PERMISSION_CAMERA)
        {

            if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                takePhoto();
            }
            else
            {
                // Permission Denied
                new AlertDialog.Builder(mContext).setTitle("無法拍照").setMessage("您未授予拍照權限").setNegativeButton("取消", null).setPositiveButton("去設置", new DialogInterface.OnClickListener()
                {
                    @Override
                    public void onClick(DialogInterface dialog, int which)
                    {
                        Intent localIntent = new Intent();
                        localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
                        localIntent.setData(Uri.fromParts("package", getPackageName(), null));
                        startActivity(localIntent);
                    }
                }).create().show();
            }

        }

    }

    /**
     * 選擇相機或者相冊
     */
    public void uploadPicture()
    {

        AlertDialog.Builder builder = new AlertDialog.Builder(WebviewForNursingActivity.this);
        builder.setTitle("請選擇圖片上傳方式");

        //取消對話框
        builder.setOnCancelListener(new DialogInterface.OnCancelListener()
        {
            @Override
            public void onCancel(DialogInterface dialog)
            {

                //一定要返回null,否則<input type='file'>
                if (uploadMessage != null)
                {
                    uploadMessage.onReceiveValue(null);
                    uploadMessage = null;
                }
                if (uploadMessageAboveL != null)
                {
                    uploadMessageAboveL.onReceiveValue(null);
                    uploadMessageAboveL = null;

                }
            }
        });


        builder.setPositiveButton("相機", new DialogInterface.OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which)
            {


                if (!TextUtils.isEmpty(mLastPhothPath))
                {
                    //上一張拍照的圖片刪除
                    mThread = new Thread(new Runnable()
                    {
                        @Override
                        public void run()
                        {

                            File file = new File(mLastPhothPath);
                            if (file != null)
                            {
                                file.delete();
                            }
                            mHandler.sendEmptyMessage(1);

                        }
                    });

                    mThread.start();


                }
                else
                {

                    //請求拍照權限
                    if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)
                    {
                        takePhoto();
                    }
                    else
                    {
                        ActivityCompat.requestPermissions(WebviewForNursingActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_PERMISSION_CAMERA);
                    }
                }


            }
        });
        builder.setNegativeButton("相冊", new DialogInterface.OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which)
            {

                chooseAlbumPic();


            }
        });

        builder.create().show();

    }

    /**
     * 拍照
     */
    private void takePhoto()
    {

        StringBuilder fileName = new StringBuilder();
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        fileName.append(UUID.randomUUID()).append("_upload.jpg");
        File tempFile = new File(mContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES), fileName.toString());
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
        {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri uri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".fileprovider", tempFile);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        }
        else
        {
            Uri uri = Uri.fromFile(tempFile);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        }

        mCurrentPhotoPath = tempFile.getAbsolutePath();
        startActivityForResult(intent, REQUEST_CODE_CAMERA);


    }

    /**
     * 選擇相冊照片
     */
    private void chooseAlbumPic()
    {

        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("image/*");
        startActivityForResult(Intent.createChooser(i, "Image Chooser"), REQUEST_CODE_ALBUM);

    }

Android-解決Webview對選擇文件 點擊無響應

但是這種方法,用相機拍照,傳遞兩張照片,有時候會有異常,可以使用下邊的代碼

 private ValueCallback<Uri[]> mUploadCallback;
    private Uri imageUri;
    private int PHOTO_REQUEST_CODE = 1111;
    ...
    public class MyWebChromeClient extends WebChromeClient
    {

        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result)
        {
            Log.i(TAG, "onJsAlert: " + message);
            return super.onJsAlert(view, url, message, result);
        }

        @Override
        public boolean onJsConfirm(WebView view, String url, String message, JsResult result)
        {
            Log.i(TAG, "onJsConfirm: " + message);
            return super.onJsConfirm(view, url, message, result);
        }

        @Override
        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)
        {
            Log.i(TAG, "onJsPrompt: " + message);
            return super.onJsPrompt(view, url, message, defaultValue, result);
        }

        @Override
        public void onReceivedTitle(WebView view, String title)
        {
            super.onReceivedTitle(view, title);
        }

        @Override
        public void onProgressChanged(WebView view, int newProgress)
        {
            if (newProgress == 100)
            {
                progressBar.setVisibility(View.GONE);
            }
            else
            {
                if (progressBar.getVisibility() == View.GONE)
                    progressBar.setVisibility(View.VISIBLE);
                progressBar.setProgress(newProgress);
            }

            super.onProgressChanged(view, newProgress);
        }

        //For Android  >= 5.0
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams)
        {

            mUploadCallback = filePathCallback;
            takePhoto();
            return true;
        }


    }

    Handler mHandler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            super.handleMessage(msg);
            takePhoto();
        }
    };
  @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {

        if (requestCode == PHOTO_REQUEST_CODE)
        {
            if (mUploadCallback != null)
            {
                choosePic(resultCode, data);
            }
            else
            {
                Toast.makeText(this, "發生錯誤", Toast.LENGTH_SHORT).show();
            }
        }
    }

 /**
     * 拍照或相冊
     */
    private void takePhoto()
    {

        String filePath = Environment.getExternalStorageDirectory() + File.separator + Environment.DIRECTORY_PICTURES + File.separator;
        String fileName = "IMG_" + DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
        imageUri = Uri.fromFile(new File(filePath + fileName));
        Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        Intent Photo = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        Intent chooserIntent = Intent.createChooser(Photo, "Image Chooser");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{captureIntent});
        startActivityForResult(chooserIntent, PHOTO_REQUEST_CODE);
    }

    private void choosePic(int resultCode, Intent data)
    {
        if (RESULT_OK == resultCode)
        {
            updatePhotos();
            if (data != null)
            {
                Uri[] results;
                Uri uriData = data.getData();
                if (uriData != null)
                {
                    results = new Uri[]{uriData};
                    mUploadCallback.onReceiveValue(results);
                }
                else if (imageUri != null)
                {
                    mUploadCallback.onReceiveValue(new Uri[]{imageUri});
                }
                else
                {
                    mUploadCallback.onReceiveValue(null);
                }
            }
            else
            {
                mUploadCallback.onReceiveValue(new Uri[]{imageUri});
            }
        }
        else
        {
            mUploadCallback.onReceiveValue(null);
        }
        mUploadCallback = null;
    }


    //更新照片
    private void updatePhotos()
    {
        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        intent.setData(imageUri);
        sendBroadcast(intent);
    }

小米部分機型,調起系統相冊沒反應的解決辦法
小米的部分機型,點擊相冊,沒反應,直接resultCode 0,解決辦法:
將MIUI優化關閉,重啓手機後,打開APP

app開發中無法調起MIUI系統相冊拾取圖片

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章