我的应用使用android.hardware.camera
课程。该类已被弃用,即使应用程序在Android 5.0+
上正常运行,当客户端在Android 7.0
安装应用程序时崩溃。
我发现了类似的问题(Use of camera2 versus deprecated Camera - what is best practice?),但我的具体问题没有答案。
由于应用已经完成,相机不是必备功能。有没有办法避免这种崩溃并保留旧的相机类?
崩溃:
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)
片段:
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();
}
}
答案 0 :(得分:0)
您的堆栈跟踪显示您的应用程序从主Ui线程上的Fragment.onResume方法调用Cameta.open()。仅此一项就可能导致Android 7上的RuntimeException,这对在UI线程上执行耗时的操作施加了更严格的限制。
另一个原因可能是权限:如果目标API小于21,则不需要实现完整的运行时权限,但是,您的代码必须准备好处理撤消相机权限时的情况,任何时候。
您的相机相关代码可能存在其他问题,请分享以供进一步分析。
答案 1 :(得分:-1)
使用此代码捕获图像......
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)
{
}
}
}