我昨晚更新到了Android 14。当我尝试在我的设备上安装我们的应用程序(来自 Play 商店)时,我在打开应用程序时开始崩溃
FATAL EXCEPTION: main
Process: com.myapp.appname, PID: 1518
java.lang.RuntimeException: Unable to create service com.myapp.StartupService:
java.lang.SecurityException: Starting FGS with type location callerApp=ProcessRecord{95e97ef
1518:com.myapp.appname/u0a370} targetSDK=34 requires permissions: all of the permissions allOf=true
[android.permission.FOREGROUND_SERVICE_LOCATION] any of the permissions allOf=false
[android.permission.ACCESS_COARSE_LOCATION, android.permission.ACCESS_FINE_LOCATION] and the app
must be in the eligible state/exemptions to access the foreground only permission at
android.app.ActivityThread.handleCreateService(ActivityThread.java:4664)
我尝试将一些新需要的权限添加到我的清单中。当一切都在测试版上进行测试时,它工作得很好(据我所知)。
我还尝试了这个问题中显示的解决方案:Foreground Service crashing on Android 14,这看起来非常相似。
这是我的文件。我试图包含我认为必要的内容。让我知道是否有有助于提供更多背景信息的文章。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.myapp"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
...
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
...
<application
android:name=".BaseApplication"
android:allowBackup="false"
android:fullBackupContent="false"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:resizeableActivity="false"
android:theme="@style/appTheme"
android:requestLegacyExternalStorage="true">
<activity
...
<!-- Service used when app is initializing on start up -->
<service android:name="com.myapp.StartupService"
android:foregroundServiceType="location"
android:exported="false"
>
</service>
...
<service
android:name="com.myapp.chat.push.FcmListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
...
</application>
</manifest>
class StartupService : IntentService {
constructor() : super("StartupService") {}
constructor(name: String?) : super(name) {}
private val STARTUP_NOTIFICATION_ID = 42
private fun createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
val name: CharSequence = getString(R.string.notification_channel_name_misc)
val description = getString(R.string.notification_channel_description_misc)
val importance = NotificationManager.IMPORTANCE_LOW
val channel = NotificationChannel(
AppConstants.NOTIFICATION_CHANNEL_MISCELLANEOUS,
name,
importance
)
channel.description = description
channel.setSound(null, null)
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
val notificationManager = getSystemService(
NotificationManager::class.java
)
notificationManager.createNotificationChannel(channel)
}
@Deprecated("Deprecated in Java")
override fun onCreate() {
super.onCreate()
createNotificationChannel()
val builder = NotificationCompat.Builder(
applicationContext,
AppConstants.NOTIFICATION_CHANNEL_MISCELLANEOUS
)
.setContentTitle(getString(R.string.notification_startup_title))
.setContentText(getString(R.string.notification_startup_text))
.setSmallIcon(R.drawable.ic_notification_small)
.setPriority(NotificationCompat.PRIORITY_LOW)
startForeground(STARTUP_NOTIFICATION_ID, builder.build()) // THIS LINE IS THROWING THE ERROR
}
...
请求前台服务权限
面向 Android 9(API 级别 28)或更高版本并使用前台服务的应用需要请求应用清单中的
FOREGROUND_SERVICE
,如以下代码片段所示。这是正常权限,因此系统会自动将其授予请求的应用程序。
此外,如果应用程序的目标 API 级别为 34 或更高,则它必须针对前台服务将要执行的工作类型请求适当的权限类型。每个前台服务类型都有对应的权限类型。例如,如果应用程序启动使用摄像头的前台服务,您必须同时请求
FOREGROUND_SERVICE
和 FOREGROUND_SERVICE_CAMERA
权限。这些都是正常权限,因此如果清单中列出了它们,系统会自动授予它们。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA"/>
<application ...>
...
</application>
</manifest>
注意: 如果目标 API 级别 28 或更高级别的应用程序尝试在未请求
FOREGROUND_SERVICE
权限的情况下创建前台服务,系统会抛出 SecurityException。同样,如果应用程序的目标 API 级别为 34 或更高级别并且未请求适当的特定权限,则系统会抛出 SecurityException。