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在后台安装(不出现安装界面的提示),这样的安装方式称为静 ...
随机推荐
- dede 调用原图的路径
步骤:1修改include/extend.func.php 添加如下代码: //取原图地址function bigimg($str_pic){$str_houzhi=substr($str_pic,- ...
- druid sql黑名单 报异常 sql injection violation, part alway true condition not allow
最近使用druid,发现阿里这个连接池 真的很好用,可以监控到连接池活跃连接数 开辟到多少个连接数 关闭了多少个,对于我在项目中查看错误 问题,很有帮助, 但是最近发现里面 有条sql语句 被拦截了, ...
- fft练习
数学相关一直都好弱啊>_< 窝这个月要补一补数学啦, 先从基础的fft补起吧! 现在做了 道. 窝的fft 模板 (bzoj 2179) #include <iostream> ...
- NFSv4的引用,迁移和备份(用户手册 v0.2)
RFC3530 定义了NFS文件系统迁移和引用的管理机制.文件系统定位功能通过fs_location属性向客户端提供文件系统的位置信息.fs_location属 性是一个包含有位置信息的列表,位置信息 ...
- [ios] 定位报错Error Domain=kCLErrorDomain Code=0 "The operation couldn’t be completed. (kCLErrorDomain error 0.)"
Error Domain=kCLErrorDomain Code=0 "The operation couldn’t be completed. (kCLErrorDomain error ...
- 通过arcgis在PostgreSQL中创建企业级地理数据库
部署环境: Win7 64位旗舰版 软件版本: PostgreSQL-9.1.3-2-windows-x64 Postgis-pg91x64-setup-2.0.6-1 Arcgis 10.1 SP1 ...
- 树莓派pppoe
连接的网络是移动(铁通)的宽带,不同的宽带的dns需要修改. 1.首先安装pppoe包 apt-get install pppoe 2.然后,复制conf文件/etc/ppp/pppoe.conf: ...
- Mysql常用表操作 | 单表查询
160905 常用表操作 1. mysql -u root -p 回车 输入密码 2. 显示数据库列表 show databases 3. 进入某数据库 use database data ...
- 如何解决audiodg占用内存高(停止与重启audiodg服务)
window7电脑audiodg.exe进程占用内存很高 首先想到的办法是结束该进程,于是在任务管理器里结束进程后,内存是释放了,但是发现发现电脑没有声音 去到电脑的system32目录下双击audi ...
- 开始用Word 2013来写博客
第一步:如果从未发布过博客文章的话,需要在菜单里面选这里添加博客账号 第二步:选择正确的设置 第三步:写完博客之后,按这里就可以发布了! 如果以后需要写新的博客的话,还可以直接点这里: ...