• 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
    "))) {
     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
    "))) {
     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('
    ');
     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:百度云盘

  • 相关阅读:
    azure虚拟机创建后如何ssh私钥连接
    VisualStudio在本地创建新解决方案后如何推送到devops
    【转载】sar命令详解
    【转载】Redis【入门】就这一篇!
    【转载】算法复杂度解析,何为O()
    centOS data格式文件
    linux centOS命令整理
    机器学习中评估计算:PR,ROC,AUC计算方法
    Python中中文输出显示以及列表初始化坑坑
    SKLearn中模型持久化
  • 原文地址:https://www.cnblogs.com/travellife/p/4010398.html
Copyright © 2020-2023  润新知