当我将目标SDK更新到30+ (Android R或更高版本)时,我的PendingIntent上出现了一个lint警告Missing PendingIntent可变性标志。当我想定义PendingIntent时,FLAG_UPDATE_CURRENT标志。

我应该如何处理这个绒线没有对应用程序功能的影响?


当前回答

我创建了PendingIntentCompat。将PendingIntent逻辑抽象到一个单独的类中。

object PendingIntentCompat {

    @JvmStatic
    @JvmOverloads
    fun getActivity(
        context: Context,
        requestCode: Int,
        intent: Intent,
        flags: Int,
        isMutable: Boolean = false
    ): PendingIntent {
        return PendingIntent.getActivity(
            context,
            requestCode,
            intent,
            addMutabilityFlags(isMutable, flags)
        )
    }

    @JvmStatic
    @JvmOverloads
    fun getService(
        context: Context,
        requestCode: Int,
        intent: Intent,
        flags: Int,
        isMutable: Boolean = false
    ): PendingIntent {
        return PendingIntent.getService(
            context,
            requestCode,
            intent,
            addMutabilityFlags(isMutable, flags)
        )
    }

    @JvmStatic
    @JvmOverloads
    @RequiresApi(Build.VERSION_CODES.O)
    fun getForegroundService(
        context: Context,
        requestCode: Int,
        intent: Intent,
        flags: Int,
        isMutable: Boolean = false
    ): PendingIntent {
        return PendingIntent.getForegroundService(
            context,
            requestCode,
            intent,
            addMutabilityFlags(isMutable, flags)
        )
    }

    /**
     * https://developer.android.com/about/versions/12/behavior-changes-12#pending-intent-mutability
     */
    private fun addMutabilityFlags(isMutable: Boolean, flags: Int): Int {
        var updatedFlags = flags

        if (isMutable) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                updatedFlags = flags or PendingIntent.FLAG_MUTABLE
            }
        } else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                updatedFlags = flags or PendingIntent.FLAG_IMMUTABLE
            }
        }
        return updatedFlags
    }
}

其他回答

如果你使用Java和ADMOB,你会在SDK S或Android 12上遇到PendingIntent错误。这里有一个修复,使ADMOB使用正确的工作-运行时。

implementation 'com.google.android.gms:play-services-ads:19.5.0'
    constraints {
        implementation('androidx.work:work-runtime:2.7.0-alpha05') {
            because 'previous versions have a bug impacting this application'
        }
    }

这是Work库的问题。 即使是最新版本也受到2.7.0-alpha04的影响

https://issuetracker.google.com/issues/194108978

作为临时解决方案-在gradle中注释掉包含“work”依赖项,并在整个项目中删除使用该类。至少这样你可以正常运行应用程序,并在其他功能和领域工作....

在我的例子中,它也是由使用旧WorkManager版本的第三方库强制所有依赖的新Android Work版本在你的根构建中使用这个。gradle文件:

allproject {
  project.configurations.all {
    resolutionStrategy {
      force 'androidx.work:work-runtime:2.7.0'
    }
  }
}

当你升级你的项目和目标android版本12时,这个问题就来了。使用该解决方案,您可以更新所有待处理实习生

目标S+(版本31及以上)需要在创建PendingIntent时指定FLAG_IMMUTABLE或FLAG_MUTABLE之一

以下代码

 PendingIntent pendingIntent = null;
        if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.S){
             pendingIntent = stackBuilder.getPendingIntent(1, PendingIntent.FLAG_MUTABLE);

        }else {
             pendingIntent = stackBuilder.getPendingIntent(1, PendingIntent.FLAG_UPDATE_CURRENT);

        }

如果你在项目中使用接收器,也要实现这个依赖工作

//Work Manager dependency
implementation 'androidx.work:work-runtime:2.7.1'

我创建了PendingIntentCompat。将PendingIntent逻辑抽象到一个单独的类中。

object PendingIntentCompat {

    @JvmStatic
    @JvmOverloads
    fun getActivity(
        context: Context,
        requestCode: Int,
        intent: Intent,
        flags: Int,
        isMutable: Boolean = false
    ): PendingIntent {
        return PendingIntent.getActivity(
            context,
            requestCode,
            intent,
            addMutabilityFlags(isMutable, flags)
        )
    }

    @JvmStatic
    @JvmOverloads
    fun getService(
        context: Context,
        requestCode: Int,
        intent: Intent,
        flags: Int,
        isMutable: Boolean = false
    ): PendingIntent {
        return PendingIntent.getService(
            context,
            requestCode,
            intent,
            addMutabilityFlags(isMutable, flags)
        )
    }

    @JvmStatic
    @JvmOverloads
    @RequiresApi(Build.VERSION_CODES.O)
    fun getForegroundService(
        context: Context,
        requestCode: Int,
        intent: Intent,
        flags: Int,
        isMutable: Boolean = false
    ): PendingIntent {
        return PendingIntent.getForegroundService(
            context,
            requestCode,
            intent,
            addMutabilityFlags(isMutable, flags)
        )
    }

    /**
     * https://developer.android.com/about/versions/12/behavior-changes-12#pending-intent-mutability
     */
    private fun addMutabilityFlags(isMutable: Boolean, flags: Int): Int {
        var updatedFlags = flags

        if (isMutable) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                updatedFlags = flags or PendingIntent.FLAG_MUTABLE
            }
        } else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                updatedFlags = flags or PendingIntent.FLAG_IMMUTABLE
            }
        }
        return updatedFlags
    }
}