在安卓系统中禁用应用程序卸载?

5

我希望有这样一种功能,当我的应用程序安装在安卓手机上时,任何人都不能从手机上卸载它,或者当有人尝试卸载它时,会弹出一个提示框或警报。

有没有办法实现这个功能?


2
你不想让人们从他们的手机上卸载你的应用程序吗?有点可怕啊... - Tyler Treat
有没有办法使设备管理员,即如果用户在Android上安装应用程序,则其他用户无法从该设备中删除该应用程序? - Ammad Ali
2
等一下,伙计们。有时候使用手机的人并不是所有者。如果我拥有一家公司并希望我的员工使用我为他们构建的应用程序,那么如果他们卸载它,我会感到非常恼火。考虑停车罚单工作人员、销售人员、交付人员。我拥有硬件设备,并且我说你必须使用它。 - baash05
@daveatflow.. 我想做这种东西。你能帮我吗? - Ammad Ali
1
@Niko 很棒的引言...“不可能”是人类经常使用的词。仅仅因为我们不知道如何做到,不意味着它不能实现。 - baash05
显示剩余3条评论
4个回答

7

您需要启用设备管理器才能禁用强制停止卸载功能。这由设备管理器API处理,该API处理企业/应用程序策略管理。


1
请问可否分享一下使用设备管理API的示例代码? - Ammad Ali

3
禁用是不可能的。但你可以使用一个变通方法。 在你的应用程序中创建一个持续在后台运行的服务:
//MasterService.java
public class MasterService extends Service{

    private ThreadPoolExecutor executor;
    private Runnable runnable = new Runnable(){
        @Override
        public void run(){}
    };

    public MasterService(){
        executor = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, 
                       new LinkedBlockingQueue<Runnable>());
    }

     @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        executor.execute(runnable);
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        executor.shutdown();
    }

};

不要忘记使用 startService(new Intent(this, MasterService.class)); 来启动它,并在清单文件中将其声明为已导出和已启用。
在 Android 上(未 root 的手机上),需要运行包管理器才能卸载应用程序。在您的 Runnable 中,需要检测包管理器是否正在前台运行。如果是,则启动一个具有输入焦点的视图来接受输入。
//MasterService.java (inside runnable)
@Override
public void run(){
    while(true) {
        ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> procInfos = activityManager.getRunningAppProcesses();

        for (int i = 0; i < procInfos.size(); i++) {
            //check if package installer runs in foreground
            if (procInfos.get(i).processName.equals("com.android.packageinstaller") && procInfos.get(i).importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {

                //start activity
                startActivity(new Intent(MasterService.this, OverlayActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY));
            }
        }
    }
}

在您的活动中,创建任何视图并覆盖后退按钮以防止用户返回到软件包卸载程序屏幕。
//OverlayActivity.java
public class OverlayActivity extends Activity{

    private ImageView view;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        view = new ImageView(this);
        setContentView(view);
    }


    @Override
    public void onBackPressed() {

    }
};

主页按钮并不重要,因为它会隐藏所有活动,如果用户按任务按钮选择包管理器,则会再次打开OverlayActivity。 确保主服务不能被停止或强制关闭。有两种方法可以解决这个问题:

  1. 在您的onDestroy函数中发送自定义广播消息,以再次启动您的服务。
  2. 通过检查com.android.settings来禁用设置应用程序。

我希望您知道自己在做什么,因为用户应该知道何时卸载应用程序。


1
你可以理论上“root”手机,将你的应用程序添加到系统分区(用户无法修改系统分区),然后再次“取消root”手机。不过我不确定这对所有型号都适用。有些设备无法“取消root”。

你能解释一下如何给手机root吗?所有的安卓制造商都允许这样做吗?如果不是,那么哪些制造商提供此功能? - Ammad Ali
1
获取手机的Root权限可能对于每个设备制造商来说都是一个非常特定的过程。我认为没有一个教程可以涵盖所有不同的品牌。恐怕你必须自己在谷歌上搜索具体的指令。我知道Sony Ericsson(现在是Sony Mobile)在获取Root权限方面非常自由(他们在自己的开发者论坛中有一个非常有帮助的社区)。 - dbm

0

我目前唯一认为你可以实现这个的方法是使用两个应用程序。

  1. 作为主程序,它运行为服务,检查应用是否已安装并在缺失时进行安装。
  2. 是您希望用户看到的应用程序。

好吧...我可以想到其他方法...就像Blessenm所说的那样,修改操作系统...但这假设您正在针对特定的硬件。

您可能能够Root系统,这可能会给您访问管理员权限的机会...不确定它是否有效。


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