静默卸载(强制卸载、没有界面的卸载)6.0以下和6.0以上的实现

版权声明:本文择自http://blog.csdn.net/maodunti,未经博主允许不得转载。

 

应用的卸载我们都再熟悉不过了,但是要不提醒用户就卸载了你知道么?当然这个不容易做到,下面讲到的方法都是采用系统签名的方法才能实现,或者大家可以用root后的设备可以实现。

系统签名就是通过签名获取到系统权限去做系统才能做的事情,root以后你就获取到系统权限,这里不多谈这些权限的问题。

 

如果使用过adb shell命令的同学知道,我们可以通过输入命令静默(强制)安装、卸载应用,即不提供“是否安装”、“是否卸载”这样的提示,我们这里主要讲静默(强制)卸载。

如下

 

*****\android-sdk-windows\platform-tools>adb shell
shell@HWNXT:/ $ /system/bin/pm uninstall com.ishugui
/system/bin/pm uninstall com.ishugui
Success
shell@HWNXT:/ $
*****\android-sdk-windows\platform-tools>

 

我们通过adb shell 卸载的手机上的com.hugui这个包,而且没有界面提示,返回值是success,表示成功卸载了,这就是静默(强制)卸载。

 

那我们怎么通过代码实现?

 

上代码!!

 

 

    public static String execRuntime(Runtime rt, String command) {
        String str = "";
        Process process = null;
        BufferedReader reader = null;

        try {
            process = rt.exec(command);

            reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

            int read;
            char[] buffer = new char[1024];
            StringBuffer output = new StringBuffer();
            while ((read = reader.read(buffer)) > 0) {
                output.append(buffer, 0, read);
            }

            process.waitFor();

            str = output.toString();

        } catch (InterruptedException ie) {
            Log.e(LOG_TAG, "exec InterruptedException:", ie);
        } catch (IOException ioe) {
            Log.e(LOG_TAG, "exec IOException:", ioe);
        } catch (Exception e) {
            Log.e(LOG_TAG, "exec Exception:", e);
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException ioe) {
                Log.e(LOG_TAG, "Close IOException", ioe);
            }

            destroyProcess(process);
        }
        return str;
    }

 

 

注意了,这个Runtime是通过签名应用获取的,所以有系统权限执行这个命令。

这个方式在6.0以下的系统签名应用都能实现,就在昨晚,在华为mate8  Android6.0上没有办法实现,到现在我也弄不明白问题所在,可能是6.0 的命令格式改变了,在通过adb shell可以实现,费解费解!迫不得已想找其他解决方案。

同事提供了一个新的方案:

 

 

PackageManager下的deletePackage();

看源码解释,

 

Attempts to delete a package. Since this may take a little while, the result will be posted back to the given observer. A deletion will fail if the calling context lacks the android.Manifest.permission permission, if the named package cannot be found, or if the named package is a "system package". (TODO: include pointer to documentation on "system packages")
Parameters:
packageName The name of the package to delete
observer An observer callback to get notified when the package deletion is complete. IPackageDeleteObserver.packageDeleted(java.lang.String,int) will be called when that happens. observer may be null to indicate that no callback is desired.
flags - possible values: DELETE_KEEP_DATA, DELETE_ALL_USERS.
Hide:
3428
3429    // @SystemApi
3430    public abstract void More ...deletePackage(
3431            String packageName, IPackageDeleteObserver observer, int flags);

 

 

 

 

 

 


试图删除应用包!!!而且是异步处理的,需要传入一个监视者observer。而且我们也看到了@SystemApi,说明这个方法应该就是静默卸载的方式之一了,二话不说尝试一下。

 

 

 private void delPkg(Context context, String pkgName) {
        try {
            PackageManager pm = context.getPackageManager();
            Method[] methods = pm != null ? pm.getClass().getDeclaredMethods() : null;
            Method mDel = null;
            if (methods != null && methods.length > 0) {
                for (Method method : methods) {
                    if (method.getName().toString().equals("deletePackage")) {
                        mDel = method;
                        break;
                    }
                }
            }

            if (mDel != null) {
                mDel.setAccessible(true);
                mDel.invoke(pm, pkgName, new PackageDeleteObserver(), 0);
            }

        } catch (Exception e) {
        
        }
    }

    private class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
        @Override
        public void packageDeleted(String packageName, int returnCode) throws RemoteException {
            Log.i(LOG_TAG, "del apk >>" + packageName + ";code >>" + returnCode);
        }
    }

 

 

因为传入了一个监视者,所以这个new 一个监视者对象传入试试,IPackageDeleteObserver 可以通过aidl 获取到。然后就是打包尝试了!

 

结果是感人的,完美实现!!!

那么问题来了,是不是6.0以上我不能使用adb shell命令来实现?还是华为rom的不一样,限制该命令的执行?如果大家有测试,请分享下测试结果。
 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值