使用位置类型启动 TGS ... TargetSDK=34 - Android 14 启动时崩溃

问题描述 投票:0回答:1

我昨晚更新到了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 kotlin android-manifest android-permissions foreground-service
1个回答
0
投票

请求前台服务权限

面向 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。

© www.soinside.com 2019 - 2024. All rights reserved.