Android中软件的静默安装,安装完成后再自动打开新安装软件(需Root)
来源:互联网 发布:python 定时任务 编辑:程序博客网 时间:2024/06/05 20:34
编写不易,如有转载,请声明出处: 梦回河口:http://blog.csdn.net/zxc514257857/article/details/77488832
前言
需要获取Root权限,安装过程完全静默实现,注册安装、卸载、升级的广播,安装完成后自动打开新安装的软件
全部代码
// AndroidManifest中权限配置<uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/><uses-permission android:name="android.permission.RESTART_PACKAGES" /><uses-permission android:name="android.permission.INSTALL_PACKAGES" tools:ignore="ProtectedPermissions" />----------------------------------------------------------------------------------------// AndroidManifest中静态注册广播<receiver android:name=".SilenceInstallReceiver"> <intent-filter> <action android:name="android.intent.action.PACKAGE_REPLACED"/> <action android:name="android.intent.action.PACKAGE_ADDED" /> <action android:name="android.intent.action.PACKAGE_REMOVED" /> <data android:scheme="package"/> </intent-filter></receiver>----------------------------------------------------------------------------------------// MainActivityimport android.content.Context;import android.content.Intent;import android.content.pm.PackageInfo;import android.net.Uri;import android.os.Environment;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import java.io.DataOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private String tempPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/temp.apk"; private PackageInfo mPackageInfo; private Context mContext = MainActivity.this; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if(RootUtils.isRooted()) { // 从assets目录中获取apk并安装 installFromAssets(); } } /** * 从assets目录中获取并安装 */ public void installFromAssets(){ try { // 根据包名判断是否安装 如果未找到包名说明包名输入错误或未安装 // 想要安装的apk的名字是testapk,其包名为com.testapk.apk mPackageInfo = getPackageManager().getPackageInfo("com.test.testapk", 0); } catch (Exception e) { mPackageInfo = null; e.printStackTrace(); } if (mPackageInfo == null) { // 启用安装新线程 new Thread(new Runnable() { @Override public void run() { Log.i(TAG , "未安装进行安装"); // 静默安装(安装其他软件或自己的升级版 无界面显示) 并启动 slientInstall(); } }).start(); } else { Log.i(TAG , "已经安装"); } } /** * 静默安装 并启动 * * @return */ public boolean slientInstall() { // 进行资源的转移 将assets下的文件转移到可读写文件目录下 createFile(); File file = new File(tempPath); boolean result = false; Process process = null; OutputStream out = null; Log.i(TAG , "file.getPath():" + file.getPath()); if (file.exists()) { System.out.println(file.getPath() + "=="); try { process = Runtime.getRuntime().exec("su"); out = process.getOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(out); // 获取文件所有权限 dataOutputStream.writeBytes("chmod 777 " + file.getPath() + "\n"); // 进行静默安装命令 dataOutputStream .writeBytes("LD_LIBRARY_PATH=/vendor/lib:/system/lib pm install -r " + file.getPath()); dataOutputStream.flush(); // 关闭流操作 dataOutputStream.close(); out.close(); int value = process.waitFor(); // 代表成功 if (value == 0) { Log.i(TAG , "安装成功!"); result = true; // 失败 } else if (value == 1) { Log.i(TAG , "安装失败!"); result = false; // 未知情况 } else { Log.i(TAG , "未知情况!"); result = false; } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } if (!result) { Log.i(TAG , "root权限获取失败,将进行普通安装"); normalInstall(mContext); result = true; } } return result; } /** * 进行资源的转移 将assets下的文件转移到可读写文件目录下 */ public void createFile() { InputStream is = null; FileOutputStream fos = null; try { // 从assets文件夹中获取testapk.apk文件 is = getAssets().open("testapk.apk"); File file = new File(tempPath); file.createNewFile(); fos = new FileOutputStream(file); byte[] temp = new byte[1024]; int i = 0; while ((i = is.read(temp)) > 0) { fos.write(temp, 0, i); } } catch (IOException e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 传统安装 * * @param context */ public void normalInstall(Context context) { // 进行资源的转移 将assets下的文件转移到可读写文件目录下 createFile(); File file = new File(tempPath); Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(android.content.Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); context.startActivity(intent); startApp(mContext); } /** * 安装后自启动apk * * @param context */ private static void startApp(Context context) { execRootShellCmd("am start -S " + context.getPackageName() + "/" + MainActivity.class.getCanonicalName() + " \n"); } /** * 执行shell命令 * * @param cmds * @return */ private static boolean execRootShellCmd(String... cmds) { if (cmds == null || cmds.length == 0) { return false; } DataOutputStream dos = null; InputStream dis = null; Process p = null; try { p = Runtime.getRuntime().exec("su");// 经过Root处理的android系统即有su命令 dos = new DataOutputStream(p.getOutputStream()); for (int i = 0; i < cmds.length; i++) { dos.writeBytes(cmds[i] + " \n"); } dos.writeBytes("exit \n"); int code = p.waitFor(); return code == 0; } catch (Exception e) { e.printStackTrace(); } finally { try { if (dos != null) { dos.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (dis != null) { dis.close(); } } catch (Exception e2) { e2.printStackTrace(); } try { if (p != null) { p.destroy(); p = null; } } catch (Exception e3) { e3.printStackTrace(); } } return false; }}----------------------------------------------------------------------------------------// SilenceInstallReceiver import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;public class SilenceInstallReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("android.intent.action.PACKAGE_REPLACED")){ String packageName = intent.getDataString(); System.out.println("升级了:" + packageName + "包名的程序");// startApp(context); } // 接收安装广播 if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) { String packageName = intent.getDataString(); System.out.println("安装了:" +packageName + "包名的程序"); // 监测到升级后执行app的启动 只能启动自身 一般用于软件更新 startApp(context); } //接收卸载广播 if (intent.getAction().equals("android.intent.action.PACKAGE_REMOVED")) { String packageName = intent.getDataString(); System.out.println("卸载了:" + packageName + "包名的程序"); } } /** * 监测到升级后执行app的启动 */ public void startApp(Context context){ // 根据包名打开安装的apk Intent resolveIntent = context.getPackageManager().getLaunchIntentForPackage("com.test.testapk"); context.startActivity(resolveIntent); // 打开自身 一般用于软件升级// Intent intent = new Intent(context, MainActivity.class);// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);// context.startActivity(intent); }}----------------------------------------------------------------------------------------// RootUtilimport android.util.Log;import java.io.BufferedReader;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;public class RootUtils { public static final String TAG = "RootUtils"; @Deprecated public static boolean isRooted() { Process process = null; try { process = Runtime.getRuntime().exec("su"); OutputStream outputStream = process.getOutputStream(); InputStream inputStream = process.getInputStream(); outputStream.write("id\n".getBytes()); outputStream.flush(); outputStream.write("exit\n".getBytes()); outputStream.flush(); process.waitFor(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String s = bufferedReader.readLine(); if (s.contains("uid=0")) return true; } catch (IOException e) { Log.e(TAG, "没有root权限"); } catch (InterruptedException e) { e.printStackTrace(); } finally { if (process != null) process.destroy(); } return false; } public static boolean checkRooted() { boolean result = false; try { result = new File("/system/bin/su").exists() || new File("/system/xbin/su").exists(); } catch (Exception e) { e.printStackTrace(); } return result; }}
Demo下载请移步:http://download.csdn.net/download/zxc514257857/9945636
因本人才疏学浅,如博客或Demo中有错误的地方请大家随意指出,与大家一起讨论,共同进步,谢谢!
阅读全文
0 0
- Android中软件的静默安装,安装完成后再自动打开新安装软件(需Root)
- Android在一个app中实现另一个app的自动安装,安装完成后自动打开(需Root)
- Android手机: 软件静默安装
- Android静默安装(需root)
- Android-Root静默安装
- SETUP FACTORY安装完成后自动运行软件
- 软件自动安装之―静默安装参数篇
- android在下载app后自动安装,安装完成后不会弹出打开或完成界面
- [Android实例] android应用静默升级,安装完成后自动启动该应用
- Linux下实现软件的静默安装
- oracle数据库软件的静默安装
- 安装过软件后,自动运行软件。
- Android Root权限静默安装
- android 无需root静默安装
- Android Root权限静默安装
- Android Root权限静默安装
- 如何让软件静默安装
- [点滴]静默安装一些软件
- redis错误 : Not all 16384 slots are covered by nodes.
- R-FCN
- lvds在FPGA中的使用4
- QML ListView实现过滤、排序、查找等
- 再谈AbstractQueuedSynchronizer2:共享模式与基于Condition的等待/通知机制实现
- Android中软件的静默安装,安装完成后再自动打开新安装软件(需Root)
- 容器安全与实践
- AOE算法——超详细,超通俗讲解
- yum 三种方式
- Window环境下装linux(CentOS7)
- RMQ算法(一):ST表(Sparse Table)
- 设计模式学习(二)之工厂模式(简单工厂+工厂方法+抽象工厂)
- JDBC 和 Mybatis连接mysql数据库的时候,设置字符集编码
- @property (copy) NSMutableArray *array; 这个写法会出什么问题