簡體   English   中英

啟動相機崩潰android的權限

[英]Permission on launch camera crash android

我制作了一個帶有按鈕的簡單應用程序 ,可以在手機上打開相機(API 19),用於掃描文檔和裁剪圖像。 效果很好,但是當我嘗試在其他型號的手機(例如API 27)上啟動相機時...該應用突然崩潰。

我猜想在Lollipop之后更改權限或棄用可能會導致此問題?

我在下面添加了堆棧跟蹤,

注意:權限已使用Android庫Dexter

編輯 :我不認為ScanActivity在這里是相關的,但萬一有(錯誤確實提到了它) 這是ScanActivity

更新 :即使我正在使用FileProvider,這似乎也是有關FileProvider的原因

Andoird清單

  <uses-feature
    android:name="android.hardware.camera"
    android:required="true" />
 <uses-feature
    android:name="android.hardware.camera.autofocus"
    android:required="false" />

<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true"
        tools:replace="android:authorities">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
    </provider>

provider_paths

<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="." />

主要活動

    @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<PermissionRequest> 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]

看起來您試圖直接從uri讀取位圖文件。 您應該使用FileProvider

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM