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

前段时间做了一个批量安装卸载应用程序的小应用,由于安装卸载应用程序的部分API是隐藏的,所以必须在ubuntu下下载Android系统源码,并编译之后使用MM命令编译生成APK文件,其实也难。

思路是这样的,在XX/packages/apps目录下有一个PackageInstaller的应用程序,Android机器中安装卸载都是由这个应用程序完成的。但是它没有批量安装和卸载的功能,如果要在自己的应用程序中添加批量安装和卸载的功能,其实很简单,只需要参考PakcageInstaller里面的安装卸载代码加个循环就可以了。但值得注意的是在编译的过程中必须复制PackageInstaller里面的Android.mk文件,修改文件为工程目录名。
好了,废话不再多说,下面是关键代码
1、 Android.mk文件


代码如下:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-subdir-java-files)

LOCAL_PACKAGE_NAME := PackageInstaller
LOCAL_CERTIFICATE := platform

include $(BUILD_PACKAGE)

代码如下:

LOCAL_PATH:= $(call my-dir) 
    include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-subdir-java-files)

LOCAL_PACKAGE_NAME := PackageInstaller 
    LOCAL_CERTIFICATE := platform

include $(BUILD_PACKAGE)

2、PakcageInstaller.java文件(关键代码)


代码如下:

package cn.ceadic.apkmgr;

import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;

import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageInfo;
    import android.content.pm.PackageManager;
    import android.content.pm.PackageManager.NameNotFoundException;
    import android.net.Uri;
    import android.util.Log;

import android.content.pm.IPackageInstallObserver;
    import android.content.pm.IPackageDeleteObserver;
    import android.os.FileUtils;

public class PackageInstaller {

private File mTmpFile;
        private final String TMP_FILE_NAME = "tmpCopy.apk";

private final static String TAG = "PackInstaller";
        private Context mContext;

public PackageInstaller(Context context) {
            mContext = context;
        }

public void install(String path,String packageName){
             Intent intent = new Intent(Intent.ACTION_VIEW);
             intent.setDataAndType(Uri.fromFile(new File(path)),
             "application/vnd.android.package-archive");
             mContext.startActivity(intent);
        }

public void instatllBatch(String path, String packageName) {

Log.i(TAG, "path=" + path);
            int installFlags = 0;
            PackageManager pm = mContext.getPackageManager();
            try {
                PackageInfo pi = pm.getPackageInfo(packageName,
                        PackageManager.GET_UNINSTALLED_PACKAGES);
                if (pi != null) {
                    installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
                }
            } catch (NameNotFoundException e) {
            }
            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
                Log.w(TAG, "Replacing package:" + packageName);
            }

// Create temp file before invoking install api
            mTmpFile = createTempPackageFile(path);
            if (mTmpFile == null) {
                // Message msg = mHandler.obtainMessage(INSTALL_COMPLETE);
                // msg.arg1 = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
                // mHandler.sendMessage(msg);
                return;
            }
            Uri mPackageURI = Uri.parse("file://" + mTmpFile.getPath());
            String installerPackageName = mContext.getIntent().getStringExtra(
                    Intent.EXTRA_INSTALLER_PACKAGE_NAME);

PackageInstallObserver observer = new PackageInstallObserver();
            pm.installPackage(mPackageURI, observer, installFlags,
                    installerPackageName);
        }

private File createTempPackageFile(String filePath) {
            File tmpPackageFile = mContext.getFileStreamPath(TMP_FILE_NAME);
            if (tmpPackageFile == null) {
                Log.w(TAG, "Failed to create temp file");
                return null;
            }
            if (tmpPackageFile.exists()) {
                tmpPackageFile.delete();
            }
            // Open file to make it world readable
            FileOutputStream fos;
            try {
                fos = openFileOutput(TMP_FILE_NAME, MODE_WORLD_READABLE);
            } catch (FileNotFoundException e1) {
                Log.e(TAG, "Error opening file " + TMP_FILE_NAME);
                return null;
            }
            try {
                fos.close();
            } catch (IOException e) {
                Log.e(TAG, "Error opening file " + TMP_FILE_NAME);
                return null;
            }

File srcPackageFile = new File(filePath);
            if (!FileUtils.copyFile(srcPackageFile, tmpPackageFile)) {
                Log.w(TAG, "Failed to make copy of file: " + srcPackageFile);
                return null;
            }
            return tmpPackageFile;
        }

private class PackageInstallObserver extends IPackageInstallObserver.Stub {
            public void packageInstalled(String packageName, int returnCode) {
                // Message msg = mHandler.obtainMessage(INSTALL_COMPLETE);
                // msg.arg1 = returnCode;
                // mHandler.sendMessage(msg);
                Log.i(TAG, "====INSTALL_COMPLETE");
            }
        }

private class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
            public void packageDeleted(boolean succeeded) {
    //            Message msg = mHandler.obtainMessage(UNINSTALL_COMPLETE);
    //            msg.arg1 = succeeded?SUCCEEDED:FAILED;
    //            mHandler.sendMessage(msg);
                Log.i(TAG, "====UNINSTALL_COMPLETE");
            }
        }

public void uninstall(String packageName){
            Uri packageURI = Uri.parse("package:" + packageName);
            Intent uninstallIntent = new Intent(Intent.ACTION_DELETE,
            packageURI);
            mContext.startActivity(uninstallIntent);
        }

public void uninstallBatch(String packageName) {
            PackageDeleteObserver observer = new PackageDeleteObserver();
            mContext.getPackageManager().deletePackage(packageName, observer, 0);

}
    }

代码如下:

package cn.ceadic.apkmgr;

import java.io.File; 
    import java.io.FileNotFoundException; 
    import java.io.FileOutputStream; 
    import java.io.IOException;

import android.content.Context; 
    import android.content.Intent; 
    import android.content.pm.PackageInfo; 
    import android.content.pm.PackageManager; 
    import android.content.pm.PackageManager.NameNotFoundException; 
    import android.net.Uri; 
    import android.util.Log;

import android.content.pm.IPackageInstallObserver; 
    import android.content.pm.IPackageDeleteObserver; 
    import android.os.FileUtils;

public class PackageInstaller {

private File mTmpFile; 
        private final String TMP_FILE_NAME = "tmpCopy.apk";

private final static String TAG = "PackInstaller"; 
        private Context mContext;

public PackageInstaller(Context context) { 
            mContext = context; 
        }

public void install(String path,String packageName){ 
             Intent intent = new Intent(Intent.ACTION_VIEW); 
             intent.setDataAndType(Uri.fromFile(new File(path)), 
             "application/vnd.android.package-archive"); 
             mContext.startActivity(intent); 
        }

public void instatllBatch(String path, String packageName) {

Log.i(TAG, "path=" + path); 
            int installFlags = 0; 
            PackageManager pm = mContext.getPackageManager(); 
            try { 
                PackageInfo pi = pm.getPackageInfo(packageName, 
                        PackageManager.GET_UNINSTALLED_PACKAGES); 
                if (pi != null) { 
                    installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 
                } 
            } catch (NameNotFoundException e) { 
            } 
            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 
                Log.w(TAG, "Replacing package:" + packageName); 
            }

// Create temp file before invoking install api 
            mTmpFile = createTempPackageFile(path); 
            if (mTmpFile == null) { 
                // Message msg = mHandler.obtainMessage(INSTALL_COMPLETE); 
                // msg.arg1 = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 
                // mHandler.sendMessage(msg); 
                return; 
            } 
            Uri mPackageURI = Uri.parse("file://" + mTmpFile.getPath()); 
            String installerPackageName = mContext.getIntent().getStringExtra( 
                    Intent.EXTRA_INSTALLER_PACKAGE_NAME);

PackageInstallObserver observer = new PackageInstallObserver(); 
            pm.installPackage(mPackageURI, observer, installFlags, 
                    installerPackageName); 
        }

private File createTempPackageFile(String filePath) { 
            File tmpPackageFile = mContext.getFileStreamPath(TMP_FILE_NAME); 
            if (tmpPackageFile == null) { 
                Log.w(TAG, "Failed to create temp file"); 
                return null; 
            } 
            if (tmpPackageFile.exists()) { 
                tmpPackageFile.delete(); 
            } 
            // Open file to make it world readable 
            FileOutputStream fos; 
            try { 
                fos = openFileOutput(TMP_FILE_NAME, MODE_WORLD_READABLE); 
            } catch (FileNotFoundException e1) { 
                Log.e(TAG, "Error opening file " + TMP_FILE_NAME); 
                return null; 
            } 
            try { 
                fos.close(); 
            } catch (IOException e) { 
                Log.e(TAG, "Error opening file " + TMP_FILE_NAME); 
                return null; 
            }

File srcPackageFile = new File(filePath); 
            if (!FileUtils.copyFile(srcPackageFile, tmpPackageFile)) { 
                Log.w(TAG, "Failed to make copy of file: " + srcPackageFile); 
                return null; 
            } 
            return tmpPackageFile; 
        }

private class PackageInstallObserver extends IPackageInstallObserver.Stub { 
            public void packageInstalled(String packageName, int returnCode) { 
                // Message msg = mHandler.obtainMessage(INSTALL_COMPLETE); 
                // msg.arg1 = returnCode; 
                // mHandler.sendMessage(msg); 
                Log.i(TAG, "====INSTALL_COMPLETE"); 
            } 
        }

private class PackageDeleteObserver extends IPackageDeleteObserver.Stub { 
            public void packageDeleted(boolean succeeded) { 
    //            Message msg = mHandler.obtainMessage(UNINSTALL_COMPLETE); 
    //            msg.arg1 = succeeded?SUCCEEDED:FAILED; 
    //            mHandler.sendMessage(msg); 
                Log.i(TAG, "====UNINSTALL_COMPLETE"); 
            } 
        }

public void uninstall(String packageName){ 
            Uri packageURI = Uri.parse("package:" + packageName); 
            Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, 
            packageURI); 
            mContext.startActivity(uninstallIntent); 
        }

public void uninstallBatch(String packageName) { 
            PackageDeleteObserver observer = new PackageDeleteObserver(); 
            mContext.getPackageManager().deletePackage(packageName, observer, 0);


    }

3、别忘记添加权限


代码如下:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        <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.READ_PHONE_STATE" />
        <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />

代码如下:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
        <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.READ_PHONE_STATE" /> 
        <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />

以上代码在Android2.1的SDK中编译通过,并正确批量安装卸载应用程序

(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 监听apk安装替换卸载广播的实现代码

    首先是要获取应用的安装状态,通过广播的形式以下是和应用程序相关的Broadcast ActionACTION_PACKAGE_ADDED 一个新应用包已经安装在设备上,数据包括包名(最新安装的包程序不能接收到这个广播)ACTION_PACKAGE_REPLACED 一个新版本的应用安装到设备,替换之前已经存在的版本ACTION_PACKAGE_CHANGED 一个已存在的应用程序包已经改变,包括包名ACTION_PACKAGE_REMOVED 一个已存在的应用程序包已经从设备上移除,包括包名(正

  • 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编程监听APK安装与删除等过程的方法

    本文实例讲述了Android编程监听APK安装与删除等过程的方法.分享给大家供大家参考,具体如下: 软件下载后的一系列动作监听:先前是通过Service监听扫描获取状态,以后用这个方法测试使用 import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class getBro

  • 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编程之软件的安装和卸载方法

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

  • android监听安装和卸载示例

    BroadcastReceiver 是系统全局广播监听类, 其主要方法是onReceive(),自定义的广播类继承于它并实现自己的onReceive()处理逻辑BroadcastReceiver 使用前,需要进行注册监听(xml和代码两种方式),不使用时需要注销监听,其生命周期一般为整个应用的生命周期 1, 自定义广播自定义广播MyInstalledReceiver继承自BroadcastReceiver,实现其onReceive()方式,具体代码如下: 复制代码 代码如下: public cl

  • 在Android 模拟器上安装和卸载APK包的方法

    模拟器(emulator.exe) 可以在 Android SDK 的安装目录下的 tools 文件夹找到运行文件(F:GPhoneandroid-sdk-windows-1.0_r1 ools),双击运行模拟器. 安装 APK 包 adb install [-l] [-r] - push this package file to the device and install it<'-l' means forward-lock the app><'-r' means reinstall

  • 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

  • 使用python编写批量卸载手机中安装的android应用脚本

    该脚本的功能是卸载android手机中安装的所有第三方应用,主要是使用adb shell pm.adb uninstall 命令,所以使用的前提是需要配好adb的环境变量,下面上代码: #!/usr/bin/env python import os def uninstall(): os.popen("adb wait-for-device") print "start uninstall..." for packages in os.popen("adb

随机推荐