簡體   English   中英

Android:權限拒絕:以撤銷權限啟動 Intent android.permission.CAMERA

[英]Android: Permission Denial: starting Intent with revoked permission android.permission.CAMERA

我正在嘗試啟動ACTION_IMAGE_CAPTURE活動以在我的應用程序中拍照,但我收到了主題錯誤。

堆棧跟蹤:

FATAL EXCEPTION: main
Process: il.ac.shenkar.david.todolistex2, PID: 3293
java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=com.google.android.GoogleCamera/com.android.camera.CaptureActivity } from ProcessRecord{22b0eb2 3293:il.ac.shenkar.david.todolistex2/u0a126} (pid=3293, uid=10126) 
with revoked permission android.permission.CAMERA

相機權限被添加到 manifest.xml 文件中:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />

這是打開相機的調用:

RadioGroup radioGroup = (RadioGroup) findViewById(R.id.statusgroup);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId)
        {
            RadioButton rb = (RadioButton) findViewById(R.id.donestatusRBtn);
            if(rb.isChecked())
            {
                Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                    startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
                }
            }
        }
    });

移除此權限

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

我在android 7中執行我的應用程序時遇到了這個錯誤。經過測試,我注意到用戶權限不在項目A中,而是在項目B中,我只在android 5設備中進行了測試。 因此,我刪除了項目 B 中的該權限,以便在其他針對 android 7 的設備上運行它並最終可以打開。

另外,我添加了 Android 在此處建議的文件提供程序代碼https://developer.android.com/training/camera/photobasics.html希望這會有所幫助。

您好,您可以在清單文件中使用這些權限以及其他權限,

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

現在我們有了非常有序的權限處理方式。 所以,這里是步驟。 我在這里添加了 kotlin。

步驟 1. 將其聲明為全局變量或任何位置。

private val permissions = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { granted ->
        granted.entries.forEach {
            when (it.value) {
                true -> {
                    // Call whatever you want to do when someone allow the permission. 
                }
                false -> {
                    showPermissionSettingsAlert(requireContext())
                }
            }
        }
    }

第2步。

// You can put this line in constant.
val storagePermission = arrayOf(
    Manifest.permission.READ_EXTERNAL_STORAGE
)

// You can put this in AppUtil. 
fun checkPermissionStorage(context: Context): Boolean {
        val result =
            ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE)

        return result == PackageManager.PERMISSION_GRANTED
 }


// Put this where you need Permission check. 

    if (!checkPermissionStorage(requireContext())) {
        permissions.launch(
                storagePermission
        )
    } else {
        // Permission is already added. 
    }

步驟 3. 權限拒絕對話框。 如果你願意,你可以使用它。

fun showPermissionSettingsAlert(context: Context) {
    val builder = AlertDialog.Builder(context)
    builder.setTitle("Grant Permission")
    builder.setMessage("You have rejected the Storage permission for the application. As it is absolutely necessary for the app to perform you need to enable it in the settings of your device. Please select \"Go to settings\" to go to application settings in your device.")
    builder.setPositiveButton("Allow") { dialog, which ->
        val intent = Intent()
        intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
        val uri = Uri.fromParts("package", context.packageName, null)
        intent.data = uri
        context.startActivity(intent)
    }
    builder.setNeutralButton("Deny") { dialog, which ->

        dialog.dismiss()
    }
    val dialog = builder.create()
    dialog.show()
}

謝謝

希望這會幫助你(Y)。

就我而言,問題與我的模擬器權限有關,

要解決此問題:

1-轉到模擬器的設置。

2- 尋找應用程序和通知。

3- 單擊添加權限。

看圖片: https ://i.stack.imgur.com/z4GfK.png

4- 選擇列表中的相機。

5- 在提供的列表中查找您的應用程序。

6-啟用相機。

看圖片: https ://i.stack.imgur.com/dJ8wG.pngEnjoy

現在你可以在你的模擬器上使用你的相機了:)

這是我解決我的方法:

首先,我認為當您嘗試在沒有完全權限的情況下使用設備相機(SDK < 26)時會出現問題。

是的,即使您已經包含此權限:

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

為了解決這個問題,我將更改為:

<uses-permission android:name="android.permission.CAMERA" 
                 android:required="true" 
                 android:requiredFeature="true"/>

來自 Android Docs 的這些信息可能真的很有幫助

如果您的應用程序使用但不需要攝像頭才能運行,請將android:required設置為false 這樣一來,Google Play 將允許沒有攝像頭的設備下載您的應用程序。 然后,您有責任通過調用hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)在運行時檢查相機的可用性。 如果相機不可用,則應禁用相機功能。

private String [] permissions = {"android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.ACCESS_FINE_LOCATION", "android.permission.READ_PHONE_STATE", "android.permission.SYSTEM_ALERT_WINDOW","android.permission.CAMERA"};

在你的OnCreate添加這個:

int requestCode = 200;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    requestPermissions(permissions, requestCode);
}

正如一些人所指出的,一種解決方案是從 AndroidManifest.xml 中刪除相機權限,即刪除以下行:

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

然而,這對我來說還不夠,因為我需要相機權限才能在我的應用程序中使用其他東西。 所以對我有用的是將該權限標記為不需要,如下所示:

<uses-permission android:name="android.permission.CAMERA" android:required="false" />

簡短的回答......它正在尋找權限,如果權限失敗,它會拋出異常; 此外,在這種情況下,它正在尋找兩個權限,即第一個存儲和第二個攝像頭。

長答案.....給它權限寫入方式以在所有版本的 Android 上工作。我正在循環獲取權限存儲和相機,以便它可以與 Intent 一起使用。

  1. 在 AndroidManifest.xml 中維護
<uses-feature
        android:name="android.hardware.camera.any"
        android:required="true" />
    <uses-feature
        android:name="android.hardware.camera.autofocus"
        android:required="false" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  1. 檢查或請求權限
  private void myStoragePermission() {
        if (ContextCompat.checkSelfPermission(Activity_Scan_QR.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            myCameraPermission();
        } else {
            //changed here
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
            }
        }
    }

    //+10 changed its sinature as Fragment; without it  onRequestPermissionsResult won't bbe called
    private void myCameraPermission() {
        if (ContextCompat.checkSelfPermission(Activity_Scan_QR.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            takePicture();
        } else {
            //changed here
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
            }
        }
    }

  1. 添加 onRequestPermissionsResult
 @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case REQUEST_WRITE_PERMISSION:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    myStoragePermission();
                } else {

                    showSnackbar(R.string.act_ScanQR_txt13, R.string.settings,
                            new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    // Build intent that displays the App settings screen.
                                    Intent intent = new Intent();
                                    intent.setAction(
                                            Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                    Uri uri = Uri.fromParts("package",
                                            BuildConfig.APPLICATION_ID, null);
                                    intent.setData(uri);
                                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    startActivity(intent);
                                }
                            });
                }
            case REQUEST_CAMERA_PERMISSION:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    takePicture();
                } else {

                    showSnackbar(R.string.act_ScanQR_txt14, R.string.settings,
                            new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    // Build intent that displays the App settings screen.
                                    Intent intent = new Intent();
                                    intent.setAction(
                                            Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                    Uri uri = Uri.fromParts("package",
                                            BuildConfig.APPLICATION_ID, null);
                                    intent.setData(uri);
                                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    startActivity(intent);
                                }
                            });

                }
        }
    }

在上面的代碼中 takePicture(); 是我在獲得存儲和相機權限后調用意圖(開始意圖)的地方。

不要因閱讀大量錯誤而感到困惑;)

供以后參考,如果有人在flutter相關的android項目中遇到問題:

https://github.com/apptreesoftware/flutter_barcode_reader/issues/32#issuecomment-420516729

萬一其他人遇到這個問題,我的問題是該應用程序在我運行它時沒有請求任何權限。 似乎小米設備會自動拒絕通過 adb 安裝的應用程序的權限。 我剛剛通過設置啟用了權限,它起作用了。

如果您需要保留

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

清單中的權限,只需確保在打開系統相機之前已授予權限。 在現代 android 中,你可以這樣做:

   val cameraPermissionResult =
    registerForActivityResult(ActivityResultContracts.RequestPermission()) { permitted ->
        if (permitted) {
            openSystemCamera()
        }
    }

您可以使用 cameraPermissionResult 如下:

cameraPermissionResult.launch(Manifest.permission.CAMERA)

如果您的應用程序已經授予該權限,它將只調用openSystemCamera() ,而無需任何用戶操作。 在其他情況下,將顯示權限對話框並根據用戶選擇的權限打開系統攝像頭。

我來晚了,但請檢查一下,因為總是有一些更新

根據官方開發者頁面 - https://developer.android.com/training/camera/photobasics ,您無需在Manifest.xml中使用uses-permission而是使用uses-feature

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

注意- 它是uses-feature ,而不是uses-permission

檢查正確,如果您同時使用uses-permissionuses-feature ,則可能會發生相同的崩潰(此注釋最重要,然后是官方頁面的更新內容,因為我同時使用了這兩個參數並且面對這個崩潰,當我開始在我的應用程序中處理相機模塊時,我不知道為什么我沒有遇到這個問題,但現在應用程序突然開始崩潰)

有關android:required的更多信息來自開發者頁面:

如果您的應用程序使用但不需要攝像頭來運行,請將 android:required 設置為 false。 這樣一來,Google Play 將允許沒有攝像頭的設備下載您的應用程序。 然后,您有責任通過調用 hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY) 在運行時檢查相機的可用性。 如果相機不可用,則應禁用相機功能。

在您的 androidManifest 中,您必須添加:

 <uses-feature android:name="android.hardware.camera" />

是android相機項目的完整清單示例

暫無
暫無

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

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