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工具类写完整
package com.lsj.slient; import java.io.ByteArrayOutputStream;
import java.io.InputStream; import android.util.Log; /**
* 应用管理类
*
* @author Lion
*
*/
public class ApkManager { private static final String TAG = "ApkManager";
private static final String INSTALL_CMD = "install";
private static final String UNINSTALL_CMD = "uninstall"; /**
* APK静默安装
*
* @param apkPath
* APK安装包路径
* @return true 静默安装成功 false 静默安装失败
*/
public static boolean install(String apkPath) {
String[] args = { "pm", INSTALL_CMD, "-r", apkPath };
String result = apkProcess(args);
Log.e(TAG, "install log:"+result);
if (result != null
&& (result.endsWith("Success") || result.endsWith("Success\n"))) {
return true;
}
return false;
} /**
* APK静默安装
*
* @param packageName
* 需要卸载应用的包名
* @return true 静默卸载成功 false 静默卸载失败
*/
public static boolean uninstall(String packageName) {
String[] args = { "pm", UNINSTALL_CMD, packageName };
String result = apkProcess(args);
Log.e(TAG, "uninstall log:"+result);
if (result != null
&& (result.endsWith("Success") || result.endsWith("Success\n"))) {
return true;
}
return false;
} /**
* 应用安装、卸载处理
*
* @param args
* 安装、卸载参数
* @return Apk安装、卸载结果
*/
public static String apkProcess(String[] args) {
String result = null;
ProcessBuilder processBuilder = new ProcessBuilder(args);
Process process = null;
InputStream errIs = null;
InputStream inIs = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int read = -1;
process = processBuilder.start();
errIs = process.getErrorStream();
while ((read = errIs.read()) != -1) {
baos.write(read);
}
baos.write('\n');
inIs = process.getInputStream();
while ((read = inIs.read()) != -1) {
baos.write(read);
}
byte[] data = baos.toByteArray();
result = new String(data);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (errIs != null) {
errIs.close();
}
if (inIs != null) {
inIs.close();
}
} catch (Exception e) {
e.printStackTrace();
}
if (process != null) {
process.destroy();
}
}
return result;
}
}
最后,把MainActivity.class补充完整
package com.lsj.slient; import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener { /**
* <pre>
* 需要安装的APK程序包所在路径
* 在Android4.2版本中,Environment.getExternalStorageDirectory().getAbsolutePath()得到的不一定是SDCard的路径,也可能是内置存储卡路径
* </pre>
*/
private static final String apkPath = Environment
.getExternalStorageDirectory().getAbsolutePath() + "/test.apk";
/**
* 要卸载应用的包名
*/
private static final String packageName = "com.example.directory"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); findViewById(R.id.install).setOnClickListener(this);
findViewById(R.id.uninstall).setOnClickListener(this);
} @Override
public void onClick(View v) {
boolean isSucceed = false;
switch (v.getId()) {
case R.id.install:
isSucceed = ApkManager.install(apkPath);
if (isSucceed) {
Toast.makeText(MainActivity.this, "静默安装成功", Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(MainActivity.this, "静默安装失败", Toast.LENGTH_SHORT)
.show();
}
break;
case R.id.uninstall:
isSucceed = ApkManager.uninstall(packageName);
if (isSucceed) {
Toast.makeText(MainActivity.this, "静默卸载成功", Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(MainActivity.this, "静默卸载失败", Toast.LENGTH_SHORT)
.show();
}
break;
default:
break;
}
} }
OK,如此,静默安装、卸载就已经实现了!
作者:登天路
转载请说明出处:http://www.cnblogs.com/travellife/
源码下载:百度云盘
测试APK:百度云盘
Android随笔之——静默安装、卸载的更多相关文章
- android 静默安装 卸载 资料汇总
1. android + eclipse + 后台静默安装(一看就会) 2. 适用于android1.5以下版本apk静默安装 3. error: INSTALL_FAILED_SHARED_USER ...
- android开发实现静默安装(root权限)
方式是将应用设置为内置的系统应用,注意事system/app目录下面,采用copy2SystemApp()方法就可以,注意chmod 777的权限,若是直接将apk拷贝到system/app目录,没有 ...
- android开发,关于android app实现静默安装自己(系统签名)
产品需求,木有办法.android系统是跟厂商定制的,保证系统开机就运行我们的app,并且实现自己静默安装,完全自动化,无需人工操作. 网上有很多办法, 1.要么要通过android 源码拿到密钥文件 ...
- android开发实现静默安装(fota升级)
这里只提供一个思路,也是咨询大神才了解到的. fota升级主要用于系统及系统应用的升级,不过貌似也会弹出提示用于用户确认.既然做到系统级别了,估计也一样可以静默安装的.
- Android apk的安装、卸载、更新升级(通过Eclipse实现静默安装)
一.通过Intent消息机制发送消息,调用系统应用进行,实现apk的安装/卸载 . (1) 调用系统的安装应用,让系统自动进行apk的安装 String fileName = "/data/ ...
- 让Android程序获得系统的权限,实现关机重启,静默安装等功能
引用:http://www.cnblogs.com/welenwho/archive/2012/05/10/2494984.html android想要获得系统权限有几种途径,一种就是你的程序固化的系 ...
- Android获取Root权限之后的静默安装实现代码示例分析
转:http://blog.csdn.net/jiankeufo/article/details/43795015 Adroid开发中,我们有时会遇到一些特殊功能的实现,有些功能并没有太高技术难度,但 ...
- Android实现静默安装与卸载
一般情况下,Android系统安装apk会出现一个安装界面,用户可以点击确定或者取消来进行apk的安装. 但在实际的项目需求中,有一种需求,就是希望apk在后台安装(不出现安装界面的提示),这种安装方 ...
- Android对于静默安装和卸载
在一般情况下,Android系统安装apk会有一个安装界面,用户可以单击确定或取消apk设备. 但在实际的项目需求中,有一种需求.就是希望apk在后台安装(不出现安装界面的提示),这样的安装方式称为静 ...
随机推荐
- 浏览器的兼容问题 判断IE方法
下面是一些判断ie的常用方法: <!-[if IE 6]> 此处是IE6才会执行的代码 <![endif]-> 还可以给他加个条件,比如判断IE6以下的浏览器: <!-[ ...
- JSONObject、JSONArray区别
json,就是一个键对应一个值,超级简单的一对一关系.现在用到的json那可以层层嵌套啊,刚开始接触的时候,确实有种崩溃的赶脚,不想去理,取个数据还那么麻烦.其实,就跟if else语句一样,如果if ...
- Mac OS X 中快速访问系统根目录的四种方法
1.通过终端打开Finder的根目录 open / 2.通过“前往文件夹”快捷键组合 用户只需点击左上角的“前往”菜单,然后选择“前往文件夹...”功能.使用快捷键+Shift+G也 ...
- SSHE框架整合(增删改查)
1.前期准备:jar包(c3p0.jdbc ,各个框架) web.xml文件:spring的 转码的,和Struts2的过滤器 <?xml version="1.0" e ...
- 【noip 2005】 采药
题目描述 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说:" ...
- cocoapods安装出错问题
今天执行pod install时,出现了错误,提示更新,好,那就更新; 1.终端执行了下:gem sources -l 查看了下源 *** CURRENT SOURCES *** https:// ...
- tomcat相关
一.下面这篇文章介绍了tomcat log相关内容 http://blog.csdn.net/cowmich/article/details/8173005
- java读写Properties属性文件公用方法
Java中有个比较重要的类Properties(Java.util.Properties),主要用于读取Java的配置文件. 它提供了几个主要的方法: 1. getProperty ( String ...
- PHP的日期和时间处理函数
1. 将日期和时间转变为时间戳 1.1 time() 原型:time(void) 作用:返回当前时间的 UNIX时间戳. 参数:void,可选(即无参数) 1.2 mktime() 原型:int mk ...
- ASP.NET Core 使用 Redis 和 Protobuf 进行 Session 缓存
前言 上篇博文介绍了怎么样在 asp.net core 中使用中间件,以及如何自定义中间件.项目中刚好也用到了Redis,所以本篇就介绍下怎么样在 asp.net core 中使用 Redis 进行资 ...