0

My app uses android.hardware.camera class. The class was deprecated, and even when the app works fine on Android 5.0+ when the client installs it on Android 7.0 the app crash.

I find similar questions (Use of camera2 versus deprecated Camera - what is best practice?), but there is no answer to my specific question.

Since the app is already finished and the camera is not the essential feature. Is there a way to avoid this crash and keep the old camera class?

Crash:

java.lang.RuntimeException: 
  at android.hardware.Camera.<init>(Camera.java:519)
  at android.hardware.Camera.open(Camera.java:379)
  at info.blacktrail.catedral.Camaracap.onResume(Camaracap.java:216)
  at android.support.v4.app.Fragment.performResume(Fragment.java:2235)
  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1346)
  at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
  at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:757)
  at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2355)
  at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2146)
  at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2098)
  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2008)
  at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:710)
  at android.os.Handler.handleCallback(Handler.java:751)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:154)
  at android.app.ActivityThread.main(ActivityThread.java:6776)
  at java.lang.reflect.Method.invoke(Native Method:0)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

Fragment:

public class Cameracap extends Fragment implements View.OnClickListener {

ProgressDialog mProgressDialog;
private SurfaceView preview = null;
private SurfaceHolder previewHolder = null;
private Camera camera = null;
private boolean inPreview = false;
private FrameLayout camera_preview;

ImageView image, captured_image,image_frame,imageshare,imagetakepic;
Bitmap bmp;
static Bitmap mutableBitmap;
File imageFileName = null;

private MediaScannerConnection msConn;
ProgressDialog dialog;

FragmentManager mFragmentManager;




@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.cameraselfie, container, false);

   ContextCompat.checkSelfPermission(getActivity(),Manifest.permission.CAMERA);



    image = (ImageView) rootView.findViewById(R.id.image);

    imageshare= (ImageView) rootView.findViewById(R.id.imageshare);
    imagetakepic= (ImageView) rootView.findViewById(R.id.imagetakepic);


    image_frame = (ImageView) rootView.findViewById(R.id.imageView18);





    captured_image = (ImageView) rootView.findViewById(R.id.captured_image);
    preview = (SurfaceView) rootView.findViewById(R.id.surface_cam);
    camera_preview = (FrameLayout) rootView.findViewById(R.id.camera_preview);




    previewHolder = preview.getHolder();
    previewHolder.addCallback(surfaceCallback);
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    previewHolder.setFixedSize(getActivity().getWindow().getWindowManager()
            .getDefaultDisplay().getWidth(), getActivity().getWindow().getWindowManager()
            .getDefaultDisplay().getHeight());


    final Button captureButton = (Button) rootView.findViewById(R.id.foto);
    final Button share_image = (Button) rootView.findViewById(R.id.shareface);
    captureButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            imageshare.setVisibility(View.VISIBLE);
            share_image.setVisibility(View.VISIBLE);
            imagetakepic.setVisibility(View.GONE);
            captureButton.setVisibility(View.GONE);


            capture();
        }
    });


    share_image.setOnClickListener(new View.OnClickListener() {




        @Override
        public void onClick(View v) {
            imageshare.setVisibility(View.GONE);
            share_image.setVisibility(View.GONE);
            imagetakepic.setVisibility(View.VISIBLE);
            captureButton.setVisibility(View.VISIBLE);


            new Title().execute();

        }
    });

    Button button_back=(Button)rootView.findViewById(R.id.button_back);


    button_back.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            mFragmentManager = getActivity().getSupportFragmentManager();

            android.support.v4.app.FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
            fragmentTransaction.replace(R.id.contenedor_principal,new FragmentoInicio()).commit();
        }
    });

    Button emergencia=(Button)rootView.findViewById(R.id.button_sos);
    emergencia.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            mFragmentManager = getActivity().getSupportFragmentManager();

            android.support.v4.app.FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
            fragmentTransaction.replace(R.id.contenedor_principal,new Emergencia()).commit();

        }
    });

    Button buttoncam=(Button)rootView.findViewById(R.id.buttoncam);
    buttoncam.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            mFragmentManager = getActivity().getSupportFragmentManager();

            android.support.v4.app.FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
            fragmentTransaction.replace(R.id.contenedor_principal,new Camera2BasicFragment()).commit();

        }
    });


    Button configbut=(Button)rootView.findViewById(R.id.button_config);
    configbut.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {



        }
    });

    return rootView;
}


@Override
public void onResume() {
    super.onResume();
    camera = Camera.open();
}

@Override
public void onPause() {
    if (inPreview) {
        camera.stopPreview();
    }

    camera.release();
    camera = null;
    inPreview = false;
    super.onPause();
}

private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) {
    Camera.Size result = null;
    for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
        if (size.width <= width && size.height <= height) {
            if (result == null) {
                result = size;
            } else {
                int resultArea = result.width * result.height;
                int newArea = size.width * size.height;
                if (newArea > resultArea) {
                    result = size;
                }
            }
        }
    }
    return (result);
}

SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            camera.setPreviewDisplay(previewHolder);
        } catch (Throwable t) {

            Toast.makeText(getActivity(), t.getMessage(), Toast.LENGTH_LONG)
                    .show();
        }
    }

    public void surfaceChanged(SurfaceHolder holder,
                               int format, int width,
                               int height) {
        Camera.Parameters parameters = camera.getParameters();
        Camera.Size size = getBestPreviewSize(width, height,
                parameters);

        if (size != null) {
            parameters.setPreviewSize(size.width, size.height);
            camera.setParameters(parameters);
            camera.setDisplayOrientation(90);
            camera.startPreview();
            inPreview = true;
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // no-op
    }
};


Camera.PictureCallback photoCallback = new Camera.PictureCallback() {
    public void onPictureTaken(final byte[] data, final Camera camera) {
        dialog = ProgressDialog.show(getActivity(), "", "Guardando foto");
        new Thread() {
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (Exception ex) {
                }
                onPictureTake(data, camera);
            }
        }.start();
    }
};


public void onPictureTake(byte[] data, Camera camera) {

    bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
    mutableBitmap = bmp.copy(Bitmap.Config.ARGB_8888, true);
    savePhoto(mutableBitmap);

    dialog.dismiss();

}






public void savePhoto(Bitmap bmp) {

    FileOutputStream out = null;

    try {
        out = new FileOutputStream("/sdcard/"
                + "catedralselfie"
                + ".jpg");
        bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
        out.flush();
        out.close();
        scanPhoto(imageFileName.toString());
        out = null;
    } catch (Exception e) {
        e.printStackTrace();
    }
}



public void scanPhoto(final String imageFileName) {
    msConn = new MediaScannerConnection(getActivity(), new MediaScannerConnection.MediaScannerConnectionClient() {
        public void onMediaScannerConnected() {
            msConn.scanFile(imageFileName, null);

        }

        public void onScanCompleted(String path, Uri uri) {
            msConn.disconnect();

        }
    });
    msConn.connect();
}


public void capture() {
    Log.e("onBack :", "yes");
    camera.takePicture(null, null, photoCallback);
    inPreview = false;
}

@Override
public void onClick(View v) {

}



// Title AsyncTask
private class Title extends AsyncTask<Void, Void, Void> {

    Drawable drawable;
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mProgressDialog = new ProgressDialog(getActivity());
        mProgressDialog.setTitle("Cerro Catedral");
        mProgressDialog.setMessage("cargando datos...");
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.show();
    }

    @Override
    protected Void doInBackground(Void... params) {
        Elements elements, elements1, elements2;

        File imgFile = new File("/sdcard/catedralselfie.jpg");

        if (imgFile.exists()) {

            Bitmap myBitmap2 = BitmapFactory.decodeFile(imgFile.getAbsolutePath());

            Matrix matrix = new Matrix();
            matrix.postRotate(90);
            Bitmap rotatedBitmap = Bitmap.createBitmap(myBitmap2 , 0, 0, myBitmap2.getWidth(), myBitmap2.getHeight(), matrix, true);
            drawable = new BitmapDrawable(getResources(), rotatedBitmap);



        }

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {


        image_frame.setBackground(drawable);

        shareintento();
        mProgressDialog.dismiss();

    }



}


protected void shareintento() {


    camera_preview.setDrawingCacheEnabled(true);

    camera_preview.buildDrawingCache();

    Bitmap bitmap = camera_preview.getDrawingCache();

    try {
        FileOutputStream out = new FileOutputStream("/sdcard/"
                + "catedralselfie2"
                + ".jpg");
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
    } catch (Exception e) {
        e.printStackTrace();
    }


    File file = new File("/sdcard/catedralselfie2.jpg");

    Intent shareIntent = new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    String _text = "#CatedralSelfie #MiSelfieEnCatedral #CatedralInvierno #Bariloche @CerroCatedralok";


    shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(String.valueOf(file))));  //optional//use this when you want to send an image


    shareIntent = new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    shareIntent.putExtra(Intent.EXTRA_TEXT, (CharSequence) _text);
    shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File("/sdcard/catedralselfie2.jpg")));  //optional//use this when you want to send an image
    shareIntent.setType("image/jpeg");
    shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    startActivity(Intent.createChooser(shareIntent, "send"));


    mFragmentManager = getActivity().getSupportFragmentManager();

    android.support.v4.app.FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.contenedor_principal,new FragmentoInicio()).commit();


}

}

Agustin Scalisi
  • 551
  • 3
  • 17
  • Please provide a [mcve]. That would include the full Java stack trace associated with the crash, along with code from your app that is referenced in that stack trace. `android.hardware.Camera` works fine on Android 7.0+ in general. – CommonsWare Jun 04 '17 at 21:42
  • Please add some code into your question – S.R Jun 05 '17 at 02:31
  • Code Added to the questions – Agustin Scalisi Jun 05 '17 at 19:31
  • The full system log from your run would also be very helpful. Right now, there's no sense of why the runtime exception happens, and the system logs should tell you. – Eddy Talvala Jun 06 '17 at 22:12

2 Answers2

0

Your stack trace shows that your app calls Cameta.open() from Fragment.onResume method on the main Ui thread. This alone may cause RuntimeException on Android 7, which imposes even tighter restrictions on performing time consuming operations on UI thread.

Another cause could be the permissions: you don't need to implement full runtime permissions if your target API is less than 21, but still, your code must be prepared to handle the case when camera permission is revoked, at any time.

There may be other issues with your camera related code, please share it for further analysis.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
-1

Use this code for capturing image...

static final int REQUEST_IMAGE_CAPTURE1 = 80;

 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
 startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE1);

    @Override
public void onActivityResult(int requestCode, int resultCode, Intent intent1) {
    super.onActivityResult(requestCode, resultCode, intent1);

    if (requestCode == REQUEST_IMAGE_CAPTURE1) {
        // Handle scan intent

        System.out.println("requestCode " + requestCode);
        System.out.println("resultCode " + resultCode);
        // System.out.println("intent "+intent1.getExtras());

        try {
            Bitmap thumbnail = (Bitmap) intent1.getExtras().get("data");
            //3
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
            //4
            String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            final File file = new File(Environment.getExternalStorageDirectory()+File.separator +"1"+ "_" + "2"+"_"+"3"+"_" + timeStamp +".jpg");
            try {
                file.createNewFile();
                FileOutputStream fo = new FileOutputStream(file);
                //5
                fo.write(bytes.toByteArray());
                fo.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            if (resultCode == RESULT_OK) {

                System.out.println("photoFile" + file);                           
                }
            } 
        }
        catch (Exception e)
        {

        }
    }
     }
Vishal Vaishnav
  • 3,346
  • 3
  • 26
  • 57