Android随笔之——静默安装、卸载

  随笔之所以叫随笔,就是太随意了,说起来,之前的闹钟系列随笔还没写完,争取在十月结束之前找时间把它给写了吧。今天要讲的Android APK的静默安装、卸载。网上关于静默卸载的教程有很多,更有说要调用隐藏API,在源码下用MM命令编译生成APK的,反正我能力有限,没一一研究过,这里选择一种我试验成功的来讲。

  静默安装、卸载的好处就是你可以偷偷摸摸,干点坏事什么的,哈哈~

 

一、准备工作

  要实现静默安装、卸载,首先你要有root权限,能把你的静默安装、卸载程序移动到system/app目录下。

  1、用RE浏览器将你的应用(一般在/data/app目录下)移动到/system/app目录下,如果你的程序有.so文件,那么请将相应的.so文件从/data/data/程序包名/lib目录下移动到/system/lib目录下

  2、重启你的手机,你就会发现你的应用已经是系统级应用了,不能被卸载,也就是说你的应用现在已经八门全开,活力无限了。

 

二、静默安装需要的权限

   <!-- 静默安装所需权限,如与Manifest报错,请运行Project->clean -->
    <!-- 允许程序安装应用 -->
    <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
    <!-- 允许程序删除应用 -->
    <uses-permission android:name="android.permission.DELETE_PACKAGES" />
    <!-- 允许应用清除应用缓存 -->
    <uses-permission android:name="android.permission.CLEAR_APP_CACHE" />
    <!-- 允许应用清除应用的用户数据 -->
    <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />

 

三、示例Demo创建

  首先,先把AndroidManifest.xml给完善好

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.lsj.slient"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    
    <!-- 静默安装所需权限,如与Manifest报错,请运行Project->clean -->
    <!-- 允许程序安装应用 -->
    <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
    <!-- 允许程序删除应用 -->
    <uses-permission android:name="android.permission.DELETE_PACKAGES" />
    <!-- 允许应用清除应用缓存 -->
    <uses-permission android:name="android.permission.CLEAR_APP_CACHE" />
    <!-- 允许应用清除应用的用户数据 -->
    <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.lsj.slient.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

  接着,把布局文件activity_main.xml写好

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button 
        android:id="@+id/install"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="静默安装"/>
    
    <Button 
        android:id="@+id/uninstall"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="静默卸载"/>

</LinearLayout>

  接下来,把实现静默安装的ApkManager工具类写完整

  1 package com.lsj.slient;
  2 
  3 import java.io.ByteArrayOutputStream;
  4 import java.io.InputStream;
  5 
  6 import android.util.Log;
  7 
  8 /**
  9  * 应用管理类
 10  * 
 11  * @author Lion
 12  * 
 13  */
 14 public class ApkManager {
 15 
 16     private static final String TAG = "ApkManager";
 17     private static final String INSTALL_CMD = "install";
 18     private static final String UNINSTALL_CMD = "uninstall";
 19 
 20     /**
 21      * APK静默安装
 22      * 
 23      * @param apkPath
 24      *            APK安装包路径
 25      * @return true 静默安装成功 false 静默安装失败
 26      */
 27     public static boolean install(String apkPath) {
 28         String[] args = { "pm", INSTALL_CMD, "-r", apkPath };
 29         String result = apkProcess(args);
 30         Log.e(TAG, "install log:"+result);
 31         if (result != null
 32                 && (result.endsWith("Success") || result.endsWith("Success\n"))) {
 33             return true;
 34         }
 35         return false;
 36     }
 37 
 38     /**
 39      * APK静默安装
 40      * 
 41      * @param packageName
 42      *            需要卸载应用的包名
 43      * @return true 静默卸载成功 false 静默卸载失败
 44      */
 45     public static boolean uninstall(String packageName) {
 46         String[] args = { "pm", UNINSTALL_CMD, packageName };
 47         String result = apkProcess(args);
 48         Log.e(TAG, "uninstall log:"+result);
 49         if (result != null
 50                 && (result.endsWith("Success") || result.endsWith("Success\n"))) {
 51             return true;
 52         }
 53         return false;
 54     }
 55 
 56     /**
 57      * 应用安装、卸载处理
 58      * 
 59      * @param args
 60      *            安装、卸载参数
 61      * @return Apk安装、卸载结果
 62      */
 63     public static String apkProcess(String[] args) {
 64         String result = null;
 65         ProcessBuilder processBuilder = new ProcessBuilder(args);
 66         Process process = null;
 67         InputStream errIs = null;
 68         InputStream inIs = null;
 69         try {
 70             ByteArrayOutputStream baos = new ByteArrayOutputStream();
 71             int read = -1;
 72             process = processBuilder.start();
 73             errIs = process.getErrorStream();
 74             while ((read = errIs.read()) != -1) {
 75                 baos.write(read);
 76             }
 77             baos.write(‘\n‘);
 78             inIs = process.getInputStream();
 79             while ((read = inIs.read()) != -1) {
 80                 baos.write(read);
 81             }
 82             byte[] data = baos.toByteArray();
 83             result = new String(data);
 84         } catch (Exception e) {
 85             e.printStackTrace();
 86         } finally {
 87             try {
 88                 if (errIs != null) {
 89                     errIs.close();
 90                 }
 91                 if (inIs != null) {
 92                     inIs.close();
 93                 }
 94             } catch (Exception e) {
 95                 e.printStackTrace();
 96             }
 97             if (process != null) {
 98                 process.destroy();
 99             }
100         }
101         return result;
102     }
103 }

  最后,把MainActivity.class补充完整

 1 package com.lsj.slient;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.os.Environment;
 6 import android.view.View;
 7 import android.view.View.OnClickListener;
 8 import android.widget.Toast;
 9 
10 public class MainActivity extends Activity implements OnClickListener {
11 
12     /**
13      * <pre>
14      * 需要安装的APK程序包所在路径
15      * 在Android4.2版本中,Environment.getExternalStorageDirectory().getAbsolutePath()得到的不一定是SDCard的路径,也可能是内置存储卡路径
16      * </pre>
17      */
18     private static final String apkPath = Environment
19             .getExternalStorageDirectory().getAbsolutePath() + "/test.apk";
20     /**
21      * 要卸载应用的包名
22      */
23     private static final String packageName = "com.example.directory";
24 
25     @Override
26     protected void onCreate(Bundle savedInstanceState) {
27         super.onCreate(savedInstanceState);
28         setContentView(R.layout.activity_main);
29 
30         findViewById(R.id.install).setOnClickListener(this);
31         findViewById(R.id.uninstall).setOnClickListener(this);
32     }
33 
34     @Override
35     public void onClick(View v) {
36         boolean isSucceed = false;
37         switch (v.getId()) {
38         case R.id.install:
39             isSucceed = ApkManager.install(apkPath);
40             if (isSucceed) {
41                 Toast.makeText(MainActivity.this, "静默安装成功", Toast.LENGTH_SHORT)
42                         .show();
43             } else {
44                 Toast.makeText(MainActivity.this, "静默安装失败", Toast.LENGTH_SHORT)
45                         .show();
46             }
47             break;
48         case R.id.uninstall:
49             isSucceed = ApkManager.uninstall(packageName);
50             if (isSucceed) {
51                 Toast.makeText(MainActivity.this, "静默卸载成功", Toast.LENGTH_SHORT)
52                         .show();
53             } else {
54                 Toast.makeText(MainActivity.this, "静默卸载失败", Toast.LENGTH_SHORT)
55                         .show();
56             }
57             break;
58         default:
59             break;
60         }
61     }
62 
63 }

  OK,如此,静默安装、卸载就已经实现了!

作者:登天路

转载请说明出处:http://www.cnblogs.com/travellife/

源码下载:百度云盘

测试APK:百度云盘

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。