android - 谁能提供一个将生成 ForegroundServiceStartNotAllowedException 的示例?

标签 android

Android 12 增加了对从某些后台任务启动的 ForegroundService 的限制。我有一个使用多个 ForegroundServices 的应用程序,其中一些不在异常(exception)情况下。但是,针对 API 31 的构建在 Android 12 Beta 4 设备上运行时没有遇到任何问题或 ForegroundServiceStartNotAllowedException。
任何人都可以提供一个示例来在构建目标 API 31 后遇到问题吗?

最佳答案

在毕业典礼上:

compileSdkVersion 31
buildToolsVersion "31.0.0"
targetSdkVersion 31
在 list 中:
 <service android:name=".MyForegroundService"
          android:exported="false"/>
       
<service android:name=".MyService"
         android:exported="false"/>

<receiver android:name=".MyBroadcastReceiver"
          android:exported="true">
              <intent-filter>
                  <action android:name="com.sdk12.foreground.ACTION"/>
              </intent-filter>
</receiver>
接收者:
class MyBroadcastReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        Log.d("tag", "onReceive()");
        val myServiceIntent = Intent(context, MyForegroundService::class.java)
            Handler(Looper.getMainLooper()).postDelayed({ 
                try {
                    ContextCompat.startForegroundService(context,myServiceIntent)
                } catch (ex : ForegroundServiceStartNotAllowedException){
                    Log.d("tag","ForegroundServiceStartNotAllowedException")
                }
            }, 5000)
        }
}
前台服务:
class MyForegroundService : Service() {
    private lateinit var br: BroadcastReceiver

    override fun onBind(intent: Intent): IBinder? {
        return null
    }

    override fun onCreate() {
        super.onCreate()
        br = MyBroadcastReceiver()
        val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION).apply {
            addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED)
        }
        registerReceiver(br, filter)

    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        val channelId = createNotificationChannel("channel1","My Background Service")

        val pendingIntent: PendingIntent =
            Intent(this, MainActivity::class.java).let { notificationIntent ->
                PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_MUTABLE)
            }

        val notificationBuilder = Notification.Builder(this, channelId )
        val notification = notificationBuilder.setOngoing(true)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle("title")
            .setContentText("contentText")
            .setCategory(Notification.CATEGORY_SERVICE)
            .setContentIntent(pendingIntent)
            .setForegroundServiceBehavior(Notification.FOREGROUND_SERVICE_IMMEDIATE)
            .build()

        startForeground(1, notification)

        return START_STICKY

    }

    override fun onDestroy() {
        unregisterReceiver(br)
        super.onDestroy()
    }

    private fun createNotificationChannel(channelId: String, channelName: String): String {
        val chan = NotificationChannel(
            "channel1",
            channelName, NotificationManager.IMPORTANCE_NONE
        )
        chan.lightColor = Color.BLUE
        chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
        chan.importance = NotificationManager.IMPORTANCE_HIGH
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(chan)
        return channelId
    }
}
我的服务:
class MyService : Service() {
    private lateinit var br: BroadcastReceiver

    override fun onBind(intent: Intent): IBinder? {
        return null
    }

    override fun onCreate() {
        super.onCreate()
        br = MyBroadcastReceiver()
        val filter = IntentFilter("com.sdk12.foreground.ACTION")
        registerReceiver(br, filter)

    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        return START_STICKY
    }

    override fun onDestroy() {
        unregisterReceiver(br)
        super.onDestroy()
    }
}
触发服务:
startService(Intent(this, MyService::class.java))
将您的应用程序发送到后台并从 adb 调用:
adb shell am broadcast -a com.sdk12.foreground.ACTION -f 0x01000000
这将确保您在后台
可能有更简单的方法,但我觉得这最容易理解

关于android - 谁能提供一个将生成 ForegroundServiceStartNotAllowedException 的示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68777762/

相关文章:

android - 使用 Android Studio 进行应用内购买时无法找到 IInAppBillingService

android - CoordinatorLayout + TabView + AnimateView(自上而下)

Android 从另一个类访问主要 Activity 变量

android - 如何关闭 Activity ,以便无法从 Activity 应用程序再次打开?

java - 在 Android 中读取和显示大格式文本文档

android - 我在使用 webintent 时总是出错

android - 为什么我的图像按钮水平和垂直翻转?

java - Class.this 是什么意思?

java.lang.RuntimeException : Unable to instantiate application : ClassNotFoundException (Only on X86 architecture device)

Android:广播接收器中的电话状态