广播接收器在 Android 6.0 Marshmallow 中不工作
Broadcast Receivers not working in Android 6.0 Marshmallow
我刚刚将我的 Nexus 5 更新到 android 6,直到现在我的应用程序运行良好,但现在广播接收器不工作。新版本有什么变化吗?
这是我试过的代码,它适用于以前的版本,但不适用于棉花糖 -
Android 清单
<intent-filter >
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
<uses-permission android:name="android.permission.READ_SMS" ></uses-permission>
广播接收器
public String TAG ="someClass";
private static String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equalsIgnoreCase(ACTION_SMS_RECEIVED)) {
Log.d(TAG, "Received...");
}
}
服务
Broadcast_receiver broadcast_receiver = new Broadcast_receiver();
IntentFilter filter1 = new IntentFilter();
filter1.addAction("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(broadcast_receiver, filter1);
同样,PHONE_STATE 的广播接收器也不工作。
您应用的目标 API 级别是 23,即 android M (6.0)。在 android M 中有与用户权限相关的巨大变化。
Here 是一篇很好的文章,解释了这些变化。
Marshmallow 正在阻止危险权限。
这不适用于所列场景,但可能对其他人有所帮助。我一直来找这个 SO 为什么我们的一些广播接收器不工作。我们有一个自定义权限设置并且有 android:protectionLevel="dangerous"
。将其更改为 android:protectionLevel= "signature"
一切都开始工作了。
如Android - Requesting Permissions
所述
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app... The user can revoke the permissions at any time...
还表示:
System permissions are divided into two categories, normal and dangerous:
Normal permissions do not directly risk the user's privacy. If your app lists a normal permission in its manifest, the system grants the permission automatically
Dangerous permissions can give the app access to the user's
confidential data. If you list
a dangerous permission, the user has to explicitly give approval to
your app
这里是 Dangerous Permissions and Normal Permissions
的完整列表
这基本上意味着您需要在实际需要时手动请求任何危险权限。
由于您的代码中可能会多次需要它,因此您可以创建一个可重用的方法来检查是否已经授予了特定权限,如果没有,则向用户请求。
举个例子:
Java
public class PermissionManager {
//A method that can be called from any Activity, to check for specific permission
public static void check(Activity activity, String permission, int requestCode){
//If requested permission isn't Granted yet
if (ActivityCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
//Request permission from user
ActivityCompat.requestPermissions(activity,new String[]{permission},requestCode);
}
}
}
Kotlin
object PermissionManager {
//A method that can be called from any Activity, to check for specific permission
fun check(activity: Activity, permission: String, requestCode: Int) {
//If requested permission isn't Granted yet
if (ActivityCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
//Request permission from user
ActivityCompat.requestPermissions(activity, arrayOf(permission), requestCode)
}
}
}
用法:
Java
//Inside your activity:
//1. Define static constant for each permission request
public static final int REQUEST_CODE_FOR_SMS=1;
//2. When needed (for example inside .onStart event) use method PermissionManager.check for requested permission
@Override
protected void onStart() {
super.onStart();
PermissionManager.check(this, Manifest.permission.RECEIVE_SMS, REQUEST_CODE_FOR_SMS);
}
//3. Handle User's response for your permission request
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if(requestCode==REQUEST_CODE_FOR_SMS){//response for SMS permission request
if(grantResults[0]==PackageManager.PERMISSION_GRANTED){
//What to do if User allowed SMS permission
}else{
//What to do if user disallowed requested SMS permission
}
}
}
Kotlin
//Inside your activity:
//1. Define static constant for each permission request
val REQUEST_CODE_FOR_SMS = 1
//2. When needed (for example inside .onStart event) use method PermissionManager.check for requested permission
override fun onStart() {
super.onStart()
PermissionManager.check(this, Manifest.permission.RECEIVE_SMS, REQUEST_CODE_FOR_SMS)
}
//3. Handle User's response for your permission request
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
if (requestCode == REQUEST_CODE_FOR_SMS) {//response for SMS permission request
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//What to do if User allowed SMS permission
} else {
//What to do if user disallowed requested SMS permission
}
}
}
注:
如果您需要在 Fragment
实例中使用 PermissionManager.check
,请使用:getActivity()
作为其第一个参数。
可以用checkSelfPermission
inside Service
instance, to check if some permission is granted already, but not requestPermissions
来申请。因为checkSelfPermission
可以用于任何Context
,而requestPermissions
只能用于Activity
我刚刚将我的 Nexus 5 更新到 android 6,直到现在我的应用程序运行良好,但现在广播接收器不工作。新版本有什么变化吗? 这是我试过的代码,它适用于以前的版本,但不适用于棉花糖 -
Android 清单
<intent-filter >
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
<uses-permission android:name="android.permission.READ_SMS" ></uses-permission>
广播接收器
public String TAG ="someClass";
private static String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equalsIgnoreCase(ACTION_SMS_RECEIVED)) {
Log.d(TAG, "Received...");
}
}
服务
Broadcast_receiver broadcast_receiver = new Broadcast_receiver();
IntentFilter filter1 = new IntentFilter();
filter1.addAction("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(broadcast_receiver, filter1);
同样,PHONE_STATE 的广播接收器也不工作。
您应用的目标 API 级别是 23,即 android M (6.0)。在 android M 中有与用户权限相关的巨大变化。 Here 是一篇很好的文章,解释了这些变化。
Marshmallow 正在阻止危险权限。
这不适用于所列场景,但可能对其他人有所帮助。我一直来找这个 SO 为什么我们的一些广播接收器不工作。我们有一个自定义权限设置并且有 android:protectionLevel="dangerous"
。将其更改为 android:protectionLevel= "signature"
一切都开始工作了。
如Android - Requesting Permissions
所述Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app... The user can revoke the permissions at any time...
还表示:
System permissions are divided into two categories, normal and dangerous:
Normal permissions do not directly risk the user's privacy. If your app lists a normal permission in its manifest, the system grants the permission automatically
Dangerous permissions can give the app access to the user's confidential data. If you list a dangerous permission, the user has to explicitly give approval to your app
这里是 Dangerous Permissions and Normal Permissions
的完整列表这基本上意味着您需要在实际需要时手动请求任何危险权限。
由于您的代码中可能会多次需要它,因此您可以创建一个可重用的方法来检查是否已经授予了特定权限,如果没有,则向用户请求。
举个例子:
Java
public class PermissionManager {
//A method that can be called from any Activity, to check for specific permission
public static void check(Activity activity, String permission, int requestCode){
//If requested permission isn't Granted yet
if (ActivityCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
//Request permission from user
ActivityCompat.requestPermissions(activity,new String[]{permission},requestCode);
}
}
}
Kotlin
object PermissionManager {
//A method that can be called from any Activity, to check for specific permission
fun check(activity: Activity, permission: String, requestCode: Int) {
//If requested permission isn't Granted yet
if (ActivityCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
//Request permission from user
ActivityCompat.requestPermissions(activity, arrayOf(permission), requestCode)
}
}
}
用法:
Java
//Inside your activity:
//1. Define static constant for each permission request
public static final int REQUEST_CODE_FOR_SMS=1;
//2. When needed (for example inside .onStart event) use method PermissionManager.check for requested permission
@Override
protected void onStart() {
super.onStart();
PermissionManager.check(this, Manifest.permission.RECEIVE_SMS, REQUEST_CODE_FOR_SMS);
}
//3. Handle User's response for your permission request
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if(requestCode==REQUEST_CODE_FOR_SMS){//response for SMS permission request
if(grantResults[0]==PackageManager.PERMISSION_GRANTED){
//What to do if User allowed SMS permission
}else{
//What to do if user disallowed requested SMS permission
}
}
}
Kotlin
//Inside your activity:
//1. Define static constant for each permission request
val REQUEST_CODE_FOR_SMS = 1
//2. When needed (for example inside .onStart event) use method PermissionManager.check for requested permission
override fun onStart() {
super.onStart()
PermissionManager.check(this, Manifest.permission.RECEIVE_SMS, REQUEST_CODE_FOR_SMS)
}
//3. Handle User's response for your permission request
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
if (requestCode == REQUEST_CODE_FOR_SMS) {//response for SMS permission request
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//What to do if User allowed SMS permission
} else {
//What to do if user disallowed requested SMS permission
}
}
}
注:
如果您需要在
Fragment
实例中使用PermissionManager.check
,请使用:getActivity()
作为其第一个参数。可以用
checkSelfPermission
insideService
instance, to check if some permission is granted already, but notrequestPermissions
来申请。因为checkSelfPermission
可以用于任何Context
,而requestPermissions
只能用于Activity