skip to Main Content

I’m updating a working app that targeted API 9 (Pie) to API 33 (Tiramisu) and the camera always returns Result.Cancelled to the OnActivityResult code. I’m using Visual Studio 2022 Version 17.3.6 on a Windows 11 pro machine. This is my camera code:

camerabutton.Click += (sender, evt) =>
{
    var cameraispresent = checkCameraHardware(this);
    if (cameraispresent)
    {
        try
        {
            CreateDirectoryForPictures();
            MySubjectInfo.Name = MySubjectInfo.Name.Replace(",", "");
            MySubjectInfo.Name = MySubjectInfo.Name.Replace(" ", "");
            MySubjectInfo.Name = MySubjectInfo.Name.Replace(".", "");
            var filename = MySubjectInfo.Name + ".jpg";
            Intent intent = new Intent(MediaStore.ActionImageCapture);
            App._file = new File(App._dir, String.Format(filename, Guid.NewGuid()));
            intent.PutExtra(MediaStore.ExtraOutput, Uri.FromFile(App._file));
            StartActivityForResult(intent, TakePictureRequestCode);
        }
        catch (Exception e)
        {
            var result = e.Message;
        };
    }
};

The create directory code, this code was also updated to reflect changes in API 33, however I can’t find the folder on my test device via file explorer where the photos should be stored yet App._dir.Exists() returns true saying it’s there:

    private void CreateDirectoryForPictures()
    {
        int version = (int)Android.OS.Build.VERSION.SdkInt;

        var root = "";

        if (Android.OS.Environment.IsExternalStorageEmulated)
        {
            root = Android.OS.Environment.ExternalStorageDirectory.ToString();
        }
        else
        {
            root = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyPictures);
        }

        if (version >= Convert.ToInt32(BuildVersionCodes.Q))
        {

            App._dir = new File(root + "/PhotoManager");
        }
        else
        {
            App._dir = new File(
                Environment.GetExternalStoragePublicDirectory(
                    Environment.DirectoryPictures), "PhotoManager");
        }

        if (!App._dir.Exists())
        {
            App._dir.Mkdirs();
        }
    }

This is the app class where I store the data:

public static class App
{
    public static File _file;
    public static File _dir;
    public static Bitmap bitmap;
}

This is the OnActivityResult1 code, I left my API 9 code in there commented out so you can see where I was and where I’m going. With API 9 I needed to resize the picture to scale it down to 160 X 100 as these photos are used for ID cards, I commented that code out until I can figure out why the camera intent is returning null:

    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, data);

        if (requestCode == TakePictureRequestCode  && resultCode == Result.Ok)
        {
            //Intent mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
            //Uri contentUri = Uri.FromFile(App._file);
            //mediaScanIntent.SetData(contentUri);
            //SendBroadcast(mediaScanIntent);

            Bitmap photo = (Bitmap)data.GetByteArrayExtra("data");
            App.bitmap = photo;
            //int height = 160; //Resources.DisplayMetrics.HeightPixels;
            //int width = 100; //MyImageView.Height;
            //App.bitmap = App._file.Path.LoadAndResizeBitmap(width, height);
            if (App.bitmap != null)
            {
                MyImageView.SetImageBitmap(App.bitmap);

                
                Bitmap bitmap = App.bitmap;
                var filePath = App._file.AbsolutePath;
                var stream = new System.IO.FileStream(filePath, System.IO.FileMode.Create);
                bitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, stream);
                stream.Close();

                bitmap = null;
                App.bitmap = null;
                PictureTaken = true;
            }

            // Dispose of the Java side bitmap.
            GC.Collect();

        }
    }

So what am I doing wrong?

2

Answers


  1. You cannot use Uri.FromFile anymore since Android 7.

    Use FileProvider to serve a writable uri for the camera app.

    Login or Signup to reply.
  2. Example: EnsureBluetoothEnabled called from a permission request

    Setup

    activityResultCallback = new ActivityResultCallback();
    activityResultCallback.OnActivityResultCalled += ActivityResultCallback_ActivityResultCalled;
    activityResultLauncher = RegisterForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResultCallback);
    
    
    private void EnsureBluetoothEnabled()
    {
                if ((bluetoothAdapter != null) && (!bluetoothAdapter.IsEnabled))
                    activityResultLauncher.Launch(new Intent(BluetoothAdapter.ActionRequestEnable));
    }
    

    Handler:

    private void ActivityResultCallback_ActivityResultCalled(object sender, ActivityResult result)
            {
                if (result.ResultCode == (int)Result.Ok)
                {
                    if (bluetoothAdapter.State == State.On)
                        ShowBluetoothConfirmationDialog(true);
                }
                else if (result.ResultCode == (int)Result.Canceled)
                    ShowBluetoothConfirmationDialog(false);
    
            }
    

    ActivityResultCallback class

    public class ActivityResultCallback : Java.Lang.Object, IActivityResultCallback
        {
            public EventHandler<ActivityResult> OnActivityResultCalled;
    
            public void OnActivityResult(Java.Lang.Object result)
            {
                ActivityResult activityResult = result as ActivityResult;
                OnActivityResultCalled?.Invoke(this, activityResult);
            }
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search