Android 静默安装和智能安装的实现方法

1 简介

最近研究了Android的静默安装和智能安装,于是写博客记录一下。静默安装就是无声无息的在后台安装apk,没有任何界面提示。智能安装就是有安装界面,但全部是自动的,不需要用户去点击。

首先强调两点:静默安装必须要root权限 智能安装必须要用户手动开启无障碍服务

2 原理

静默安装、卸载的原理就是利用pm install命令来安装apk,pm uninstall 来卸载apk. 智能安装是利用android系统提供的无障碍服务AccessibilityService,来模拟用户点击,从而自动安装.

3 pm命令介绍

(1) pm install

pm install 命令的用法及参数解释如下:

<code class="hljs haml">pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH
Options:
 -l: install the package with FORWARD_LOCK.
 -r: reinstall an exisiting app, keeping its data.
 -t: allow test .apks to be installed.
 -i: specify the installer package name.
 -s: install package on sdcard.
 -f: install package on internal flash.</code>

(2) pm uninstall

pm uninstall 命令的用法及参数解释如下:

<code class="hljs livecodeserver">pm uninstall [-k] PACKAGE
Options:
 -k: keep the data and cache directories around.</code>

上面英语很简单,不解释了.

4 静默安装

为了方便演示,我把爱奇艺的安装包重命名为test.apk后放在了sdcard上。你可以自己去爱奇艺官网去下载,也可以自己找一个apk放到sdcard上,但是要知道apk的包名,后面卸载的时候要用到。

先上代码:

<code class="hljs cs">//静默安装
 private void installSlient() {
 String cmd = "pm install -r /mnt/sdcard/test.apk";
 Process process = null;
 DataOutputStream os = null;
 BufferedReader successResult = null;
 BufferedReader errorResult = null;
 StringBuilder successMsg = null;
 StringBuilder errorMsg = null;
 try {
  //静默安装需要root权限
  process = Runtime.getRuntime().exec("su");
  os = new DataOutputStream(process.getOutputStream());
  os.write(cmd.getBytes());
  os.writeBytes("\n");
  os.writeBytes("exit\n");
  os.flush();
  //执行命令
  process.waitFor();
  //获取返回结果
  successMsg = new StringBuilder();
  errorMsg = new StringBuilder();
  successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
  errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
  String s;
  while ((s = successResult.readLine()) != null) {
  successMsg.append(s);
  }
  while ((s = errorResult.readLine()) != null) {
  errorMsg.append(s);
  }
 } catch (Exception e) {
  e.printStackTrace();
 } finally {
  try {
  if (os != null) {
   os.close();
  }
  if (process != null) {
   process.destroy();
  }
  if (successResult != null) {
   successResult.close();
  }
  if (errorResult != null) {
   errorResult.close();
  }
  } catch (Exception e) {
  e.printStackTrace();
  }
 }
 //显示结果
 tvTest.setText("成功消息:" + successMsg.toString() + "\n" + "错误消息: " + errorMsg.toString());
 }</code>

这段代码就是在程序中执行pm命令,和在adb下执行 pm install -r /mnt/sdcard/test.apk 效果是一样的, 关键的代码是 Runtime.getRuntime().exec(“su”) ,这段代码会要求获取root权限,所以你的手机必须root,不想root的话,直接用模拟器也可以。

通过 Runtime.getRuntime().exec(“su”) 获取到 process 对象后就可以写入命令了,每写入一条命令就要换行,写入 ‘\n' 即可,最后写入exit后离开命令执行的环境.

5 静默卸载

静默卸载和静默安装是一样的,只是命令不同,静默卸载需要用到包名,同样,静默卸载也需要root权限
看代码:

<code class="hljs java">//爱奇艺apk的包名
private static final String PACKAGE_NAME = "com.qiyi.video";
//静默卸载
 private void uninstallSlient() {
 String cmd = "pm uninstall " + PACKAGE_NAME;
 Process process = null;
 DataOutputStream os = null;
 BufferedReader successResult = null;
 BufferedReader errorResult = null;
 StringBuilder successMsg = null;
 StringBuilder errorMsg = null;
 try {
  //卸载也需要root权限
  process = Runtime.getRuntime().exec("su");
  os = new DataOutputStream(process.getOutputStream());
  os.write(cmd.getBytes());
  os.writeBytes("\n");
  os.writeBytes("exit\n");
  os.flush();
  //执行命令
  process.waitFor();
  //获取返回结果
  successMsg = new StringBuilder();
  errorMsg = new StringBuilder();
  successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
  errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
  String s;
  while ((s = successResult.readLine()) != null) {
  successMsg.append(s);
  }
  while ((s = errorResult.readLine()) != null) {
  errorMsg.append(s);
  }
 } catch (Exception e) {
  e.printStackTrace();
 } finally {
  try {
  if (os != null) {
   os.close();
  }
  if (process != null) {
   process.destroy();
  }
  if (successResult != null) {
   successResult.close();
  }
  if (errorResult != null) {
   errorResult.close();
  }
  } catch (Exception e) {
  e.printStackTrace();
  }
 }
 //显示结果
 tvTest.setText("成功消息:" + successMsg.toString() + "\n" + "错误消息: " + errorMsg.toString());
 }</code>

和静默安装一样的代码就不解释了。还有,如果你不知道一个apk的包名,那么请反编译后去看AndroidManifest.xml文件,如果这个文件打开全是乱码,说明是被混淆过的,那么直接安装它,然后到/data/data下面去找它的包,当然,手机得root才能进/data/data目录。

6 智能安装

智能安装就稍微麻烦点了,原理是用到了android提供的AccessibilityService服务,这个服务可以获取屏幕上的节点,一个节点也就是一个view,我们写的xml文件中每个标签就是一个节点,然后可以模拟用户的操作,对这些节点进行点击、滑动等操作。我们就是利用这个原理,来自动点击安装按钮的,当然使用这个服务必须用户手动开启无障碍服务。下面我们来看具体的实现方法。

(1) 创建AccessibilityService配置文件

在res目录下创建xml目录,然后在xml目录下创建一个accessibility_service_config.xml文件,内容如下
res/xml/accessibility_service_config.xml:

<code class="hljs xml" data-filtered="filtered"></accessibility-service></code>

accessibilityEventTypes:指定我们在监听窗口中可以模拟哪些事件,typeAllMask表示所有的事件都能模拟.

accessibilityFeedbackType:指定无障碍服务的反馈方式.

canRetrieveWindowContent:指定是否允许我们的程序读取窗口中的节点和内容,当然是true.

description: 当用户手动配置服务时,会显示给用户看.

packageNames: 指定我们要监听哪个应用程序下的窗口活动,这里写com.android.packageinstaller表示监听Android系统的安装界面。

其余参数照写即可。

res/strings.xml:

<code class="hljs xml"><resources>
 <string name="app_name">SlientInstallTest</string>
 <string name="desc">智能安装app功能演示</string>
</resources></code>

(2) 创建AccessibilityService服务

<code class="hljs java">public class MyAccessibilityService extends AccessibilityService {
 private static final String TAG = "[TAG]";
 private Map<integer, boolean=""> handleMap = new HashMap<>();
 @Override
 public void onAccessibilityEvent(AccessibilityEvent event) {
 AccessibilityNodeInfo nodeInfo = event.getSource();
 if (nodeInfo != null) {
  int eventType = event.getEventType();
  if (eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED || eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
  if (handleMap.get(event.getWindowId()) == null) {
   boolean handled = iterateNodesAndHandle(nodeInfo);
   if (handled) {
   handleMap.put(event.getWindowId(), true);
   }
  }
  }
 }
 }
 @Override
 public void onInterrupt() {
 }
 //遍历节点,模拟点击安装按钮
 private boolean iterateNodesAndHandle(AccessibilityNodeInfo nodeInfo) {
 if (nodeInfo != null) {
  int childCount = nodeInfo.getChildCount();
  if ("android.widget.Button".equals(nodeInfo.getClassName())) {
  String nodeCotent = nodeInfo.getText().toString();
  Log.d(TAG, "content is: " + nodeCotent);
  if ("安装".equals(nodeCotent) || "完成".equals(nodeCotent) || "确定".equals(nodeCotent)) {
   nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
   return true;
  }
  }
  //遇到ScrollView的时候模拟滑动一下
  else if ("android.widget.ScrollView".equals(nodeInfo.getClassName())) {
  nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
  }
  for (int i = 0; i < childCount; i++) {
  AccessibilityNodeInfo childNodeInfo = nodeInfo.getChild(i);
  if (iterateNodesAndHandle(childNodeInfo)) {
   return true;
  }
  }
 }
 return false;
 }
}</integer,></code>

当进入apk安装界面就会回调onAccessibilityEvent()这个方法,我们只关心TYPE_WINDOW_CONTENT_CHANGED和TYPE_WINDOW_STATE_CHANGED两个事件,为了防止重复处理事件,用一个map来过滤事件,后面递归遍历节点,找到'安装' ‘完成' ‘确定' 的按钮,就点击,由于安装界面需要滚动一下才能出现安装按钮,所以遇到ScrollView的时候就滚动一下.

(3) 在AndroidManifest中配置服务

<code class="hljs xml"><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE">
  <intent-filter>
  <category android:name="android.intent.category.LAUNCHER">
  </category></action></intent-filter>
 </activity>
 <service android:label="智能安装App" android:name=".MyAccessibilityService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
  <intent-filter>
  </action></intent-filter>
  <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibility_service_config">
 </meta-data></service>
 </application></uses-permission></code>

重点是后面的service标签:

android:label:这个就是用户看到的无障碍服务的名称

android:permission: 需要用到BIND_ACCESSIBILITY_SERVICE这个权限.

action: android.accessibilityservice.AccessibilityService 有了这个action,用户才能在设置里面看到我们的服务,否则用户无法开启我们写的服务,也就不能进到我们写的MyAccessibilityService里面了.所以,注意不要写错了,如果你发现无障碍服务里面没有我们写的服务,请检查这里.

(4) 调用智能安装代码

前面准备工作完毕后,现在要用了,调用智能安装的代码如下:

<code class="hljs cs"> //智能安装
 private void smartInstall() {
 Uri uri = Uri.fromFile(new File("/mnt/sdcard/test.apk"));
 Intent localIntent = new Intent(Intent.ACTION_VIEW);
 localIntent.setDataAndType(uri, "application/vnd.android.package-archive");
 startActivity(localIntent);
 }</code>

(5) 手动配置智能安装服务

代码运行之后,还要用户选择开启智能安装服务,让用户自己去找是不明智的,因此,我们要主动跳到配置界面,代码如下:

<code class="hljs cs">//跳转到开启智能安装服务的界面
Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivity(intent);</code>

配置如下图:

看到了吗,上面显示的就是Service里面的label的值,如果你没有上面的选项,请检查AndroidManifest里面Service的配置.
点击'智能安装App',开启服务,如下图:

其中的提示文字就是我们在res/xml/accessibility_service_config.xml文件中配置的description属性

7 只能我们写的app可以自动安装

这样写完代码可以运行,点击按钮自动安装sdcard上的test.apk.但是你会发现,所有apk都会自动安装,这就不符合我们的要求了,我们要求只能通过我们写的app来自动安装,其他apk还是要用户手动去点。怎么解决这个问题呢?

思路是:在MainActivity中创建一个public static boolean flag,在MyAccessibilityService的onAccessibilityEvent()中加一个flag判断,然后调用智能安装前flag设为true,创建apk安装事件的广播接收器,当apk安装完成后,设置falg为false,这样其他apk就不能自动安装了,就解决了这个问题

下面上完整代码.

8 完整代码

app/MainActivity.java:

<code class="hljs java">public class MainActivity extends AppCompatActivity implements View.OnClickListener {
 private static final String TAG = "[TAG][MainActivity]";
 private static final String PACKAGE_NAME = "com.qiyi.video";
 private String apkPath = "/mnt/sdcard/test.apk";
 public static boolean flag = false;//控制只能自己的app才能执行智能安装
 private TextView tvTest;
 private MyInstallReceiver receiver;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 tvTest = (TextView) findViewById(R.id.tv_test);
 findViewById(R.id.btn_install).setOnClickListener(this);
 findViewById(R.id.btn_uninstall).setOnClickListener(this);
 findViewById(R.id.btn_set).setOnClickListener(this);
 findViewById(R.id.btn_smart_install).setOnClickListener(this);
 //注册apk安装监听
 receiver = new MyInstallReceiver();
 IntentFilter filter = new IntentFilter();
 filter.addAction("android.intent.action.PACKAGE_ADDED");
 filter.addAction("android.intent.action.PACKAGE_REMOVED");
 filter.addDataScheme("package");
 this.registerReceiver(receiver, filter);
 }
 @Override
 public void onClick(View v) {
 switch (v.getId()) {
  //静默安装
  case R.id.btn_install:
  installSlient();
  break;
  //静默卸载
  case R.id.btn_uninstall:
  uninstallSlient();
  break;
  //设置无障碍服务
  case R.id.btn_set:
  //跳转到开启无障碍服务的界面
  Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
  startActivity(intent);
  break;
  //智能安装
  case R.id.btn_smart_install:
  //控制只能自己的app才能智能安装
  flag = true;
  smartInstall();
  break;
 }
 }
 //静默安装
 private void installSlient() {
 String cmd = "pm install -r /mnt/sdcard/test.apk";
 Process process = null;
 DataOutputStream os = null;
 BufferedReader successResult = null;
 BufferedReader errorResult = null;
 StringBuilder successMsg = null;
 StringBuilder errorMsg = null;
 try {
  //静默安装需要root权限
  process = Runtime.getRuntime().exec("su");
  os = new DataOutputStream(process.getOutputStream());
  os.write(cmd.getBytes());
  os.writeBytes("\n");
  os.writeBytes("exit\n");
  os.flush();
  //执行命令
  process.waitFor();
  //获取返回结果
  successMsg = new StringBuilder();
  errorMsg = new StringBuilder();
  successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
  errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
  String s;
  while ((s = successResult.readLine()) != null) {
  successMsg.append(s);
  }
  while ((s = errorResult.readLine()) != null) {
  errorMsg.append(s);
  }
 } catch (Exception e) {
  e.printStackTrace();
 } finally {
  try {
  if (os != null) {
   os.close();
  }
  if (process != null) {
   process.destroy();
  }
  if (successResult != null) {
   successResult.close();
  }
  if (errorResult != null) {
   errorResult.close();
  }
  } catch (Exception e) {
  e.printStackTrace();
  }
 }
 //显示结果
 tvTest.setText("成功消息:" + successMsg.toString() + "\n" + "错误消息: " + errorMsg.toString());
 }
 //静默卸载
 private void uninstallSlient() {
 String cmd = "pm uninstall " + PACKAGE_NAME;
 Process process = null;
 DataOutputStream os = null;
 BufferedReader successResult = null;
 BufferedReader errorResult = null;
 StringBuilder successMsg = null;
 StringBuilder errorMsg = null;
 try {
  //卸载也需要root权限
  process = Runtime.getRuntime().exec("su");
  os = new DataOutputStream(process.getOutputStream());
  os.write(cmd.getBytes());
  os.writeBytes("\n");
  os.writeBytes("exit\n");
  os.flush();
  //执行命令
  process.waitFor();
  //获取返回结果
  successMsg = new StringBuilder();
  errorMsg = new StringBuilder();
  successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
  errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
  String s;
  while ((s = successResult.readLine()) != null) {
  successMsg.append(s);
  }
  while ((s = errorResult.readLine()) != null) {
  errorMsg.append(s);
  }
 } catch (Exception e) {
  e.printStackTrace();
 } finally {
  try {
  if (os != null) {
   os.close();
  }
  if (process != null) {
   process.destroy();
  }
  if (successResult != null) {
   successResult.close();
  }
  if (errorResult != null) {
   errorResult.close();
  }
  } catch (Exception e) {
  e.printStackTrace();
  }
 }
 //显示结果
 tvTest.setText("成功消息:" + successMsg.toString() + "\n" + "错误消息: " + errorMsg.toString());
 }
 //智能安装
 private void smartInstall() {
 Uri uri = Uri.fromFile(new File(apkPath));
 Intent localIntent = new Intent(Intent.ACTION_VIEW);
 localIntent.setDataAndType(uri, "application/vnd.android.package-archive");
 startActivity(localIntent);
 }
 //监听apk安装
 private class MyInstallReceiver extends BroadcastReceiver {
 @Override
 public void onReceive(Context context, Intent intent) {
  if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) { // install
  String packageName = intent.getDataString();
  Log.i(TAG, "安装了 :" + packageName);
  //安装完毕,设置flag,从而使得其余的apk不能自动安装
  flag = false;
  }
  if (intent.getAction().equals("android.intent.action.PACKAGE_REMOVED")) { // uninstall
  String packageName = intent.getDataString();
  Log.i(TAG, "卸载了 :" + packageName);
  }
 }
 }
 @Override
 protected void onDestroy() {
 super.onDestroy();
 if (receiver != null) {
  unregisterReceiver(receiver);
 }
 }
}</code>

界面上就三个按钮

res/layout/activity_main.xml:

<code class="hljs xml"><!--?xml version="1.0" encoding="utf-8"?-->
<relativelayout android:layout_height="match_parent" android:layout_width="match_parent" android:paddingbottom="@dimen/activity_vertical_margin" android:paddingleft="@dimen/activity_horizontal_margin" android:paddingright="@dimen/activity_horizontal_margin" android:paddingtop="@dimen/activity_vertical_margin" xmlns:android="https://schemas.android.com/apk/res/android" xmlns:tools="https://schemas.android.com/tools">
 <textview android:id="@+id/tv_test" android:layout_height="wrap_content" android:layout_width="match_parent" android:text=""><button android:id="@+id/btn_install" android:layout_centerinparent="true" android:layout_height="wrap_content" android:layout_width="match_parent" android:text="安装"></button><button android:id="@+id/btn_uninstall" android:layout_below="@id/btn_install" android:layout_height="wrap_content" android:layout_width="match_parent" android:text="卸载"></button><button android:id="@+id/btn_set" android:layout_below="@id/btn_uninstall" android:layout_height="wrap_content" android:layout_width="match_parent" android:text="开启智能安装功能"></button></textview></relativelayout></code><button android:id="@+id/btn_smart_install" android:layout_below="@id/btn_set" android:layout_height="wrap_content" android:layout_width="match_parent" android:text="智能安装"><code class="hljs xml">
</code></button>

服务配置文件

res/xml/accessibility_service_config.xml

<code class="hljs xml" data-filtered="filtered"></accessibility-service></code>

智能安装服务

app/MyAccessibilityService.java:

<code class="hljs java">public class MyAccessibilityService extends AccessibilityService {
 private static final String TAG = "[TAG]";
 private Map<integer, boolean=""> handleMap = new HashMap<>();
 @Override
 public void onAccessibilityEvent(AccessibilityEvent event) {
 AccessibilityNodeInfo nodeInfo = event.getSource();
 if (nodeInfo != null && MainActivity.flag) {
  int eventType = event.getEventType();
  if (eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED || eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
  if (handleMap.get(event.getWindowId()) == null) {
   boolean handled = iterateNodesAndHandle(nodeInfo);
   if (handled) {
   handleMap.put(event.getWindowId(), true);
   }
  }
  }
 }
 }
 @Override
 public void onInterrupt() {
 }
 //遍历节点,模拟点击安装按钮
 private boolean iterateNodesAndHandle(AccessibilityNodeInfo nodeInfo) {
 if (nodeInfo != null) {
  int childCount = nodeInfo.getChildCount();
  if ("android.widget.Button".equals(nodeInfo.getClassName())) {
  String nodeCotent = nodeInfo.getText().toString();
  Log.d(TAG, "content is: " + nodeCotent);
  if ("安装".equals(nodeCotent) || "完成".equals(nodeCotent) || "确定".equals(nodeCotent)) {
   nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
   return true;
  }
  }
  //遇到ScrollView的时候模拟滑动一下
  else if ("android.widget.ScrollView".equals(nodeInfo.getClassName())) {
  nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
  }
  for (int i = 0; i < childCount; i++) {
  AccessibilityNodeInfo childNodeInfo = nodeInfo.getChild(i);
  if (iterateNodesAndHandle(childNodeInfo)) {
   return true;
  }
  }
 }
 return false;
 }
}</integer,></code>

最后是配置文件AndroidManifest.xml:

<code class="hljs xml"><manifest package="com.slientinstalltest" xmlns:android="https://schemas.android.com/apk/res/android">
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE">
  <intent-filter>
  <category android:name="android.intent.category.LAUNCHER">
  </category></action></intent-filter>
 </activity>
 <service android:label="智能安装App" android:name=".MyAccessibilityService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
  <intent-filter>
  </action></intent-filter>
  <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibility_service_config">
 </meta-data></service>
 </application>
</uses-permission></manifest></code>

注意:请把自己要安装的apk放到sdcard上,并且修改代码中的apk路径和包名

9 运行效果

10 总结

Android智能安装的原理就是利用了类似钩子的服务,这个服务还可以用于微信抢红包的开发,怎么样,是不是比ios好玩儿的多呢.

您可能感兴趣的文章:

  • Android静默安装实现方案 仿360手机助手秒装和智能安装功能
  • Android 静默安装和卸载的方法
  • Android实现静默安装实例代码
  • Android实现静默安装的两种方法
  • Android无需root实现apk的静默安装
  • android实现静默安装与卸载的方法
(0)

相关推荐

  • Android 静默安装和卸载的方法

    本文介绍了Android 静默安装和卸载的方法,分享给大家,具体如下: 一. 条件 系统签名 需要放到 /system/app里作为系统app 二. 适用环境 机顶盒开发,系统开发,车机开发,智能设备开发. 三. 步骤 1. 在 AndroidManifest.xml 中 1.1. 在清单文件 AndroidManifest.xml 添加 android.uid.system 声明为系统应用. 1.2. 权限 <uses-permission android:name="android.p

  • Android实现静默安装的两种方法

    前言 一般情况下,Android系统安装apk会出现一个安装界面,用户可以点击确定或者取消来进行apk的安装. 但在实际的项目需求中,有一种需求,就是希望apk在后台安装(不出现安装界面的提示),这种安装方式称为静默安装.下面这篇文章就给大家介绍了两种方法来实现,下面来一起看看吧. 1.root权限静默安装实现 实现实际使用的是su pm install -r filePath命令. 核心代码如下: protected static void excuteSuCMD() { Process pr

  • android实现静默安装与卸载的方法

    本文实例讲述了android实现静默安装与卸载的方法.分享给大家供大家参考.具体如下: 方法1:[使用调用接口方法,由于安装卸载应用程序的部分API是隐藏的,所以必须下载Android系统源码,在源码下开发并编译之后使用MM命令编译生成APK文件] import java.io.File; import android.app.Activity; import android.os.Bundle; import android.content.Intent; import android.con

  • Android无需root实现apk的静默安装

    Android的静默安装似乎是一个很有趣很诱人的东西,但是,用普通做法,如果手机没有root权限的话,似乎很难实现静默安装,因为Android并不提供显示的Intent调用,一般是通过以下方式安装apk: Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); startAct

  • Android实现静默安装实例代码

    静默安装主要分为以下几种方式: 一.在ROOT过的机器上,在App中使用pm install指令安装APK: // 申请su权限 Process process = Runtime.getRuntime().exec("su"); dataOutputStream = new DataOutputStream(process.getOutputStream()); // 执行pm install命令 String command = "pm install -r "

  • Android静默安装实现方案 仿360手机助手秒装和智能安装功能

    之前有很多朋友都问过我,在Android系统中怎样才能实现静默安装呢?所谓的静默安装,就是不用弹出系统的安装界面,在不影响用户任何操作的情况下不知不觉地将程序装好.虽说这种方式看上去不打搅用户,但是却存在着一个问题,因为Android系统会在安装界面当中把程序所声明的权限展示给用户看,用户来评估一下这些权限然后决定是否要安装该程序,但如果使用了静默安装的方式,也就没有地方让用户看权限了,相当于用户被动接受了这些权限.在Android官方看来,这显示是一种非常危险的行为,因此静默安装这一行为系统是

  • Android 静默安装和智能安装的实现方法

    1 简介 最近研究了Android的静默安装和智能安装,于是写博客记录一下.静默安装就是无声无息的在后台安装apk,没有任何界面提示.智能安装就是有安装界面,但全部是自动的,不需要用户去点击. 首先强调两点:静默安装必须要root权限 智能安装必须要用户手动开启无障碍服务 2 原理 静默安装.卸载的原理就是利用pm install命令来安装apk,pm uninstall 来卸载apk. 智能安装是利用android系统提供的无障碍服务AccessibilityService,来模拟用户点击,从

  • Android 静默方式实现批量安装卸载应用程序的深入分析

    前段时间做了一个批量安装卸载应用程序的小应用,由于安装卸载应用程序的部分API是隐藏的,所以必须在ubuntu下下载Android系统源码,并编译之后使用MM命令编译生成APK文件,其实也难. 思路是这样的,在XX/packages/apps目录下有一个PackageInstaller的应用程序,Android机器中安装卸载都是由这个应用程序完成的.但是它没有批量安装和卸载的功能,如果要在自己的应用程序中添加批量安装和卸载的功能,其实很简单,只需要参考PakcageInstaller里面的安装卸

  • Android 静默安装实现方法

    Android静默安装的方法,静默安装就是绕过安装程序时的提示窗口,直接在后台安装. 注意:静默安装的前提是设备有ROOT权限. 代码如下: /** * 静默安装 * @param file * @return */ public boolean slientInstall(File file) { boolean result = false; Process process = null; OutputStream out = null; try { process = Runtime.ge

  • Android 检查更新、下载、安装功能的实现

    android检查更新.下载.安装 前言: 由于友盟更新即将下线,我们就修改了更新逻辑,自己检查更新.下载.安装,但是检查更新还是要依赖于友盟中的在线参数: 1.MainActivity.Java: public class MainActivity extends BaseActivity{ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setCon

  • Android编程实现应用强制安装到手机内存的方法

    本文实例讲述了Android编程实现应用强制安装到手机内存的方法.分享给大家供大家参考,具体如下: 在Froyo(android 2.2,API Level:8)中引入了android:installLocation.通过设置该属性可以使得开发者以及用户决定程序的安装位置. android:installLocation隶属于AndroidManifest.XML中的manifest节点.如下所示: <manifest xmlns:android="http://schemas.andro

  • Android实现用代码简单安装和卸载APK的方法

    本文实例讲述了Android实现用代码简单安装和卸载APK的方法.分享给大家供大家参考,具体如下: public class TestInstallAPK extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); // this.unInstallFi

  • Android编程实现监控apk安装,卸载,替换的方法

    本文实例讲述了Android编程实现监控apk安装,卸载,替换的方法.分享给大家供大家参考,具体如下: public class GetBroadcast extends BroadcastReceiver { private static GetBroadcast mReceiver = new GetBroadcast(); private static IntentFilter mIntentFilter; public static void registerReceiver(Conte

  • Android编程之软件的安装和卸载方法

    本文实例讲述了Android编程之软件的安装和卸载方法.分享给大家供大家参考,具体如下: 安装:从sdcard String fileName = Environment.getExternalStorageDirectory() + "/myApp.apk"; Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.parse("file://" + filePath),&

随机推荐