我制作了一个带有按钮的简单应用程序 ,可以在手机上打开相机(API 19),用于扫描文档和裁剪图像。 效果很好,但是当我尝试在其他型号的手机(例如API 27)上启动相机时...该应用突然崩溃。
我猜想在Lollipop之后更改权限或弃用可能会导致此问题?
我在下面添加了堆栈跟踪,
编辑 :我不认为ScanActivity在这里是相关的,但万一有(错误确实提到了它) 这是ScanActivity
更新 :即使我正在使用FileProvider,这似乎也是有关FileProvider的原因
Andoird清单
android:name="android.hardware.camera"
android:required="true" />
android:name="android.hardware.camera.autofocus"
android:required="false" />
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
provider_paths
主要活动
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
camera = findViewById(R.id.open_cam);
//first of all we will ask run time permissions for camera and read and write file
checkPermissions();
camera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openCamera();
}
});
}
public void openCamera() {
int preference = ScanConstants.OPEN_CAMERA;
Intent intent = new Intent(this, ScanActivity.class);
intent.putExtra(ScanConstants.OPEN_INTENT_PREFERENCE, preference);
startActivityForResult(intent, OPEN_THING);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && data != null) {
if (requestCode == OPEN_THING) {
Uri uri = data.getExtras().getParcelable(ScanConstants.SCANNED_RESULT);
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
getContentResolver().delete(uri, null, null);
scannedImageView.setImageBitmap(bitmap);
FileOutputStream outputStream = null;
File sdCard = Environment.getExternalStorageDirectory();
File directory = new File (sdCard.getAbsolutePath() +"/Scan Documents");
directory.mkdir();
String filename = String.format("d.jpg", System.currentTimeMillis());
File outFile = new File(directory, filename);
Toast.makeText(this, "Image Saved Successfully", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(outFile));
sendBroadcast(intent);
try{
outputStream = new FileOutputStream(outFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.flush();
outputStream.close();
}catch (FileNotFoundException e)
{
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void checkPermissions()
{
Dexter.withActivity(this)
.withPermissions(
Manifest.permission.CAMERA,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
).withListener(new MultiplePermissionsListener() {
@Override public void onPermissionsChecked(MultiplePermissionsReport report)
{
// check if all permissions are granted
if (report.areAllPermissionsGranted()) {
// do you work now
}
// check for permanent denial of any permission
if (report.isAnyPermissionPermanentlyDenied()) {
// permission is denied permenantly, navigate user to app settings
showSettingsDialog();
}
}
@Override public void onPermissionRationaleShouldBeShown(List permissions, PermissionToken token)
{
token.continuePermissionRequest();
}
}).withErrorListener(new PermissionRequestErrorListener() {
@Override
public void onError(DexterError error) {
Toast.makeText(MainActivity.this, "Error Occured!!!", Toast.LENGTH_SHORT).show();
}
})
.onSameThread()
.check();
}
private void showSettingsDialog()
{
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Need Camera and Storage Permissions");
builder.setMessage("This app needs permissions to use this feature you can grant them in app settings");
builder.setPositiveButton("GOTO SETTINGS", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
openSettings();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
}
private void openSettings()
{
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, 101);
}
堆栈跟踪崩溃
2019-11-27 23:34:41.843 15892-15892/com.nabeeltech.myapplication.debug E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.nabeeltech.myapplication.debug, PID: 15892
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nabeeltech.myapplication.debug/com.scanlibrary.ScanActivity}:
java.lang.SecurityException: UID 10093 does not have permission to content://com.scanlibrary.provider/external_files/scanSample/IMG_20191127_223441.jpg [user 0]
Caused by: java.lang.SecurityException: UID 10093 does not have permission to content://com.scanlibrary.provider/external_files/scanSample/IMG_20191127_223441.jpg [user 0]