随笔之所以叫随笔,就是太随意了,说起来,之前的闹钟系列随笔还没写完,争取在十月结束之前找时间把它给写了吧。今天要讲的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:百度云盘