一、通过Intent消息机制发送消息,调用系统应用进行,实现apk的安装/卸载
(1) 调用系统的安装应用,让系统自动进行apk的安装
String fileName = "/data/data/com.zlc.ipanel.operate/FileOperate.apk";Uri uri = Uri.fromFile(new File(fileName));Intent intent = new Intent(Intent.ACTION_VIEW);intent.setDataAndType(uri, "application/vnd.android.package-archive");startActivity(intent);
上诉安装不仅可以安装新的apk(从无到有),也可以用于更新旧的apk(版本更新),在进行版本更新的时候,必须保证两个apk的签名是一致的。
如果是一般应用,安装到data/分区下面,新的apk会替换旧的apk。
如果是系统应用,一般安装到system/app下面,更新之后, system/app/下的旧apk仍然存在,系统会将新的apk被复制到data/app下。虽然同时存在两新旧apk,但运行时系统选择data分区的新apk运行, 如果执行卸载则是删除data分区的apk,再次启动程序运行的是system目录下旧的apk。
(2)启动系统的卸载应用,让系统自动卸载apk
//通过程序的包名创建URI Uri packageURI = Uri.parse("package:com.zlc.ipanel"); //创建Intent意图 Intent intent = new Intent(Intent.ACTION_DELETE,packageURI); //执行卸载程序 startActivity(intent);

与apk安装不同的是,Intent消息这里改了:ACTION_DELETE,apk安装使用的是(ACTION_VIEW)

二、通过调用系统提供的接口packageManager对apk进行卸载、安装、获取权限等(静默安装)
(1)需要平台签名(写个Android.mk在源码下编译最省事,当然网上也有很多其他方法,比如:singapk命令行签名
(2)由于调用的是未公开的API,所以需要引入源码(仅仅做一个马甲,不参与编译)
(3)在AndroidManifest.xml添加安装apk的权限
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
(4)如果升级失败出现Unable to open zip '/data/FileOperate.apk': Permission denied,说明是权限不够,有可能当前apk只有(-rw-------)权限,通过Runtime.exec方法修改权限之后再进行升级是可以成功的。

PackageManager pm = this.getPackageManager();File file = new File("/data/data/com.zlc.ipanel.operate/FileOperate.apk");pm.installPackage(Uri.fromFile(file), null,PackageManager.INSTALL_REPLACE_EXISTING, "com.zlc.ipanel");

(5)下面举一个例子通过Eclipse来实现静默安装/卸载
1)按照我们上面讲的静默安装需求一步步实现我们的操作。首先准备马甲(静默安装需要调用的接口)
由于调用了系统未公开的接口,而这些接口有些是通过aidl实现的,下面我们把需要的马甲修改一下。
PackageManager.java

/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package android.content.pm;import android.content.Context;import android.net.Uri;/** * Class for retrieving various kinds of information related to the application * packages that are currently installed on the device. * * You can find this class through {@link Context#getPackageManager}. */public abstract class PackageManager {    /**     * Flag parameter for {@link #installPackage} to indicate that you want to replace an already     * installed package, if one exists.     * @hide     */    public static final int INSTALL_REPLACE_EXISTING = 0x00000002;    /**     * @hide     *     * Install a package. Since this may take a little while, the result will     * be posted back to the given observer.  An installation will fail if the calling context     * lacks the {@link android.Manifest.permission#INSTALL_PACKAGES} permission, if the     * package named in the package file's manifest is already installed, or if there's no space     * available on the device.     *     * @param packageURI The location of the package file to install.  This can be a 'file:' or a     * 'content:' URI.     * @param observer An observer callback to get notified when the package installation is     * complete. {@link IPackageInstallObserver#packageInstalled(String, int)} will be     * called when that happens.  observer may be null to indicate that no callback is desired.     * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},     * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.     * @param installerPackageName Optional package name of the application that is performing the     * installation. This identifies which market the package came from.     */    public abstract void installPackage(            Uri packageURI, IPackageInstallObserver observer, int flags,            String installerPackageName);    /**     * Attempts to delete a package.  Since this may take a little while, the result will     * be posted back to the given observer.  A deletion will fail if the calling context     * lacks the {@link android.Manifest.permission#DELETE_PACKAGES} permission, if the     * named package cannot be found, or if the named package is a "system package".     * (TODO: include pointer to documentation on "system packages")     *     * @param packageName The name of the package to delete     * @param observer An observer callback to get notified when the package deletion is     * complete. {@link android.content.pm.IPackageDeleteObserver#packageDeleted(boolean)} will be     * called when that happens.  observer may be null to indicate that no callback is desired.     * @param flags - possible values: {@link #DONT_DELETE_DATA}     *     * @hide     */    public abstract void deletePackage(            String packageName, IPackageDeleteObserver observer, int flags);  }

安装成功的回调接口IPackageInstallObserver.java(修改过的马甲)

package android.content.pm;import android.os.RemoteException;public interface IPackageInstallObserver {public class Stub implements IPackageInstallObserver{public void packageInstalled(String packageName, int returnCode)throws RemoteException {// TODO Auto-generated method stub}}}
卸载成功的回调接口IPackageDeleteObserver.java(修改过的马甲)
package android.content.pm;public interface IPackageDeleteObserver {public class Stub implements IPackageDeleteObserver{public void packageDeleted(String packageName, int returnCode) {// TODO Auto-generated method stub}}}
2)马甲准备好之后,就开始实现我们的操作逻辑。
实现静默安装/卸载的方法,并且注册回调(无论失败成功都会返回对应值)
//静默安装public static void installApkDefaul(Context context,String fileName,String pakcageName){Log.d(TAG, "jing mo an zhuang");File file = new File(fileName);int installFlags = 0;if(!file.exists())return;Log.d(TAG, "jing mo an zhuang  out");installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;  PackageManager pm = context.getPackageManager();IPackageInstallObserver observer = new MyPakcageInstallObserver(); pm.installPackage(Uri.fromFile(file), observer, installFlags, pakcageName);}//静默卸载public static void uninstallApkDefaul(Context context,String packageName){PackageManager pm = context.getPackageManager();IPackageDeleteObserver observer = new MyPackageDeleteObserver();        pm.deletePackage(packageName, observer, 0);}//静默卸载回调private static class MyPackageDeleteObserver extends IPackageDeleteObserver.Stub{@Overridepublic void packageDeleted(String packageName, int returnCode) {// TODO Auto-generated method stubLog.d(TAG, "returnCode = "+returnCode);//返回1代表卸载成功}}//静默安装回调private static class MyPakcageInstallObserver extends IPackageInstallObserver.Stub{@Overridepublic void packageInstalled(String packageName, int returnCode)throws RemoteException {// TODO Auto-generated method stub     Log.i(TAG, "returnCode = " + returnCode);//返回1代表安装成功  }}
3)主要的逻辑实现之后,在AndroidManifest.xml 添加安装和卸载的权限
<uses-permission android:name="android.permission.INSTALL_PACKAGES" /><uses-permission android:name="android.permission.DELETE_PACKAGES" />
4)运行Eclipse,生成该应用的apk,下面就要进行系统签名了。写一个脚本来来实现替换成系统签名
使用签名包签名首先我们要去源码里面取出下面这几个文件platform.x509.pem、platform.pk8、signapk.jar

脚本1.bat 和生成的apk以及上面三个文件放到同一个目录下面,一般为工程下面的bin目录)
java -jar  signapk.jar  platform.x509.pem  platform.pk8 FileUpdateControl.apk 1.apkadb uninstall com.zlc.ipanel.operateadb  install 1.apk
5)当下载到系统里面的apk权限不够时(静默安装提示权限问题, 有可能当前apk只有(-rw-------)权限
可以使用下面三种方式修改权限

1.使用Runtime来启动一个线程修改权限

try {Runtime.getRuntime().exec("chmod 777 " + file.getCanonicalPath());} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}

2.写一个native接口直接通过jni调用c的接口修改权限。
3.使用FileUtils,这个类默认是隐藏的,官方sdk中不包含这个类,所以代码如果要使用这个类,需要将工程放到android源码中编译
FileUtils.setPermissions(f.getAbsolutePath(), FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IROTH, -1, -1) ;

三、其他apk安装的方法

(1)通过cmd窗口 adb 命令,install / uninstall apk。
(2)cp apk 到 system/app目录下,系统会自动安装
(3)直接通过代码调用pm命令执行apk的安装和卸载
1 execCommand("pm","install","-f", filePath);//安装apk,filePath为apk文件路径,如/sdcard/operate.apk

2 execCommand("pm","uninstall", packageName);//卸载apk,packageName为包名,如com.zlc.ipanel

静默安装依赖源码包下载

更多相关文章

  1. Pycharm安装PyQt5的详细教程
  2. Android(安卓)环境搭建
  3. Android(安卓)给 app默认权限(不弹窗申请权限)
  4. 第一章 andriod studio 安装与环境搭建
  5. Android,一个思路实现APP版本更新
  6. android插件汇总
  7. Android(安卓)RabbitMQ使用之RabbitMQ安装及配置
  8. ubuntu NDK 的安装
  9. android获取经纬度和地方名称

随机推荐

  1. Linux Kernel and Android(安卓)休眠与唤
  2. 浅析 Android(安卓)的窗口
  3. 学习android(1)
  4. Android(安卓)NDK开发(一)——ndk-build
  5. Android下怎么使用LDD查看依赖库
  6. Android(安卓)UI开发专题(一) 之界面设计
  7. Android中的横竖屏
  8. 我对谷歌的chromium和android发展的看法
  9. Android智能指针SP WP使用方法介绍
  10. 想做android开发工程师?这些技能都要具备