boot_completed not working on Android 10 Q API level 29

前端 未结 3 1984
别那么骄傲
别那么骄傲 2020-12-18 08:22

I need help.

I have an application that starts an Intent after the boot that works from Android 6 to Android 9 API level 28. But this code does not work on

相关标签:
3条回答
  • 2020-12-18 08:58

    Guess I found a 'solution' for me.

        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;
            }
        }
    
    0 讨论(0)
  • 2020-12-18 09:13

    I know that this may be old but I have faced the same problem and according to this: https://developer.android.com/guide/components/activities/background-starts

    The easiest solution I came up with was simply adding

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

    And setting up the receiver:

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

    To the manifest.

    Receiver code:

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

    Both options work. The only downside I see is that it takes rather a while for app to load (can be up to 10 seconds from my testings)

    Leaving this here for other people if they encounter this as well. This only applies to android 10 and up.

    As stated by @legolas108, this requires drawing overlay, which can be done with:

    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;
            }
    
    0 讨论(0)
  • 2020-12-18 09:25

    context.startActivity() is not launching, I solved it the following way:

      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());
        }
    }
    
    0 讨论(0)
提交回复
热议问题