ActivityCompat.requestPermissions未显示对话框

Ida*_*zen 60 java permissions android

if (ContextCompat.checkSelfPermission(RegisterActivity.this,      Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED){
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE_PERMISSION);
Run Code Online (Sandbox Code Playgroud)

我正试图在nexus 5 api 23上使用这个功能,它只是没有向我显示它应该做的对话框,它只是没有做任何事情.什么可能导致问题?(此代码在java活动中)我尝试将最小api更改为23并使用requestPermissions()而不使用ActivityCompat但仍无效.

apply plugin: 'com.android.application'

android {
compileSdkVersion 23
buildToolsVersion "23.0.2"

defaultConfig {
    applicationId "com.example.idanayzen.photomap"
    minSdkVersion 23
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.google.android.gms:play-services:8.4.0'
compile 'com.android.support:design:23.1.1'
}
Run Code Online (Sandbox Code Playgroud)

和清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.idanayzen.photomap">

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_SMS" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">


    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="@string/google_maps_key" />

    <activity
        android:name=".MapsActivity"
        android:label="@string/title_activity_maps" />
    <activity android:name=".RegisterActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".WrongPhoneNum"></activity>
</application>

</manifest>
Run Code Online (Sandbox Code Playgroud)

Nig*_*Dev 81

以下是使用示例requestPermissions():

首先,在清单中定义权限(如您在帖子中所做的那样),否则,您的请求将被自动拒绝:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Run Code Online (Sandbox Code Playgroud)

接下来,在onRequestPermissionsResult()中定义一个值来处理权限回调:

private final int REQUEST_PERMISSION_PHONE_STATE=1;
Run Code Online (Sandbox Code Playgroud)

这是调用requestPermissions()的代码:

private void showPhoneStatePermission() {
    int permissionCheck = ContextCompat.checkSelfPermission(
            this, Manifest.permission.READ_PHONE_STATE);
    if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.READ_PHONE_STATE)) {
            showExplanation("Permission Needed", "Rationale", Manifest.permission.READ_PHONE_STATE, REQUEST_PERMISSION_PHONE_STATE);
        } else {
            requestPermission(Manifest.permission.READ_PHONE_STATE, REQUEST_PERMISSION_PHONE_STATE);
        }
    } else {
        Toast.makeText(MainActivity.this, "Permission (already) Granted!", Toast.LENGTH_SHORT).show();
    }
}
Run Code Online (Sandbox Code Playgroud)

首先,检查您是否已经拥有权限(请记住,即使获得了权限,用户也可以稍后撤消"应用程序设置"中的权限.)

最后,这是您检查是否获得许可的方式:

@Override
public void onRequestPermissionsResult(
        int requestCode,
        String permissions[],
        int[] grantResults) {
    switch (requestCode) {
        case REQUEST_PERMISSION_PHONE_STATE:
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(MainActivity.this, "Permission Granted!", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(MainActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
            }
    }
}

private void showExplanation(String title,
                             String message,
                             final String permission,
                             final int permissionRequestCode) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(title)
            .setMessage(message)
            .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    requestPermission(permission, permissionRequestCode);
                }
            });
    builder.create().show();
}

private void requestPermission(String permissionName, int permissionRequestCode) {
    ActivityCompat.requestPermissions(this,
            new String[]{permissionName}, permissionRequestCode);
}
Run Code Online (Sandbox Code Playgroud)

  • 如果requestPermissions不工作,那么进行所有这些检查是否无用?在我的代码我只是检查我是否有权限,如果不是我调用requestPermissions.后来我猜这会改变.我完全按照你的说法完成了requestPermissions语法,但它对我不起作用. (12认同)
  • 感谢您突出显示"首先,在清单中定义权限(就像您在帖子中所做的那样),否则,您的请求将被自动拒绝".我是这样的<uses-permission android:name ="android.permission.GET_ACCOUNTS"android:maxSdkVersion ="22"tools:replace ="maxSdkVersion"/>我将"22"改为"23" (4认同)

hru*_*unk 42

我有同样的问题,结果是由于清单合并工具android:maxSdkVersion从依赖项中提取属性.

要查看您在APK中请求的实际权限,您可以使用此aapt工具,如下所示:

/path/to/android-sdk/build-tools/version/aapt d permissions /path/to/your-apk.apk
Run Code Online (Sandbox Code Playgroud)

在我的情况下,它打印:

uses-permission: name='android.permission.WRITE_EXTERNAL_STORAGE' maxSdkVersion='18'
Run Code Online (Sandbox Code Playgroud)

即使我没有maxSdkVersion在我的清单中指定一个.我通过将<uses-permission>清单更改为:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion"/>
Run Code Online (Sandbox Code Playgroud)

(工具命名空间所在的位置http://schemas.android.com/tools)

  • 你救了我的一天!谢谢 (4认同)
  • 至少到目前为止,要查看实际的权限(合并的)清单,您可以在没有任何其他工具(例如“ aapt”)的情况下查看它。当您从Android Studio中看到AndroidManifest.xml时,请查看底部的标签,只需单击“合并的清单”标签。 (2认同)

Tal*_*lha 23

希望这有助于其他人.

我需要请求WRITE_EXTERNAL_STORAGE的许可,但是尽管尝试了所有提到的不同建议,但没有获得弹出窗口.

最终的罪魁祸首是HockeyApp.它使用清单合并来包含自己对WRITE_EXTERNAL_STORAGE的权限,除了它将最大sdk版本应用于它.

解决这个问题的方法是将它包含在你的清单文件中但是替换它,以覆盖HockeyApp的版本和成功!

4.7.2请求外部存储权限的其他依赖项(SDK 5.0.0及更高版本)要为Android O做好准备,HockeySDK-Android 5.0.0及更高版本会使用maxSdkVersion过滤器限制WRITE_EXTERNAL_STORAGE权限.在某些用例中,例如,当应用程序包含需要此权限的依赖项时,maxSdkVersion使这些依赖项无法授予或请求权限.这些案件的解决方案如下:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace"/>
Run Code Online (Sandbox Code Playgroud)

这将导致来自低优先级清单的其他属性将被替换而不是被合并.

https://support.hockeyapp.net/kb/client-integration-android/hockeyapp-for-android-sdk#permissions-advanced


Com*_*are 9

更换:

ActivityCompat.requestPermissions(this, new String[]{"Manifest.permission.READ_PHONE_STATE"}, 225);
Run Code Online (Sandbox Code Playgroud)

有:

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 225);
Run Code Online (Sandbox Code Playgroud)

该权限的实际字符串不是"Manifest.permission.READ_PHONE_STATE".使用符号Manifest.permission.READ_PHONE_STATE.


and*_*guy 8

一行代码可能不是问题。

在某些设备上(我不记得它是否有库存 Android),权限对话框包含一个标记为“不再询问”的复选框。如果您在选中该框的情况下单击拒绝,则不会再次提示您输入该权限,应用程序将自动拒绝该权限。要恢复此设置,您必须进入设置 -> 应用程序 -> 权限并为该应用程序重新启用该权限。然后将其关闭以再次拒绝它。您可能需要先打开该应用程序,然后再将其关闭,这不确定。

我不知道你的 Nexus 有没有。也许值得一试。

  • 我有这样的情况。我能想到的最好的解决办法是检查 `onRequestPermissionsResult()` 中的 `PackageManager.PERMISSION_DENIED` 并调整 UI 以向用户解释必须手动设置权限并打开 `Settings.ACTION_APPLICATION_DETAILS_SETTINGS`。 (2认同)

小智 5

就我而言,目标 sdk 33 到 32 解决了这个问题