0

Hello to all programmers.

While creating my first android app in Visual studio Xamarin, I stuck with one more problem (there was lot of them =) ). I try to make permissions check for Android Marshmallow+. And while I try to launch Camera Activity (MediaStore.ActionImageCapture), my app crashes. Here the code

const int REQUEST_CAMERA = 1;
const int REQUEST_EXTERNAL_STORAGE = 2;
const string cameraPermission = Android.Manifest.Permission.Camera;
const string storageWritePermission = Android.Manifest.Permission.WriteExternalStorage;
const string storageReadPermission = Android.Manifest.Permission.ReadExternalStorage;
public static class App
{
  public static File _file;
  public static File _dir;
  public static Bitmap bitmap;
  public static string fileName;
}
private bool IsThereAnAppToTakePicture()
{
  Intent intent = new Intent(MediaStore.ActionImageCapture);
  IList<ResolveInfo> availableActivities =
  PackageManager.QueryIntentActivities(intent, PackageInfoFlags.MatchDefaultOnly);
  return availableActivities != null && availableActivities.Count > 0;
}
private void CreateDirectoryForPictures()
{
  App._dir = new File(Enviroment.GetExternalStoragePublicDirectory(Enviroment.DirectoryPictures), "Kuponguru");
  if (!App._dir.Exists())
  {
    App._dir.Mkdirs();
  }
}
private void StartCameraActivity()
{
  Intent intent = new Intent(MediaStore.ActionImageCapture);
  App.fileName = String.Format("picture_{0}.jpg", Guid.NewGuid());
  App._file = new File(App._dir, App.fileName);
  intent.PutExtra(MediaStore.ExtraOutput, Uri.FromFile(App._file));
  StartActivityForResult(intent, REQUEST_CAMERA);
}
protected override void OnCreate(Bundle savedInstanceState)
{
  base.OnCreate(savedInstanceState);
  SetContentView(Resource.Layout.TakePicture);
  pictureImageButton = FindViewById<ImageView>(Resource.Id.pictureButton);
  pictureImageButton.Click += TakePicture;
  if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
  {
    if (CheckSelfPermission(storageReadPermission) == (int)Permission.Granted &&
    CheckSelfPermission(storageWritePermission) == (int)Permission.Granted)
    {
      if (IsThereAnAppToTakePicture())
      {
        CreateDirectoryForPictures();
      }                  
    }
    else
    {
      RequestPermissions(new string[] { storageWritePermission, storageReadPermission }, REQUEST_EXTERNAL_STORAGE);
    }
  }
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
  switch (requestCode)
  {
    case REQUEST_EXTERNAL_STORAGE:
    {
      if (grantResults[0] == Permission.Granted)
      {
        if (IsThereAnAppToTakePicture())
        {
          CreateDirectoryForPictures();
        }
      }
    }
    break;
    case REQUEST_CAMERA:
    {
      if (grantResults[0] == Permission.Granted)
      {
        StartCameraActivity();
      }
    }
  }
}
private void TakePicture(object sender, EventArgs e)
{
  if (Build.VERSION.SdkInt >= BuildVersionCodes.M) {
    if (CheckSelfPermission(cameraPermission) == (int)Permission.Granted &&
                    CheckSelfPermission(storageWritePermission) == (int)Permission.Granted)
    {
      StartCameraActivity();
    }
    else
    {
      RequestPermissions(new string[] { cameraPermission, storageWritePermission }, REQUEST_CAMERA);
    }
  }
  else
  {
    StartCameraActivity();
  }
}

If I delete string intent.PutExtra(MediaStore.ExtraOutput, Uri.FromFile(App._file)); in StartCameraActivity, then camera works, but with this command app crashed.

I'll be appreciated for all suggestions.

--UPDATED--

I check Uri.FromFile(App._file) in intent.PutExtra(MediaStore.ExtraOutput, Uri.FromFile(App._file)); File is not exists So, problem is - app can't create file (but can create directory)

--UPDATED--

I check application on Marshmallow emulator. All works fine. Also I check on emulated device - file, where camera should save photo, is not exists when I send it to Camera activity in intent.PutExtra(MediaStore.ExtraOutput, Uri.FromFile(App._file)); Well problem is still here.

--UPDATED--

Added try catch for Camera activity start and get exception file:///storage/emulated/0/Pictures/MyApp/picture_123.jpg exposed beyond app through ClipData.Item.getUri

1 Answers1

3

At least I found whats wrong. It's god damned version issue. In Android N+ there are no more file:// URIs, only content:// URIs instead. That's why Camera Activity can't work with Uri.FromFile(App._file). For this solution I have to thank request Answer of question by questioner SuperThomasLab and users Pkosta, hqzxzwb and Java coder

The solution, changed for VS Xamarin, I used:

**Solution **

protected override void OnCreate(Bundle savedInstanceState){
  StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
  StrictMode.SetVmPolicy(builder.Build());
  base.OnCreate(savedInstanceState);
  ...
}

Other code is without changes.

I tried it on Android N 7.1.1 on real device and it's works.

Thanks to all, who take attention to my problem.