Search code examples
androidandroid-afilechooser

Any Option other than OpenFileChooser


I am Using and OpenFileChooser it is working on Android 4.2.2(Jelly Bean) but not working on Android Lollipop (5.0) version.So is there any option to do this thing which support from 4.0 to until new version.

I am using this tutorial

http://androidexample.com/Open_File_Chooser_With_Camera_Option_In_Webview_File_Option/index.php?view=article_discription&aid=128&aaid=148

And there is issue submitted regarding that

Issue 62220: openFileChooser not called when is clicked on android 4.4 webview

I am using webview in which I had call webpage which contain file chooser/Image chooser.


Solution

  • Add this before onCreate:

    private WebView mWebView;
    private ProgressBar mProgressBar;
    
    //new block
    private static final String TAG = MainActivity.class.getSimpleName();
    public static final int INPUT_FILE_REQUEST_CODE = 1;
    public static final String EXTRA_FROM_NOTIFICATION = "EXTRA_FROM_NOTIFICATION";
    private ValueCallback<Uri[]> mFilePathCallback;
    private String mCameraPhotoPath;
    
    // Storage Permissions
    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA
    };
    

    Add to mWebView.setWebChromeClient(new WebChromeClient() { this:

    public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,
                        WebChromeClient.FileChooserParams fileChooserParams) {
    
                    //verifyStoragePermissions(MainActivity.this);
                    Log.e("111","onShowFileChooser");
                    if(mFilePathCallback != null) {
                        mFilePathCallback.onReceiveValue(null);
                    }
                    mFilePathCallback = filePathCallback;
    
                    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    if (takePictureIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {
                        // Create the File where the photo should go
                        File photoFile = null;
                        try {
                            photoFile = createImageFile();
                            takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
                        } catch (IOException ex) {
                            // Error occurred while creating the File
                            Log.e(TAG, "Unable to create Image File", ex);
                        }
    
                        // Continue only if the File was successfully created
                        if (photoFile != null) {
                            mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
                            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                                    Uri.fromFile(photoFile));
                        } else {
                            takePictureIntent = null;
                        }
                    }
    
                    Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
                    contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
                    contentSelectionIntent.setType("image/*");
    
                    Intent[] intentArray;
                    if(takePictureIntent != null) {
                        intentArray = new Intent[]{takePictureIntent};
                    } else {
                        intentArray = new Intent[0];
                    }
    
                    Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
                    chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
                    chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
                    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
    
                    startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
    
                    return true;
                }
    

    And add this to class:

    @Override
    public void onActivityResult (int requestCode, int resultCode, Intent data) {
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) {
                super.onActivityResult(requestCode, resultCode, data);
                return;
            }
    
            Uri[] results = null;
    
            // Check that the response is a good one
            if (resultCode == Activity.RESULT_OK) {
                if (data == null) {
                    // If there is not data, then we may have taken a photo
                    if (mCameraPhotoPath != null) {
                        results = new Uri[]{Uri.parse(mCameraPhotoPath)};
                    }
                } else {
                    String dataString = data.getDataString();
                    if (dataString != null) {
                        results = new Uri[]{Uri.parse(dataString)};
                    }
                }
            }
    
            mFilePathCallback.onReceiveValue(results);
            mFilePathCallback = null;
        } else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
            System.out.println("In KitKat Condition");
    
            if (requestCode != FILECHOOSER_RESULTCODE || mUploadMessage == null) {
                System.out.println("In != Null");
                super.onActivityResult(requestCode, resultCode, data);
                return;
            }
            if (requestCode == FILECHOOSER_RESULTCODE) {
    
                System.out.println("requestCode == FileChooser ResultCode");
                if (null == this.mUploadMessage) {
                    System.out.println("In null == this.mUploadMessage");
                    return;
                }
                Uri result = null;
                try {
                    if (resultCode != RESULT_OK) {
    
                        result = null;
                    } else {
    
                        //newcode
    
                        // retrieve from the private variable if the intent is null
                        result = data == null ? mCapturedImageURI : data.getData();
    
                        KitkatPath = Uri.parse("file://"+getPath(MainActivity.this, result));
                        System.out.println("KitkatPath== "+KitkatPath);
                        System.out.println("result = "+result);
                    }
                } catch (Exception e) {
                    // Toast.makeText(getApplicationContext(), "activity :" + e, Toast.LENGTH_LONG).show();
                    e.printStackTrace();
                }
                // mUploadMessage.onReceiveValue(result);
                mUploadMessage.onReceiveValue(KitkatPath);
                System.out.println("mUploadMessage = "+mUploadMessage);
                mUploadMessage = null;
            }
        }
    
    }
    

    Last thing, add to Manifest

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    

    It should work on lollipop and marshmallow