Android 10.0开机启动应用程序

7
我们有一个安卓应用程序,我们希望在手机启动时启动它。 在Android 10中尝试了一些代码后,我们意识到在Android 8.0之后,无法在启动时启动应用程序。 在Android 6之前是可以的。 即使在Android 10的实际设备/手机/模拟器上,我们也在自启动列表中授予权限给我们的应用程序。 <<目标:有没有任何方法(解决方法)可以在最新版本即Android 8以上启动应用程序?>> 我们在Android 10中尝试了以下三个代码部分的尝试 - AndroidManifest.xml、MyActivity.java和MyBroadcastReceiver.java。
1)AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<activity android:name=".MainActivity"  android:launchMode="singleTop" android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<receiver android:name=".MyBroadcastReceiver" android:enabled="true" android:exported="true" android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>

2)MyActivity.java

public class MainActivity extends FlutterActivity {
@java.lang.Override
protected void onCreate(android.os.Bundle savedInstanceState) { 
super.onCreate(savedInstanceState);
// "Display pop up window"
    if (!Settings.canDrawOverlays(getApplicationContext())) {
        startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION));
    }
Log.d(TAG, "-------- onCreate -------"); // this is printed
}
}

3)MyBroadcastReceiver.java

public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Intent i = new Intent(context, MainActivity.class);
i.setAction(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_LAUNCHER);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(i);
Log.d(TAG, "------ tried to launch MainActivity -------"); // this is printed
}
}
}

1
https://dev59.com/TVIH5IYBdhLWcg3wL6dJ#63250729 - Dan Baruch
@Dan:感谢您的建议。我编辑了代码:(a)添加了manifest SYSTEM_ALERT_WINDOW (b)在MyBrodcastReceiver.java :: onReceive()中--我进行了编辑-->> Intent i = new Intent(context, MainActivity.class); i.setAction(Intent.ACTION_MAIN); i.addCategory(Intent.CATEGORY_LAUNCHER); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); context.startActivity(i); Log.d(TAG,“------尝试启动MainActivity-------”); //这将被打印在日志中...但应用程序没有启动.. - shibendra chakraborty
@Dan:我现在已经在MainActivity :: onCreate()中添加了提供覆盖权限的代码,所以现在在我的Redmi6 Pro上,在部署期间会弹出权限屏幕(显示在其他应用程序上),但不幸的是,在我的Redmi6 Pro上,在启动后,此权限不足以在启动后启动。所以我在我的Redmi手机上手动给了一个额外的权限,在“设置>应用程序>权限>在后台运行时显示弹出窗口”下。这样就可以正常工作了。 - shibendra chakraborty
但是在模拟器中,Pixel 2(Android 10.0)上的“在其他应用程序上显示”权限就足以正常工作。非常感谢您识别出了这个问题并提供了解决方案。 - shibendra chakraborty
当然,很高兴你让它工作了 :) - Dan Baruch
显示剩余3条评论
2个回答

3

如果您的应用程序获得了“SYSTEM_ALERT_WINDOW”权限(绘制在其他应用上方),则该应用程序在Android 10及以上版本上自动启动后不会被终止。

因此,您需要显示此设置活动并要求用户启用它:

if (!Settings.canDrawOverlays(this)) {
    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, 0);
}

这在文档的最后一个要点中提到。


3

开机启动应用程序可能会让用户感到烦恼。相反地,您可以启动一个前台服务。根据您的设备,BOOT_COMPLETE意图可能有多种不同的形式。我在这里尝试捕获所有这些形式。

在您的清单文件中:

<receiver android:name=".receiver.BootReceiver" // YOUR RECEIVER HERE
        android:enabled="true"
        android:exported="true"
        android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
        <intent-filter>
            <category android:name="android.intent.category.DEFAULT" />
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.ACTION_BOOT_COMPLETED" />
            <action android:name="android.intent.action.REBOOT" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            <action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
            <action android:name="android.intent.action.ACTION_SHUTDOWN" />
        </intent-filter>
    </receiver>

在接收器中:

class BootReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        // START FOREGROUND SERVICE HERE
    }
}

3
基本上,在onReceive()中启动服务是已经完成并测试过的。在启动完成后,我们会在通知抽屉中收到通知。当用户点击该通知时,我们将通过PendingIndent()启动应用程序。这很好,也很有效。但是我们的目标/要求是——在Android 8+中,我们需要在启动时自动启动应用程序,而不需要手动点击通知来启动。 - shibendra chakraborty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接