Samsung S8 - Unable to resolve image path
LiamLamb opened this issue · comments
Hi @siralam,
I'm using your plugin for an application that should support users to take picture and upload them to a server.
Your plugin tool works great - but i have noticed a few small 'compatibility' issues when i comes to selecting images from the gallery on certain devices.
We develop on a number of devices, but Samsung generally seems to show the most amount of issues when it comes to working with the camera / gallery in general.
The picker works fine on one of our Samsung devices (SM-G360F), but has issues on one of our later devices: Samsung Galaxy A5 (2017).
The issues tends to be that it can't resolve the path of the selected image. Do you have any suggestion on how to fix this ?
I can send you more details about replicating the issue if you like, as well as some detailed error logging if that helps ?
I look forward to hearing from you.
Liam
Please can you tell us in which Android version it happens?
Sure - We're running this application targetting Oreo
@LiamLamb Yes I do need more detailed logs as I don't have that particular device, do you have any?
Hi @siralam and @EmmanuelGuther ,
Here are some details to help you reproduce the error.
I would like to first give a bit of context as to what development environment we are in, what we are using etc.
We are developing an application as part of a cross platform project, using MvvmCross in Xamarin.
All of the following code is therefore my interpretation into c#, which to be fair didn't really need much interpreting.
Android Environment Settings:
- Target Version: 8.1 Oreo
- Minimum Android Version: 4.4 KitKat
The permissions currently prompt on install are:
- Internet
- Network state access
- Vibrate
- Write external storage
- Read external storage
Steps that i've taken to setup the Image Picker on Android:
- Manifest File:
The following was added into the 'Application' tag of the file.
<provider android:name="android.support.v4.content.FileProvider" android:authorities="PACKAGENAME.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"/> </provider>
- XML/file_paths.xml:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="external_files" path="." /> </paths>
- FragmentViewWithBSImage:
On click method snippet for opening the image picker:
public void OnRandomButtonClick(object sender, EventArgs e)
{
try
{
//NOTE: It is intentional that we Set maximum display images to 2 as we currently only want to show
// the gallery and camera button - as images don't always load correctly into the picker :(
BSImagePicker singleSelectionPicker = new BSImagePicker.Builder("PACKAGENAME.fileprovider")
.SetMaximumDisplayingImages(2)
.SetSpanCount(2)
.SetGridSpacing(Utils.Dp2Px(2))
.SetPeekHeight(Utils.Dp2Px(200))
.Build();
singleSelectionPicker.Show(ChildFragmentManager, "Picker");
}
catch (Exception ex)
{
_logService.LogException("An error has occured opening the mother image picker.", ex);
_alertService.ShowAlert("Information", "Something went wrong setting up the image picker. Please try again later.");
}
}
I then implement the IOnSingleImageSelectedListener to catch the selected image Uri
public void OnSingleImageSelected(Android.Net.Uri uri)
{
byte[] resizedImageBytes = null;
try
{
// In the method below is where we get the issue
var imageBytes = GetImageBytes(uri);
resizedImageBytes = ResizeImage(imageBytes, uri);
// Set the original image bytes to the image data. If the image data is null, then we will default to default image
ViewModel.OriginalBytes = ViewModel.ImageData;
// Set the image data to the new image bytes
ViewModel.ImageData = resizedImageBytes;
ViewModel.UploadEntryImageCommand.Execute(null);
}
catch (Exception ex)
{
_logService.LogException("An error has occured proessing a baby's selected image.", ex);
_alertService.ShowAlert("Information", "Something went wrong processing the selected image. Please try again later.");
ViewModel.ResetButtonsState();
}
}
The method causing the actual exception:
// Method to get the image bytes in a helper class:
public static byte[] GetImageBytes(Uri uri)
{
byte[] imageBytes = null;
// This guy sometime throws an exception - whereby it cannot resolve the path provided.
System.IO.Stream stream = Application.Context.ContentResolver.OpenInputStream(uri);
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
imageBytes = memoryStream.ToArray();
}
return imageBytes;
}
These are pretty much the steps to reproduce the issue. As mentioned in my previous comments - this doesn't happen on all devices. It seems to however be happening on later devices like Samsung S8 and One+ 5 device.
Here are some log of image pathing issues from today:
These logs are pulled from the exception during debugging:
{Java.IO.FileNotFoundException: /0/1/content:/media/external/images/media/153678/ORIGINAL/NONE/879549069 (No such file or directory)
at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00089] in <588bdbe85f2c4d10b23065ee1d01a212>:0
at Java.Interop.JniPeerMembers+JniInstanceMethods.FinishCreateInstance (System.String constructorSignature, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0004f] in <588bdbe85f2c4d10b23065ee1d01a212>:0
at Android.Media.ExifInterface..ctor (System.String filename) [0x00072] in <d002c74216a24d44bf5e58a5ea253126>:0
at CompanyName.Droid.Helpers.EntryImageHelpers.ResizeImage (System.Byte[] originalBytes, Android.Net.Uri uri) [0x00065] in /Users/CompanyEngineer/Documents/_git/Central/PatientPortal/Mobile/CompanyName.Shared.Droid/Helpers/EntryImageHelpers.cs:186
at CompanyName.Droid.Views.PregnancyPlannerFragments.MotherOverviewView.OnSingleImageSelected (Android.Net.Uri uri) [0x00011] in /Users/CompanyEngineer/Documents/_git/Central/PatientPortal/Mobile/CompanyName.Shared.Droid/Views/PregnancyPlannerFragments/MotherOverviewView.cs:236
--- End of managed Java.IO.FileNotFoundException stack trace ---
java.io.FileNotFoundException: /0/1/content:/media/external/images/media/153678/ORIGINAL/NONE/879549069 (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:200)
at java.io.FileInputStream.<init>(FileInputStream.java:150)
at java.io.FileInputStream.<init>(FileInputStream.java:103)
at android.media.ExifInterface.<init>(ExifInterface.java:1336)
at com.asksira.bsimagepicker.BSImagePicker.n_onActivityResult(Native Method)
at com.asksira.bsimagepicker.BSImagePicker.onActivityResult(BSImagePicker.java:88)
at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:149)
at md5c44e626e43e5b8d6d42d28410a243d52.MvxEventSourceAppCompatActivity.n_onActivityResult(Native Method)
at md5c44e626e43e5b8d6d42d28410a243d52.MvxEventSourceAppCompatActivity.onActivityResult(MvxEventSourceAppCompatActivity.java:119)
at android.app.Activity.dispatchActivityResult(Activity.java:7317)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4436)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4484)
at android.app.ActivityThread.-wrap19(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1743)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6753)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:482)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
}
I think there is a better way to convert Uri into byteArray.
For me, I usually turn the Uri into a File
before I start working with it, so the File
class looks promising to me, I think this SO post might help you, could you try with it first?
Strange way. Why not use contentResolver.query(//...) for to get a string file path?