Forum Xamarin.Android

How i take a picture without the camera preview?

in short, I am making an application that if someone touches my cell phone, it sends a log to my computer, this log includes the date, time and 2 photos. I want my application to take 2 photos, one from the front camera and one from the rear camera, but how do I do that without the photo preview? I can't tell anyone on my cell phone "take a picture there for me". And, I have to do this all in the "OnPasswordFailed" and "OnPasswordSucceeded" methods of DeviceAdminReceiver, that is, in no screen, everything in the background. Is it possible to take a picture without a preview, in the background?

Actually, my code to take a picture is:

var p = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
    DefaultCamera = CameraDevice.Front
});

Answers

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    Do you want to achieve the result like following GIF?

    You cannot use CrossMedia this plugin to achieve it. you should use Native Camera API to achieve it.

    I used the SurfaceView to achieve it, but I set the layout_height and layout_width to 1dp. it cannot be seen in the activity.

    Here is background code.

         [Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
    public class MainActivity : AppCompatActivity, ISurfaceHolderCallback
    {
        private LinearLayout mll;
        private Button button;
        private Camera camera;
        private ISurfaceHolder mHolder;
        private SurfaceView sfv;
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.activity_main);
    
    
           // Android.Content.PM.ShortcutManager shortcutManager = (ShortcutManager)this.GetSystemService(Context.ShortcutService);
    
            //Open camera permission
            //if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.Camera) != (int)Android.Content.PM.Permission.Granted)
            //{
            //  RequestPermissions(new string[] { Manifest.Permission.Camera }, 0);
            //}
    
    
            ////Open storage permission
            //if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.WriteExternalStorage) != (int)Android.Content.PM.Permission.Granted)
            //{
            //  RequestPermissions(new string[] { Manifest.Permission.ReadExternalStorage, Manifest.Permission.WriteExternalStorage }, 0);
            //}
    
    
             initView();
            initListener();
    
    }
        protected override void OnResume()
        {
            base.OnResume();
            if (null == camera)
            {
                camera = getCustomCamera();
                if (mHolder != null)
                {
                    previceCamera(camera, mHolder);
                }
    
            }
    
        }
    
        protected override void OnStop()
        {
            base.OnStop();
            if (null != camera)
            {
                camera.SetPreviewCallback(null);
                camera.StopPreview();
                camera.Release();
                camera = null;
            }
    
        }
        private void previceCamera(Camera camera, ISurfaceHolder mHolder)
        {
            camera.SetPreviewDisplay(mHolder);
            camera.SetDisplayOrientation(90);
            camera.StartPreview();
        }
    
    
        private int FindFrontFacingCamera()
        {
            int cameraId = -1;
            // Search for the front facing camera
    
            int numberOfCameras = Camera.NumberOfCameras;
            for (int i = 0; i < numberOfCameras; i++)
            {
                CameraInfo info = new CameraInfo();
                Camera.GetCameraInfo(i, info);
                if (info.Facing == CameraInfo.CameraFacingFront)
                {
                    //Log.d(DEBUG_TAG, "Camera found");
                    cameraId = i;
                    break;
                }
            }
            return cameraId;
        }
    
        private Camera getCustomCamera()
        {
            if (null == camera)
            {
                camera = Camera.Open(FindFrontFacingCamera());
                // CameraInfo cameraInfo = new CameraInfo();  
    
            }
            return camera;
    
        }
    
        private void initListener()
        {
            button.Click += Button_Click; 
        }
    
        private void Button_Click(object sender, System.EventArgs e)
        {
            var parameters = camera.GetParameters();
    
            parameters.PictureFormat = ImageFormatType.Jpeg;
            parameters.SetPreviewSize(480, 720);
            parameters.FocusMode = Camera.Parameters.FocusModeAuto;
            camera.AutoFocus(new MyFocusCallback(camera));
        }
    
    
    
    
        private void initView()
        {
            mll = FindViewById<LinearLayout>(Resource.Id.ll);
            button = FindViewById<Button>(Resource.Id.button1);
            mFloatView();
            mHolder = sfv.Holder;
            mHolder.AddCallback(this);
        }
    
        public void mFloatView()
        {
    
            IWindowManager windowManager = GetSystemService(Context.WindowService).JavaCast<IWindowManager>();
            WindowManagerFlags flags = WindowManagerFlags.NotFocusable | WindowManagerFlags.NotTouchModal | 
            WindowManagerFlags.NotTouchable;
            var layoutParams = new WindowManagerLayoutParams(1, 1,
            WindowManagerTypes.SystemAlert,
            flags,
            Format.Rgb888);
            sfv = new SurfaceView(this);
            //mll is LinearLayout
            mll.AddView(sfv, layoutParams);
    
        }
    
    
    
        public void SurfaceCreated(ISurfaceHolder holder)
        {
            previceCamera(camera, holder);
        }
    
        public void SurfaceDestroyed(ISurfaceHolder holder)
        {
            if (null != camera)
            {
                camera.SetPreviewCallback(null);
                camera.StopPreview();
                camera.Release();
                camera = null;
            }
    
    
        }
    
        public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] Format format, int width, int height)
        {
            camera.StopPreview();
            previceCamera(camera, holder);
        }
    
    
    
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] 
       Android.Content.PM.Permission[] grantResults)
        {
            PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    
    
            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
      }
    }
    
    public class MyFocusCallback : Java.Lang.Object, IAutoFocusCallback
    {
        Camera mCamera;
        public MyFocusCallback(Camera camera)
        {
            mCamera = camera;
        }
        public void Dispose()
        {
        }
    
        public void OnAutoFocus(bool success, Camera camera)
        {
        mCamera.TakePicture(null, null, new MyPictureCallback());
        if (success)
            {
    
            }
        }
    }
    
    public class MyPictureCallback : Java.Lang.Object, IPictureCallback
    {
    
        public void Dispose()
        {
            throw new NotImplementedException();
        }
    
        public void OnPictureTaken(byte[] data, Camera camera)
        {
            dealWithCameraData(data);
        }
    
        private void dealWithCameraData(byte[] data)
        {
            // Here to save your photo
            FileOutputStream fos = null;
        //       string tempStr = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
        var path = 
    
     Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDocuments).AbsolutePath;
        string fileName = path + Java.Lang.JavaSystem.CurrentTimeMillis() + ".jpg";
    
           Toast.MakeText(Application.Context,fileName,ToastLength.Short).Show();
            File tempFile = new File(fileName);
            fos = new FileOutputStream(fileName);
            fos.Write(data);
            fos.Close();
    
        }
    }
    

    Here is my demo(Do not forget to add the permissions manually).

  • UmCaraQualquerUmCaraQualquer Member ✭✭

    I will take a picture in the DeviceAdminReceiver, i don't have an activity or a button.

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    This is just a simple for your function(withOut button and activity, I cannot test it for you), You can create surfaceview by code in background service or broadCastReceiver.

Sign In or Register to comment.