Java 即使我已经声明 Android 权限也不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32635704/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android permission doesn't work even if I have declared it
提问by Nathan Loudjani
I'm trying to write code to send an SMS from an Android app, but when I try to send the SMS it sends me back the error:
我正在尝试编写代码以从 Android 应用程序发送短信,但是当我尝试发送短信时,它向我发送了错误消息:
09-17 18:37:29.974 12847-12847/**.**.****E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: **.**.****, PID: 12847
java.lang.SecurityException: Sending SMS message: uid 10092 does not have android.permission.SEND_SMS.
at android.os.Parcel.readException(Parcel.java:1599)
at android.os.Parcel.readException(Parcel.java:1552)
at com.android.internal.telephony.ISms$Stub$Proxy.sendTextForSubscriber(ISms.java:768)
at android.telephony.SmsManager.sendTextMessageInternal(SmsManager.java:310)
at android.telephony.SmsManager.sendTextMessage(SmsManager.java:293)
at **.**.****.MainActivity.onClick(MainActivity.java:70)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I checked but I have the permissions in the manifest, as follows:
我检查过,但我在清单中有权限,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-feature android:name="android.hardware.telephony"
android:required="true"/>
<application
android:exported="true"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I searched the internet but all the errors were about the <uses-permission/>
syntax, could you help me please?
我搜索了互联网,但所有错误都与<uses-permission/>
语法有关,您能帮帮我吗?
采纳答案by CommonsWare
(the following is extracted from a blog post of mine about this)
(以下内容摘自我关于此的博客文章)
The big reason for not getting your permission nowadays is because
your project has a targetSdkVersion
of 23 or higher, and the permission
that you are requesting is "dangerous". In Android 6.0, this includes:
现在没有得到你的许可的一个重要原因是因为你的项目有targetSdkVersion
23 或更高,并且你请求的许可是“危险的”。在 Android 6.0 中,这包括:
ACCESS_COARSE_LOCATION
ACCESS_FINE_LOCATION
ADD_VOICEMAIL
BODY_SENSORS
CALL_PHONE
CAMERA
GET_ACCOUNTS
PROCESS_OUTGOING_CALLS
READ_CALENDAR
READ_CALL_LOG
READ_CELL_BROADCASTS
READ_CONTACTS
READ_EXTERNAL_STORAGE
READ_PHONE_STATE
READ_SMS
RECEIVE_MMS
RECEIVE_SMS
RECEIVE_WAP_PUSH
RECORD_AUDIO
SEND_SMS
USE_SIP
WRITE_CALENDAR
WRITE_CALL_LOG
WRITE_CONTACTS
WRITE_EXTERNAL_STORAGE
ACCESS_COARSE_LOCATION
ACCESS_FINE_LOCATION
ADD_VOICEMAIL
BODY_SENSORS
CALL_PHONE
CAMERA
GET_ACCOUNTS
PROCESS_OUTGOING_CALLS
READ_CALENDAR
READ_CALL_LOG
READ_CELL_BROADCASTS
READ_CONTACTS
READ_EXTERNAL_STORAGE
READ_PHONE_STATE
READ_SMS
RECEIVE_MMS
RECEIVE_SMS
RECEIVE_WAP_PUSH
RECORD_AUDIO
SEND_SMS
USE_SIP
WRITE_CALENDAR
WRITE_CALL_LOG
WRITE_CONTACTS
WRITE_EXTERNAL_STORAGE
For these permissions, not only does your targetSdkVersion
23+ app
need to have the <uses-permission>
element(s), but you also have
to ask for those permissions at runtime from the user on Android 6.0+
devices, using methods like checkSelfPermission()
and
requestPermissions()
.
对于这些权限,您的targetSdkVersion
23+ 应用程序不仅需要具有<uses-permission>
元素,而且您还必须在运行时向 Android 6.0+ 设备上的用户请求这些权限,使用方法如checkSelfPermission()
和
requestPermissions()
。
As a temporary workaround, drop your targetSdkVersion
below 23.
作为临时解决方法,将您的值targetSdkVersion
降至 23 以下。
However, eventually, you will have some reason to want your
targetSdkVersion
to be 23 or higher. At that time, you will need
to adjust your app to use the new runtime permission system.
The Android documentation has
a page dedicated to this topic.
但是,最终,您将有一些理由希望自己
targetSdkVersion
年满 23 岁或更高。届时,您需要调整您的应用程序以使用新的运行时权限系统。Android 文档有
一个专用于此主题的页面。
回答by Dharmendra Pratap
If you are using sdk 23 or higher then you must check run time permissions.
如果您使用 sdk 23 或更高版本,则必须检查运行时权限。
回答by Dumi Jay
Along with CommonsWare's answer,
随着CommonsWare的回答,
There is a Security Setting (I checked on CM13) to set SMS Message Limit. If you set this to "None", OS will popup a Dialog for every SMS, even after obtaining SMS_SEND permission in the runtime. Best thing is to set this to maximum.
有一个安全设置(我在 CM13 上检查过)来设置 SMS 消息限制。如果您将此设置为“无”,即使在运行时获得 SMS_SEND 权限后,操作系统也会为每个 SMS 弹出一个对话框。最好的办法是将其设置为最大值。
If the maximum is not enough, there are ways to increases the maximum rate on a rooted device.
如果最大值还不够,可以通过多种方式提高 root 设备上的最大速率。
回答by Harshad Pansuriya
when you declare permisson
in Manifest
and it's not work means you are performing Task in MarshMallow
and for MarshMallow
you have set Permisson at RunTime
.
在声明permisson
中Manifest
,它不是工作,你在执行任务的手段MarshMallow
和MarshMallow
你在设置在未经许可的RunTime
。
like this way
像这样
ActivityCompat.requestPermissions();
回答by Masquitos
I added this to my MainActivity, that resolve my problem
我将此添加到我的 MainActivity,解决了我的问题
int MY_PERMISSIONS_REQUEST_READ_CONTACTS=0;
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
回答by user7176550
Above API level 23 you will be given programmatically pragmatically like:
在 API 级别 23 以上,您将以编程方式以务实的方式获得,例如:
private static final int PERMISSION_REQUEST_CODE = 1;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.SEND_SMS)
== PackageManager.PERMISSION_DENIED) {
Log.d("permission", "permission denied to SEND_SMS - requesting it");
String[] permissions = {Manifest.permission.SEND_SMS};
requestPermissions(permissions, PERMISSION_REQUEST_CODE);
}
}
回答by Dan Alboteanu
request permission pragmatically (after API 23)
务实地请求权限(在 API 23 之后)
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Ask for permision
ActivityCompat.requestPermissions(this,new String[] { Manifest.permission.SEND_SMS}, 1);
}
else {
// Permission has already been granted
}
"If the app has the permission, the method checkSelfPermission() returns PERMISSION_GRANTED, and the app can proceed with the operation.
“如果应用程序有权限,方法 checkSelfPermission() 返回 PERMISSION_GRANTED,应用程序可以继续操作。
If the app does not have the permission, the method returns PERMISSION_DENIED, and the app has to explicitly ask the user for permission. You need to prompt the user for that permission, as shown in the above code. Calling requestPermissions() brings up a standard Android dialog, which you cannot customize."
如果应用程序没有权限,则该方法返回 PERMISSION_DENIED,并且应用程序必须明确要求用户授予权限。您需要提示用户获得该权限,如上面的代码所示。调用 requestPermissions() 会打开一个标准的 Android 对话框,您无法对其进行自定义。”
回答by Zohaib Hassan
If you are using Android version "23" or "23+", then app will show you errors when you are trying to access anything which requires user's permission. You have to ask for permissions at run-time even if you have declared those permissions in Android manifest.
如果您使用的是 Android 版本“23”或“23+”,那么当您尝试访问需要用户许可的任何内容时,应用程序将向您显示错误。即使您已经在 Android 清单中声明了这些权限,您也必须在运行时请求权限。
Check this: https://developer.android.com/training/permissions/requesting.html
检查这个:https: //developer.android.com/training/permissions/requesting.html
But if you have created your whole application and don't want to change at every place then a little cheat will be sufficient.
但是,如果您已经创建了整个应用程序并且不想在每个地方都进行更改,那么稍微作弊就足够了。
Go to "Build.gradle" file and change the target Sdk version to less than 23, like 22, 21.
转到“Build.gradle”文件并将目标 Sdk 版本更改为小于 23,例如 22、21。
回答by Rishabh Saxena
Please go through the link below, https://developer.android.com/guide/topics/permissions/overview.html
请通过下面的链接, https://developer.android.com/guide/topics/permissions/overview.html
Some samples are also available there to get start with the permissions.
那里还提供了一些示例以开始使用权限。
To make android more secure now developers has to mention permission in manifest as well as they should have to ask user as well in run time to get the work done. They are permission categorized in dangerous permission section which are mention below
现在,为了使 android 更安全,开发人员必须在清单中提及权限,并且他们还应该在运行时询问用户以完成工作。它们是分类在危险权限部分的权限,如下所述
CALENDAR
日历
READ_CALENDAR
WRITE_CALENDAR
CAMERA
相机
CAMERA
CONTACTS
联系方式
READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
LOCATION
地点
ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
MICROPHONE
麦克风
RECORD_AUDIO
PHONE
电话
READ_PHONE_STATE
READ_PHONE_NUMBERS
CALL_PHONE
ANSWER_PHONE_CALLS (must request at runtime)
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
ANSWER_PHONE_CALLS
SENSORS
传感器
BODY_SENSORS
SMS
短信
SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
STORAGE
贮存
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
回答by Amirhf
You can use this code to access your messages
您可以使用此代码访问您的消息
Open a Dialog using the code below:
使用以下代码打开对话框:
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
1);
Get the Activity result as below:
获取活动结果如下:
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
or edit file build.gradle
and chanche number targetSdkVersion
less than 23
And no longer need the code above
或编辑文件build.gradle
和chanche numbertargetSdkVersion
小于23
并且不再需要上面的代码
NOTE
Of course this is not the case, and it's just an educational aspect
注意
当然不是这样,这只是一个教育方面