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:百度雲盤

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM