Boot _completed无法在Android 10 Q API级别29上运行

bvn4nwqk  于 2022-11-27  发布在  Android
关注(0)|答案(4)|浏览(262)

我有一个应用程序, Boot 后启动一个Intent,从Android 6到Android 9 API级别28。

但此代码无法在Android 10 API级别29上运行,Broadcast不会接收任何事件,也不会在 Boot 后在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>

这里的部分不运行在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);
        }
    }
}
ozxc1zmp

ozxc1zmp1#

我知道这可能是旧的,但我已经面临同样的问题,并根据这:https://developer.android.com/guide/components/activities/background-starts
我想到的最简单的解决方案就是

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

设置接收器:

<receiver
android:name=".BootReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

到货单上。
接收方代码:

@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);
    }
}

这两个选项都有效。我看到的唯一缺点是应用程序加载需要相当长的时间(从我的测试中可以长达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;
        }
mhd8tkvw

mhd8tkvw2#

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

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;
        }
    }
gwo2fgha

gwo2fgha3#

context.startActivity()没有启动,我用以下方法解决了这个问题:

private void restartApp( Context mContext) {
    try {
        long restartTime = 1000*5;
        Intent intents = mContext.getPackageManager().getLaunchIntentForPackage(mContext.getPackageName());
        PendingIntent restartIntent = PendingIntent.getActivity(mContext, 0, intents, PendingIntent.FLAG_ONE_SHOT);
        AlarmManager mgr = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + restartTime, restartIntent);

        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            mgr.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + restartTime, restartIntent);
        }
    } catch (Exception e) {
        Log.e(TAG, e.getMessage());
    }
}
1szpjjfi

1szpjjfi4#

我用清单中的这个权限解决了它:

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

而在主要活动中:

if (!Settings.canDrawOverlays(getApplicationContext())) {
        startActivity(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION));
    }

设置的正确导入为:android.provider
应用程序第一次启动时,将提示权限控制哪些应用程序可以在其他应用程序之上绘制,下一个设备将启动应用程序,并使用典型的广播接收器启动。
这是医生

相关问题