如何在Android手机开机时启动我的应用程序?

268

我尝试使用这篇教程中的示例代码,但它似乎已经过时了,而且没有起作用。那么我需要做哪些更改,修改哪些文件,才能使我的应用在Android启动完成后自动启动?

10个回答

339

首先,在你的 AndroidManifest.xml 文件中需要添加权限声明:

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

同时,在你的AndroidManifest.xml文件中,定义你的服务并监听BOOT_COMPLETED事件:

<service android:name=".MyService" android:label="My Service">
    <intent-filter>
        <action android:name="com.myapp.MyService" />
    </intent-filter>
</service>

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

然后您需要定义接收器来接收BOOT_COMPLETED操作并启动您的服务。

public class StartMyServiceAtBootReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            Intent serviceIntent = new Intent(context, MyService.class);
            context.startService(serviceIntent);
        }
    }
}

现在你的服务应该可以在手机启动时运行。


8
活动:http://developer.android.com/guide/topics/fundamentals/activities.html服务:http://developer.android.com/guide/topics/fundamentals/services.html要在手机启动时启动应用程序,您需要像上面显示的那样注册服务,然后在其中使用startActivity()方法启动应用程序。不过,如果用户没有请求,则将屏幕放在用户面前并不是一个好主意。 - Sean Schulte
20
想要补充说明的是,在您的接收器中,最好使用Intent.ACTION_BOOT_COMPLETED代替硬编码字符串。同时,在创建意图时应使用新的Intent(context, MySystemService.class)构造函数。 - brianestey
7
如果使用intent-filter,检查意图类型是否有原因吗? - Pijusn
5
MySystemService是什么? - sports
2
@agmezr 兄弟,我们是安卓人,去SO上加个IOS标签再问问题吧 :) - Muhammed Refaat
显示剩余5条评论

129
以下是如何使Android设备重启后运行活动的方法:
将以下代码插入到您的AndroidManifest.xml文件中,在元素内(而不是在元素内):
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<receiver
    android:enabled="true"
    android:exported="true" 
    android:name="yourpackage.yourActivityRunOnStartup"
    android:permission="android.permission.RECEIVE_BOOT_COMPLETED">

    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.QUICKBOOT_POWERON" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>

</receiver>

接着创建一个新的类 yourActivityRunOnStartup (与清单文件中 <receiver> 元素指定的 android:name 相匹配):

package yourpackage;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class yourActivityRunOnStartup extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
            Intent i = new Intent(context, MainActivity.class);
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(i);
        }
    }

}

注意: 调用i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);很重要,因为该活动是从活动之外的上下文启动的。如果没有这个,该活动将不会启动。
此外,在<receiver>标记中的值android:enabledandroid:exportedandroid:permission似乎不是必需的。应用程序可以在没有这些值的情况下接收事件,请参见此处的示例

2
看起来那段代码应该放在一个 BroadcastReceiveronReceive() 方法中。 - Someone Somewhere
2
这段代码应该放在名为“yourActivityrRunOnStartup”的活动中,该活动扩展了BroadcastReceiver类,并位于onReceive()方法内部。 - thrylos
3
我试图给你点10个赞,但是无法。抱歉和谢谢。 - Abdul Saleem
1
这应该是最佳答案,因为它明确回答了原始问题“如何在启动时启动应用程序?” - Hong
1
这对我有用,但仅当意图过滤器中只有“<action android:name="android.intent.action.BOOT_COMPLETED" />”时才有效。如果我使用其他两个,它就不起作用。 - emhomm4
显示剩余5条评论

71

监听 ACTION_BOOT_COMPLETE 并执行所需操作。这里有一个代码片段

更新:

回答中的原链接已失效,因此根据评论,这里提供了链接的代码,以防链接失效时无法获取代码。

在 AndroidManifest.xml 文件的应用程序部分中:

<receiver android:enabled="true" android:name=".BootUpReceiver"
        android:permission="android.permission.RECEIVE_BOOT_COMPLETED">

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

...

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

...

public class BootUpReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
                Intent i = new Intent(context, MyActivity.class);  //MyActivity can be anything which you want to start on bootup...
                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(i);  
        }

}

来源:https://web.archive.org/web/20150520124552/http://www.androidsnippets.com/autostart-an-application-at-bootup


这段代码位于哪个文件中:public class BootUpReceiver extends BroadcastReceiver - Jeff Janes
它可以工作,谢谢!(在Android 4.0.4 API级别15上工作)。是的...现在已经是2017年了,我仍然需要为Android 4.0.4开发... :( - Luca
3
无法在Android 8.0上运行!但可以在Android 4.0上运行。 - Mehdi Haghgoo
1
我正在使用相同的代码,但在KitKat版本上无法正常工作,我想要在Android TV启动时启动应用程序。 - Ashutosh Tripathi
@AshutoshTripathi 你修好了吗? - ralphgabb
将接收器代码放置在<application></application>标签内。 - Ishmael Mavor Raines

9

此外,如果您不想修改代码,也可以使用AutoStart等应用程序在启动时启动Android应用程序:AutoStart - No root


7

对于Android 10,存在后台限制。

对于Android 10和所有版本的Android,请按照以下步骤在重新启动或打开手机后启动应用程序:

在Android清单中添加以下两个权限:

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

在你的应用程序标签中添加以下内容

<receiver
        android:name=".BootReciever"
        android:enabled="true"
        android:exported="true"
        android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
</receiver>

将此类添加到启动时启动活动

public class BootReciever extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

    if (Objects.equals(intent.getAction(), Intent.ACTION_BOOT_COMPLETED)) {
        Intent i = new Intent(context, SplashActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(i);
    }
 }}

我们需要为Android 10获取绘制叠加权限。

因此,请在您的第一个活动中添加以下内容:

 private fun requestPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (!Settings.canDrawOverlays(this)) {
            val intent = Intent(
                Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + this.packageName)
            )
            startActivityForResult(intent, 232)
        } else {
            //Permission Granted-System will work
        }
    }
}

请求权限会导致应用程序崩溃。 - Hila Grossbard

2

Sean的解决方案最初对我没有起作用(Android 4.2.2)。我不得不在同一个Android项目中添加一个虚拟活动,并手动在设备上运行该活动至少一次。然后,Sean的解决方案开始起作用,并且在随后的重新启动后通知了BroadcastReceiver。


2
对于Flutter用户,您可以在包文件夹中创建一个名为MainActivityReceiver.kt的文件。例如:android/app/src/main/kotlin/com/your_company/packageMainActivityReceiver.kt:
package com.your_company.package

import android.content.BroadcastReceiver
import android.content.Context;
import android.content.Intent;

class MainActivityReceiver: BroadcastReceiver() {
  override fun onReceive(context: Context, intent: Intent) {
    if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
      val i = Intent(context, MainActivity::class.java)
      i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
      context.startActivity(i)
    }
  }
}

请参考第一个答案修改您的AndroidManifest.xml文件。


4
如果你在回答中加上 AndroidManifest.xml 的指示,而不是提到另一个答案,我认为会更好 :-) - JonasVautherin

0
另一种方法是使用android.intent.action.USER_PRESENT而不是android.intent.action.BOOT_COMPLETED,以避免在启动过程中出现减速。但是,只有当用户启用锁屏时,这才是true - 否则此意图永远不会广播。

参考博客 - Android的ACTION_USER_PRESENT意图存在的问题


2
因此,换句话说,它不应该被使用。 - behelit

0

screenshot

我想在这个问题中补充一个观点,这是我遇到了几天的问题。我尝试了所有的答案,但它们对我都不起作用。如果您正在使用Android 5.1版本,请更改以下设置。

如果您正在使用Android 5.1版本,则必须从应用程序设置中取消选择(限制启动)。

设置>应用程序>您的应用程序>取消选择“限制启动”


3
我认为这从未成为标准。我从未听说过“限制启动”。在三星、华硕、索尼等不同品牌的设备上也从未见过。这对我来说毫无意义。它是指只允许应用程序启动吗?这是什么意思? - The incredible Jan

0
这个问题一直阻碍着我的应用,请这样做——弹出窗口,用户勾选框以授予权限。
  // To start app after boot
private void startSystemAlertWindowPermission(){
    try{
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if(! Settings.canDrawOverlays(this)) {
                Log.i(TAG, "[startSystemAlertWindowPermission] requesting system alert window permission.");
                startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:"+getPackageName())));
            }
        }
    }catch (Exception e){
        Log.e(TAG, "[startSystemAlertWindowPermission] error:", e);
    }
}

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