boot_completed 不适用于 Android 10 Q API 级别 29

Mar*_*sen 10 java android

我需要帮助。

我有一个在启动后启动 Intent 的应用程序,该应用程序从 Android 6 运行到 Android 9 API 级别 28。 但是此代码在 Android 10 API 级别 29 上不起作用,广播根本不接收任何事件并且不在 MyClassBroadcastReceiver 上运行 onReceive开机后。android 10 系统有什么额外的权限或需要做的配置吗?

示例的干燥部分: 清单:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.softniels.autostartonboot">

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

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <service
        android:name="com.softniels.autostartonboot.ForegroundService"
        android:label="My Service">
        <intent-filter>
            <action android:name="com.softniels.autostartonboot.ForegroundService" />
        </intent-filter>
    </service>

    <receiver
        android:name=".StartMyServiceAtBootReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
        </intent-filter>
    </receiver>

</application>
Run Code Online (Sandbox Code Playgroud)

这里是不能在 Android 10 上运行的部分。

public class StartMyServiceAtBootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
        Log.i("onReceive", "call onReceive ACTION_BOOT_COMPLETED");
        Intent i = new Intent(context, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

}

小智 7

我知道这可能很旧,但我遇到了同样的问题,根据这个:https : //developer.android.com/guide/components/activities/background-starts

我想出的最简单的解决方案是简单地添加

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Run Code Online (Sandbox Code Playgroud)

并设置接收器:

<receiver
android:name=".BootReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
Run Code Online (Sandbox Code Playgroud)

到清单。

接收器代码:

@Override
public void onReceive(Context context, Intent intent) {
    if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
//            Intent n =  context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
 //            n.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | 
 //    Intent.FLAG_ACTIVITY_CLEAR_TASK);
 //            context.startActivity(n);

        Intent myIntent = new Intent(context, MainActivity.class);
        myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(myIntent);
    }
}
Run Code Online (Sandbox Code Playgroud)

这两个选项都有效。我看到的唯一缺点是应用程序加载需要一段时间(从我的测试开始最多可能需要 10 秒)

如果其他人也遇到这种情况,请将其留在这里。这仅适用于 android 10 及更高版本。需要申请“在其他应用上显示”权限

这需要绘制叠加层,可以通过以下方式完成:

if (!Settings.canDrawOverlays(getApplicationContext())) {
            Intent myIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
            Uri uri = Uri.fromParts("package", getPackageName(), null);

            myIntent.setData(uri);
            startActivityForResult(myIntent, REQUEST_OVERLAY_PERMISSIONS);
            return;
        }
Run Code Online (Sandbox Code Playgroud)

  • 这也对我有用,但只有在添加 `if (!Settings.canDrawOverlays(getApplicationContext())) { startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)); 之后才有效。}` 到 `MainActivity.onCreate()`,手动启动应用一次并授予权限。(请参阅 [android.permission.SYSTEM_ALERT_WINDOW](https://developer.android.com/reference/android/Manifest.permission#SYSTEM_ALERT_WINDOW)。) (2认同)

Car*_*s.V 1

我想我找到了一个适合我的“解决方案”。

    public class StartMyServiceAtBootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
                Log.e(TAG, "launching from special > API 28 (" + Build.VERSION.SDK_INT + ")"); // You have to schedule a Service
                JobServiceScheduler jobServiceScheduler = new JobServiceScheduler(context);
                boolean result = jobServiceScheduler.scheduleMainService(20L); // Time you will wait to launch
            } else {
                Log.e(TAG, "launching from normal < API 29"); // You can still launch an Activity 
                try {
                    Intent intentMain = new Intent(context, YourActivity.class);
                    intentMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    if (Build.VERSION.SDK_INT < 28) {
                        context.startService(intentMain);
                    } else {
                        context.startForegroundService(intentMain);
                    }
                } catch (ActivityNotFoundException ex) {
                    Log.e(TAG, "ActivityNotFoundException" + ex.getLocalizedMessage());
                }
            }
    }

    boolean scheduleMainService(Long segundos) {
        ComponentName serviceComponent = new ComponentName(context, YourService.class);
        JobInfo.Builder builder = getCommonBuilder(serviceComponent, YOUR_SERVICE_JOB_ID);
        builder.setMinimumLatency(TimeUnit.SECONDS.toMillis(segundos / 2)); // wait at least
        builder.setOverrideDeadline(TimeUnit.SECONDS.toMillis(segundos)); // maximum delay
        PersistableBundle extras = new PersistableBundle();
        extras.putLong("time", segundos);
        builder.setExtras(extras);

        JobScheduler jobScheduler = getJobScheduler(context);
        if (jobScheduler != null) {
            jobScheduler.schedule(builder.build());
            return true;
        } else {
            return false;
        }
    }
Run Code Online (Sandbox Code Playgroud)