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);
我试图在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'
}
和清单:
<?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>
答案 0 :(得分:76)
以下是使用requestPermissions()
:
首先,在清单中定义权限(就像您在帖子中所做的那样),否则,您的请求将被自动拒绝:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
接下来,在onRequestPermissionsResult()中定义一个值来处理权限回调:
private final int REQUEST_PERMISSION_PHONE_STATE=1;
这里是调用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();
}
}
首先,检查您是否已拥有权限(请记住,即使获得权限,用户也可以稍后撤消“应用程序设置”中的权限。)
最后,这是您检查是否获得许可的方式:
@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);
}
答案 1 :(得分:35)
我遇到了同样的问题,原因是manifest merger tool从依赖项中提取android:maxSdkVersion
属性。
要查看您在APK中请求的实际权限,您可以使用aapt
工具,如下所示:
/path/to/android-sdk/build-tools/version/aapt d permissions /path/to/your-apk.apk
在我的情况下,它打印出来:
uses-permission: name='android.permission.WRITE_EXTERNAL_STORAGE' maxSdkVersion='18'
即使我没有在我的清单中指定maxSdkVersion
。我通过将清单中的<uses-permission>
更改为:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion"/>
(工具命名空间为http://schemas.android.com/tools
)
答案 2 :(得分:20)
希望这有助于其他人。
我需要请求WRITE_EXTERNAL_STORAGE的许可,但是尽管尝试了所有提到的不同建议,但没有获得弹出窗口。
最终的罪魁祸首是HockeyApp。它使用清单合并来包含自己对WRITE_EXTERNAL_STORAGE的权限,除了它将最大sdk版本应用到它上面。
解决此问题的方法是将其包含在您的清单文件中,但替换它,以覆盖HockeyApp的版本并取得成功!
4.7.2请求外部存储权限的其他依赖项(SDK 5.0.0及更高版本)为Android O做好准备, HockeySDK-Android 5.0.0及更高版本限制了WRITE_EXTERNAL_STORAGE maxSdkVersion过滤器的权限。在某些用例中,例如 应用程序包含需要此权限的依赖项, maxSdkVersion使这些依赖项无法授予或 请求许可。这些案件的解决方案如下:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace"/>
它会导致其他属性变低 优先清单将被替换而不是合并。
答案 3 :(得分:8)
替换:
ActivityCompat.requestPermissions(this, new String[]{"Manifest.permission.READ_PHONE_STATE"}, 225);
使用:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 225);
The actual string for that permission不是"Manifest.permission.READ_PHONE_STATE"
。使用符号Manifest.permission.READ_PHONE_STATE
。
答案 4 :(得分:4)
我将目标SDK版本从22更新到23,并且运行良好。
答案 5 :(得分:3)
单行代码可能不是问题。
在某些设备上(我不记得它是否有现货),“权限”对话框包含一个标有“不再询问”的复选框。如果您在选中复选框的情况下单击“拒绝”,则不会再次提示您该权限,该权限将自动被应用拒绝。要对此进行验证,您必须进入“设置”->“应用程序”->“权限”,然后为应用程序重新启用该权限。然后将其关闭以再次拒绝。不确定,您可能需要先打开该应用程序,然后才能将其关闭。
我不知道您的Nexus是否装有它。也许值得一试。
答案 6 :(得分:1)
对我来说,问题是错误地请求群组而不是实际的权限。
答案 7 :(得分:1)
我遇到了同样的问题,并通过用android.Manifest.permission.READ_PHONE_STATE替换Manifest.permission.READ_PHONE_STATE解决了这个问题。
答案 8 :(得分:1)
这恰好发生在我身上。事实证明我正在请求所有权限,当我需要过滤到DANGEROUS权限时,它突然开始工作。
fun requestPermissions() {
val missingDangerPermissions = PERMISSIONS
.filter { ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED }
.filter { this.getPackageManager().getPermissionInfo(it, PackageManager.GET_META_DATA).protectionLevel == PermissionInfo.PROTECTION_DANGEROUS } // THIS FILTER HERE!
if (missingDangerPermissions.isNotEmpty()) {
Log.i(TAG, "Requesting dangerous permission to $missingDangerPermissions.")
ActivityCompat.requestPermissions(this,
missingDangerPermissions.toTypedArray(),
REQUEST_CODE_REQUIRED_PERMISSIONS);
return
} else {
Log.i(TAG, "We had all the permissions we needed (yay!)")
}
}
答案 9 :(得分:1)
我在三星S8和N8中遇到了这个问题(在其他任何产品中都发现过)
所以问题出在清单文件uses-permission
<uses-permission android:name="android.permission.CAMERA"
android:requiredFeature="true" />
由于某种原因,属性android:requiredFeature
是罪魁祸首。而且我还没有找到原因的解释。
解决方法就是将其删除
<uses-permission android:name="android.permission.CAMERA" />
答案 10 :(得分:0)
这是我想与大家分享的另一种经验。在实施以下代码以检查BLE访问权限后,出现了问题:
2
我的意思是要区分在清单中已定义的FINE和COARSE位置许可请求。检查ACCESS_COARSE_LOCATION权限时,“请求权限”对话框从不弹出,但始终使用PERMISSION_DENIED调用final String requiredPermission = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && targetSdkVersion >= Build.VERSION_CODES.Q) ?
android.Manifest.permission.ACCESS_FINE_LOCATION :
android.Manifest.permission.ACCESS_COARSE_LOCATION;
(以防在应用程序设置中未启用权限)。因此,我删除了对BUILD.SDK的检查,仅检查了onRequestPermissionsResult
,发现缺少的对话框出现了。
ACCESS_FINE_LOCATION
成功了!
清单来源包含:
final String requiredPermission = android.Manifest.permission.ACCESS_FINE_LOCATION;
,但apk仅包含<uses-permission android:name="android.permission.COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
。在构建期间的某个时间,android.permission.ACCESS_FINE_LOCATION
已被删除。
我希望这可以帮助遇到同样问题的人。
答案 11 :(得分:0)
<!--Declaring the required permissions-->
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.CAMERA" />
然后转到下一步。
答案 12 :(得分:0)
不要忘记在清单中没有多余空格的情况下写权限。就我而言,我有:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE " />
但是,最后,还有一个额外的空间。用正确的方式写
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
现在正在工作
答案 13 :(得分:0)
对我来说,问题在于发出请求后,我的主要活动又发起了另一个活动。那取代了对话框,所以它从未被看到。
答案 14 :(得分:0)
也许此解决方案可以帮助任何人 而不是:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
使用:
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
因此我们将android.
添加到Manifest.permission.WRITE_EXTERNAL_STORAGE
答案 15 :(得分:0)
if(Build.VERSION.SDK_INT&gt; = Build.VERSION_CODES.M){ requestPermissions(new String [] {Manifest.permission.ACCESS_COARSE_LOCATION},MY_PERMISSIONS_REQUEST_READ_LOCATION); }
答案 16 :(得分:0)
对我来说,错误在清单中:权限是大写的。 Android Studio以大写形式向我建议权限。我不关心这个问题,我花了两个小时来解决这个问题。
权限的正确语法是
&lt; uses-permission android:name =“android.permission.WRITE_EXTERNAL_STORAGE”/&gt;
答案 17 :(得分:0)
上述信息很好,但将targetSdkVersion
设置为23(或更高)严重,Android会将清单中的<uses-permission>
标记解释为&#34;我会在代码中询问&#34;而不是&#34;我要求安装。&#34;很多消息来源都会告诉您需要<uses-permission>
标签,但没有人说明为什么,如果您没有设置该值,您就会像我一样困惑几个小时结束。
答案 18 :(得分:0)
对我来说问题是我的请求代码无效。我选择0xDEADBEEF作为请求代码并且它默默地失败了(也许它在某个地方被内部转移到小于32位的东西?)如果我选择255,一切正常,就像上面描述的NightSkyDev一样。
答案 19 :(得分:0)
我有同样的问题。我更新到 buildToolsVersion“23.0.3”它突然起作用了。希望这可以帮助任何人解决这个问题。