5

我想要这样的事情,当我的应用程序将安装在 Android 手机中时。没有人可以从手机上卸载它,或者当任何人试图卸载它时,弹出显示或任何警报。有什么办法吗?

4

4 回答 4

7

您将需要启用 deviceAdmin 以禁用Force StopUninstall功能。这由Device Admin API处理企业/应用程序策略管理的处理。

于 2012-10-08T09:58:13.627 回答
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

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

于 2016-12-07T15:16:53.433 回答
1

从理论上讲,您可以“root”手机,将您的应用程序添加到系统分区(用户不能修改系统分区),然后再次“取消root”手机。不过,我不确定这是否适用于所有型号。某些设备不能“无根”。

于 2012-04-20T07:09:50.427 回答
0

我目前认为您可以完成此操作的唯一方法是使用两个应用程序。

  1. 是主人..它作为服务运行,检查是否安装了应用
    程序,如果缺少则安装它。
  2. 是您希望用户看到的应用

好的..我可以想到其他方法..正如 Blessenm 所说,改变操作系统..但这假设您针对的是特定的硬件。

您可能能够 Root 系统,这可以让您访问管理想法..不确定它是否会工作。

于 2012-04-20T06:58:51.300 回答