xamarinxamarin.formswebviewxamarin.androidfilechooser

Files Chooser for Xamarin Forms Not adding the selected image taken from camera and file


I'm creating a mobile application using Xamarin forms, As part of my implementation, I have a requirement to to show file chooser on clicking on camera icon which is loaded in webView and load the image to webView. currently file chooser is being shown, but image is not getting added.

public override bool OnShowFileChooser(Android.Webkit.WebView webView, Android.Webkit.IValueCallback filePathCallback, FileChooserParams fileChooserParams) {

    Intent takePictureIntent = new Intent(MediaStore.ActionImageCapture);

    if (takePictureIntent.ResolveActivity(mContext.PackageManager) != null) {

        Java.IO.File photoFile = null;

        try {
            string folder = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
            photoFile = new Java.IO.File(folder, "image" + DateTime.Now.Millisecond + ".png");
            takePictureIntent.PutExtra("PhotoPath", mCameraPhotoPath);

            //photoFile = createImageFile();
            //takePictureIntent.PutExtra("PhotoPath", mCameraPhotoPath);
        } catch (Exception e) {
            Console.WriteLine("catch the Exception" + e);
        }
        if (photoFile != null) {
            mCameraPhotoPath = "file:" + photoFile.AbsolutePath;
            //pictureUri = FileProvider.GetUriForFile(mContext, "asdasd", photoFile);
            takePictureIntent.PutExtra(Android.Provider.MediaStore.ExtraOutput, photoFile);
        } else {
            takePictureIntent = null;
        }

    }

    Intent contentSelectionIntent = new Intent(Intent.ActionGetContent);
    contentSelectionIntent.AddCategory(Intent.CategoryOpenable);
    contentSelectionIntent.SetType(file_type);

    Intent[] intentArray;
    if (takePictureIntent != null) {
        intentArray = new Intent[] {
            takePictureIntent
        };
    } else {
        intentArray = new Intent[0];
    }

    Intent chooserIntent = new Intent(Intent.ActionChooser);
    chooserIntent.PutExtra(Intent.ExtraIntent, contentSelectionIntent);
    chooserIntent.PutExtra(Intent.ExtraTitle, "File chooser");
    chooserIntent.PutExtra(Intent.ExtraInitialIntents, intentArray);

    //mContext.StartActivity(chooserIntent);
    mContext.StartActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
    return true;

}

private Java.IO.File createImageFile() {
    // Create an image file name
    string timeStamp = Android.OS.SystemClock.CurrentThreadTimeMillis().ToString();
    string imageFileName = "JPEG_" + timeStamp + "_";
    Java.IO.File storageDir;

    if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Gingerbread) {
        storageDir = mContext.CacheDir;

    } else {
        storageDir = mContext.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures);
    }
    //new Java.IO.File(mContext.GetExternalFilesDir(null).AbsolutePath);
    Java.IO.File imageFile = Java.IO.File.CreateTempFile(
        imageFileName, /* prefix */
        ".jpg", /* suffix */
        storageDir /* directory */
    );

    return imageFile;

}

Solution

  • At first, please add the following code into the AndroidManifest.xml to declare the permissions:

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

    And then request the permission in the MainActivity's construction method.

    var read = await Permissions.RequestAsync<Permissions.StorageRead>();
    var write = await Permissions.RequestAsync<Permissions.StorageWrite>();
    

    Finally, please override the OnActivityResult method of the Mainactivity:

      protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            if (data != null)
            {
                if (requestCode == INPUT_FILE_REQUEST_CODE)// the value of the INPUT_FILE_REQUEST_CODE
                {
                    if (null == this.message)
                    {
                        return;
                    }
    
                    this.message.OnReceiveValue(WebChromeClient.FileChooserParams.ParseResult((int)resultCode, data));
                    this.message = null;
                }
            }
        }