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

时间:2020-03-16 01:08:47

标签: java android

我需要帮助。

我有一个应用程序,该应用程序在从Android 6到Android 9 API级别28的启动过程中启动了Intent。 但是此代码在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>

这是无法在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);
    }
}

}

3 个答案:

答案 0 :(得分:3)

我知道这可能已经很老了,但是我也面临着同样的问题,并据此: 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及更高版本。

如@ legolas108所述,这需要图形叠加,可以使用以下方法完成:

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

答案 1 :(得分:1)

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

Dataframe A
name score  month
Alex   20   2020/01
Alex   30   2020/03

Dataframe B
name   month   tenure
Alex  2020/01     1
Alex  2020/02     2
Alex  2020/03     3

Join A+B using name and month - expected result
name   month  score  tenure
Alex  2020/01   20     1
Alex  2020/02   20     2 --> repeat the score from the most recent date
Alex  2020/03   30     3

答案 2 :(得分:0)

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