草庐IT

Android App开机自启动

拉莫帅 2023-07-26 原文

最近项目中,有用到开机自启动的功能,这里做一下总结,供大家学习探讨!

Android 开机启动延迟问题
Android 开机自启动被拦截问题

实战演练

测试手机:红米手机 Redmi 6A 安卓version 9
                  华为手机 DUA-AL00 安卓version 8.1.0
                  华为手机 Honor 9i 安卓version 9.1.0
                  VIVO手机 vivo iQOO 安卓version 11
                  小米平板 MI PAD 4 安卓version 8.1.0

                   经测试以上机型测试成功

对于开机自启的基本思路:

  1. 想要实现app开机自启动,我们用广播的方式来实现这种需求。app首先需要去注册一个关于接收发送开机启动的广播(android.intent.action.BOOT_COMPLETED);而且必须要注意的一点是:这个广播必须的静态注册的,不能是动态注册的广播(这种接收开机广播的,一定要静态注册,这样应用还没运行起来时也照样能够接收到开机广播
    ,动态广播就不行了)。
  2. 静态注册好了广播之后,在onReceive方法里面做处理就可以了
  3. 重点注意项
    (1)在安装完应用后,要先运行一次,然后关机,再启动。
    (2)针对Andorid4.0之后需先启动一次APP才可收到开机完成的广播,主要目的是防止恶意程序
    (3)同设备尽可能只允许一个APP实现开机自启动的功能,否则俩者应该会有冲突

具体实现

//加入权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

这里关于onReceive方法里面的处理,有些机型不起作用,这里总结了两种实现方式:
1.根据包名启动应用
2.指定class类,跳转到相应的Activity

/**
 * @author Martin-harry
 * @date 2022/3/4
 * @address
 * @Desc 定义自启动BroadcastReceiver
 */
public class AutoStartBroadReceiver extends BroadcastReceiver {
    private static final String ACTION = "android.intent.action.BOOT_COMPLETED";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("接收广播", "onReceive: ");
        Log.e("接收广播", "onReceive: " + intent.getAction());
        //开机启动
        if (ACTION.equals(intent.getAction())) {
            Log.e("接收广播", "onReceive: 启动了。。。");

//第一种方式:根据包名
//            PackageManager packageManager = context.getPackageManager();
//            Intent mainIntent = packageManager.getLaunchIntentForPackage("com.harry.martin");
//            mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//            context.startActivity(mainIntent);
//            context.startService(mainIntent);


//第二种方式:指定class类,跳转到相应的Acitivity
            Intent mainIntent = new Intent(context, LoginActivity.class);
            /**
             * Intent.FLAG_ACTIVITY_NEW_TASK
             * Intent.FLAG_ACTIVITY_CLEAR_TOP
             */
            mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(mainIntent);
//            context.startService(mainIntent);
        }
    }

}

注册广播

       <receiver
            android:name=".receiver.AutoStartBroadReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />

                <category android:name="android.intent.category.HOME" />
            </intent-filter>
        </receiver>

        <activity
            android:name=".mvp.view.Activity.LoginActivity"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

场景测试

做完上面的工作后,这里就针对部分手机应用的权限管理操作了

   ComponentName localComponentName = new ComponentName(MyApp.getInstance(), MyInstalledReceiver.class);
   int i = MyApp.getInstance().getPackageManager().getComponentEnabledSetting(localComponentName);
//        Log.e("自启动 >>>>", "onCreate: " + i);
   getAutostartSettingIntent(this);
/**
     * 获取自启动管理页面的Intent
     *
     * @param context context
     * @return 返回自启动管理页面的Intent
     */
    public static Intent getAutostartSettingIntent(Context context) {
        ComponentName componentName = null;
        String brand = Build.MANUFACTURER;
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        switch (brand.toLowerCase()) {
            case "samsung"://三星
                componentName = new ComponentName("com.samsung.android.sm", "com.samsung.android.sm.app.dashboard.SmartManagerDashBoardActivity");
                break;
            case "huawei"://华为
                Log.e("自启动管理 >>>>", "getAutostartSettingIntent: 华为");
                componentName = new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.appcontrol.activity.StartupAppControlActivity");
//            componentName = new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity");//目前看是通用的
                break;
            case "xiaomi"://小米
//                componentName = new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity");
                componentName = new ComponentName("com.android.settings","com.android.settings.BackgroundApplicationsManager");
                break;
            case "vivo"://VIVO
//            componentName = new ComponentName("com.iqoo.secure", "com.iqoo.secure.safaguard.PurviewTabActivity");
                componentName = new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity");
                break;
            case "oppo"://OPPO
//            componentName = new ComponentName("com.oppo.safe", "com.oppo.safe.permission.startup.StartupAppListActivity");
                componentName = new ComponentName("com.coloros.oppoguardelf", "com.coloros.powermanager.fuelgaue.PowerUsageModelActivity");
                break;
            case "yulong":
            case "360"://360
                componentName = new ComponentName("com.yulong.android.coolsafe", "com.yulong.android.coolsafe.ui.activity.autorun.AutoRunListActivity");
                break;
            case "meizu"://魅族
                componentName = new ComponentName("com.meizu.safe", "com.meizu.safe.permission.SmartBGActivity");
                break;
            case "oneplus"://一加
                componentName = new ComponentName("com.oneplus.security", "com.oneplus.security.chainlaunch.view.ChainLaunchAppListActivity");
                break;
            case "letv"://乐视
                intent.setAction("com.letv.android.permissionautoboot");
            default://其他
                intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
                intent.setData(Uri.fromParts("package", context.getPackageName(), null));
                break;
        }
        intent.setComponent(componentName);
        return intent;
    }

关于红米手机授权操作:

找到红米手机里面的手机管家应用,并打开里面的应用管理

打开授权管理,给自己的应用设置自启动权限,并允许应用在后台弹出界面

关于华为手机授权操作:

总结

本人在测试的时候,红米手机开机自启时间需要等待一段时间,如果有大佬知道怎么解决的,可以下方评论一下,谢谢啦

项目下载地址:AutoBroadCastReceiver_HandlerOOM

题外话:

另外一种实现方式的话,最好就是让系统桌面应用启动你,Launcher
PackageName:comp.xxx.launcher
launcher就是java写的一个app,只不过它是系统应用,但是拿这个代码的话,好像得fw的人帮忙,或者你自己搞出来
具体的也是在Launcher这个的MainActivity里面加个intent 跳转你app的包名

有关Android App开机自启动的更多相关文章

  1. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  2. UE4 源码阅读:从引擎启动到Receive Begin Play - 2

    一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame

  3. ruby - 使用 Capistrano 启动 sidekiq - 2

    我想用Capistrano启动sidekiq。下面是代码namespace:sidekiqdotask:startdorun"cd#{current_path}&&bundleexecsidekiq-c10-eproduction-Llog/sidekiq.log&"pcapture("psaux|grepsidekiq|awk'{print$2}'|sed-n1p").strip!endend它执行成功但sidekiq仍然没有在服务器上启动。输出:$capsidekiq:starttriggeringloadcallbacks*2014-06-0315:03:01executing`

  4. ruby-on-rails - fastercsv 的 Rails 3 服务器启动问题 - 2

    我有一个正在升级到Rails3的Rails2.3.5应用程序。我做了所有我需要做的升级以及当我使用启动Rails服务器时要做的事情railsserver它给了我这个PleaseswitchtoRuby1.9'sstandardCSVlibrary.It'sFasterCSVplussupportforRuby1.9'sm17nencodingengine.我正在使用ruby-1.9.2-p0并安装了fastercsv(1.5.3)gem。在puts语句的帮助下,我能够追踪到错误发生的位置。我发现执行在这一行停止了Bundler.require(:default,Rails.env)if

  5. 电脑启动后显示器黑屏怎么办?排查下面4个问题,快速解决 - 2

    电脑启动出现显示器黑屏是一个相当常见的问题。如果您遇到了这个问题,不要惊慌,因为它有很多可能的原因,可以采取一些简单的措施来解决它。在本文中,小编将介绍下面4种常见的电脑启动后显示器黑屏的原因,排查这些原因,快速解决! 演示机型:联想Ideapad700-15ISK-ISE系统版本:Windows10一、显示器问题如果出现电脑启动后显示器黑屏的情况。那么首先您需要检查一下显示器是否正常工作。您可以通过更换另一个显示器或将当前显示器连接到另一台计算机来检查显示器是否存在问题。如果问题仍然存在,那么您可以排除显示器故障的可能性。 二、显卡问题如果您的电脑配备了独立显卡,那么显卡故障也可能是导致电脑

  6. 如何判断oracle是否启动及启动oracle数据库 - 2

    plsql连接Oracle超时,完犊子了肯定是服务器断电了。得马上检查Oracle服务器状态1、检查数据库是否启动su-oracle切换到Oracle用户,输入sqlplus/assysdba显示连接状态。如果末尾显示的状态是Connectedtoanidleinstance.证明未启动2、启动数据库startup启动数据库,末尾出现Databaseopened说明数据库启动成功3、查看数据库监听是否正常先quit;断开Oracle连接,使用lsnrctlstatus查看监听状态,如果出现TNS-开头的Nolistener、Connectionrefused等错误,说明监听未启动4、启动数据库

  7. ruby-on-rails - 为什么 Rails 在启动时预加载它的所有依赖项(gems)? - 2

    当Rails启动时,它会预加载所有依赖项(gems),这会导致启动时间非常缓慢。在我正在处理的一个中型项目中,Rails的启动时间为10-15秒,具体取决于机器。虽然这在生产中不是问题,但在开发中却是一个巨大的痛苦。特别是在工作TDD/BDD时。有加速测试的解决方案(如spork),但它们会引入自己的问题。我的问题是:为什么不在每个代码文件中要求所需的依赖项,而不是在启动时预加载所有内容?手动要求的缺点是什么?额外的代码行? 最佳答案 Rails不是PHP。一些资源是自动加载的,但是您可能需要的所有资源都在启动/初始化时加载,因为最

  8. ruby - 无法启动 sinatra 进程 - eventmachine "no acceptor" - 2

    我有一个作为守护程序运行的Sinatra应用程序,使用Apache端口转发在端口80和端口7655之间进行调解。这在过去一直运行良好。今天,不太好。我不明白为什么。问题:sudoruby​​my_process.rb返回:/var/lib/gems/1.9.1/gems/eventmachine-1.0.0/lib/eventmachine.rb:526:in`start_tcp_server':noacceptor(portisinuseorrequiresrootprivileges)(RuntimeError)尝试过:更新所有系统包,更新所有gem。没有帮助(除了来自eventm

  9. ruby - 无法让测试单元启动在 ruby​​ 1.9.2 中工作 - 2

    我正在使用Ruby1.9.2(ruby-vyields:ruby1.9.2p290(2011-07-09revision32553)[x86_64-linux]),我正在尝试让它工作:require'test/unit'classTestStartup当我运行它时,我得到了Loadedsuitetest_startupStartedintest1.Finishedin0.000395seconds.1tests,0assertions,0failures,0errors,0skips我很难找到有关此功能的文档,除了SO等上的零散帖子。是的,我想使用这个功能而不是设置。TIA

  10. ruby - 使用 Foreman 启动位于不同目录的 Rack App - 2

    我有一个成功运行多个进程的Procfile设置:#/Procfileredis:bundleexecredis-serversidekiq:bundleexecsidekiq-v-C./config.ymlforward:forward4567mock-api我需要再添加一个进程-一个位于我机器上不同目录中的Sinatra应用程序。如果我cd到该目录,我可以从终端启动它:$rackup-p4567我可以使用终端从不同的目录启动它:$sh-c'cd/Path/to/project/&&execrackup-p4567'但是我应该如何使用工头来做到这一点。我尝试添加以下内容,但它无声地失败

随机推荐