广播接收器在 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:

  1. 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

  2. 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
        }
    }
}

注:

  1. 如果您需要在 Fragment 实例中使用 PermissionManager.check,请使用:getActivity() 作为其第一个参数。

  2. 可以用checkSelfPermission inside Service instance, to check if some permission is granted already, but not requestPermissions来申请。因为checkSelfPermission可以用于任何Context,而requestPermissions只能用于Activity