You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级至API 32后Android应用因语音命令无响应遭审核驳回求助

问题

强制将应用API等级改为32后,每次发布新版本/更新都会被审核驳回,驳回原因:

  • 媒体类应用:执行语音命令后无响应(无音乐播放也无错误提示)
  • 消息类应用:确认或编辑自定义消息时无法响应“Reply”指令;无法响应“Reply”“Send It”“Cancel”指令
  • 导航类应用:执行语音命令后无响应

本地测试应用运行完全正常,仅修改了API等级,向审核团队求助未得到帮助,附上相关代码:

AndroidManifest.xml

<?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.inmystream.radiox">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
    <!--<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />-->

    <uses-feature
        android:name="android.hardware.telephony"
        android:required="false" />

    <uses-feature
        android:name="android.hardware.wifi"
        android:required="false" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:usesCleartextTraffic="true">
        <meta-data
            android:name="com.google.android.gms.car.application"
            android:resource="@xml/automotive_app_desc" />

        <activity
            android:name="stereopesaro.mactechinteractiv.stereopesaro.MainActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:launchMode="singleInstance"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <meta-data
            android:name="com.google.android.gms.car.notification.SmallIcon"
            android:resource="@mipmap/ic_launcher" />

        <service
            android:name="stereopesaro.mactechinteractiv.stereopesaro.AutoMediaBrowserService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.media.browse.MediaBrowserService" />
                <action android:name="android.intent.action.MEDIA_BUTTON" />
            </intent-filter>
        </service>
        <!--<receiver-->
        <!--android:name="stereopesaro.mactechinteractiv.stereopesaro.Utils.NetworkChangeReceiver"-->
        <!--android:label="NetworkChangeReceiver">-->
        <!--<intent-filter>-->
        <!--<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />-->
        <!--</intent-filter>-->
        <!--</receiver>-->



        <!-- END PushWoosh activities and services -->
        <service android:name="stereopesaro.mactechinteractiv.stereopesaro.radio.RadioService" />
        <!-- A receiver that will receive media buttons and send as
          intents to your MediaBrowserServiceCompat implementation.
          Required on pre-Lollipop. -->

        <receiver android:name="androidx.media.session.MediaButtonReceiver"
            android:exported="true"
            >


            <intent-filter>
                <action android:name="android.intent.action.MEDIA_BUTTON" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 31
    buildToolsVersion '30.0.3'

    defaultConfig {
        applicationId "com.inmystream.studio54radio"
        minSdkVersion 21
        targetSdkVersion 31
        versionCode 9
        versionName '1.2'
        multiDexEnabled true

        /*lintOptions {
            checkReleaseBuilds false
            // Or, if you prefer, you can continue to check for errors in release builds,
            // but continue the build even when errors are found:
            abortOnError false
        }*/

    }
    compileOptions {
        targetCompatibility JavaVersion.VERSION_1_8
                sourceCompatibility JavaVersion.VERSION_1_8

    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {

        }
    }

    productFlavors {
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'jp.wasabeef:blurry:4.0.0'
    implementation 'com.android.support:multidex:1.0.3'
    implementation 'org.greenrobot:eventbus:3.2.0'
    implementation 'androidx.work:work-runtime-ktx:2.7.0'
    implementation 'androidx.appcompat:appcompat:1.5.0'
    implementation "androidx.media:media:1.6.0"
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'com.squareup.picasso:picasso:2.5.2'
    implementation 'com.squareup.okhttp3:okhttp:4.5.0'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'androidx.recyclerview:recyclerview:1.2.1'
    implementation 'com.karumi:dexter:6.1.2'
    implementation 'pub.devrel:easypermissions:0.4.3'
    implementation 'com.google.android.exoplayer:exoplayer:2.14.0'
}

注:修改API等级前应用运行正常且已通过审核。


解决方案

1. 同步CompileSdkVersion与TargetSdkVersion到32

当前build.gradle中compileSdkVersion为31,targetSdkVersion也未更新到32,这会触发兼容性校验问题。修改如下:

android {
    compileSdkVersion 32
    buildToolsVersion '32.0.0'

    defaultConfig {
        // ...其他配置
        targetSdkVersion 32
    }
}

2. 补充前台服务类型权限

API 31+要求FOREGROUND_SERVICE权限必须指定具体类型,你的应用属于媒体类,需添加对应权限:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />

同时启动前台服务时需指定类型:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    Intent serviceIntent = new Intent(context, RadioService.class);
    serviceIntent.setForegroundServiceType(Service.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK);
    startForegroundService(serviceIntent);
}

3. 适配媒体会话的语音指令处理

确保AutoMediaBrowserService正确实现MediaBrowserServiceCompat回调,且MediaSessionCompat处理语音相关Action:

  • 实现onPlayFromSearch()方法,处理语音搜索播放命令,执行后更新会话状态(如设置为PLAYING)
  • 对于消息类的Reply指令,确认处理组件(Activity/Service)已显式设置android:exported="true",并能接收对应Intent

4. 检查组件导出状态

API 31+要求带Intent-Filter的组件必须显式设置android:exported,目前你的核心组件已设置,但需确认处理语音命令的所有相关组件(如消息处理Service)都正确配置该属性,避免系统无法触发。

5. 模拟审核场景测试

使用API 32的实体设备或模拟器,通过系统语音助手触发命令(而非仅在应用内测试),模拟审核时的后台唤醒场景,排查本地测试未覆盖的问题。

6. 调整广播接收逻辑

API 31+限制隐式广播接收,若应用依赖广播触发逻辑,改用WorkManager或注册显式广播,确保语音命令相关的广播能被正确接收。


内容的提问来源于stack exchange,提问作者Andrea Giordano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 15:35:21