Android apk的安装、卸载

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

               Android apk的安装、卸载、更新升级(通过Eclipse实现静默安装)
发表于2年前(2013-04-06 20:55)   阅读( 10840) | 评论( 3554人收藏此文章, 我要收藏
赞9

7.16,杭州,阿里巴巴。阿里百川无线开放大会报名开启,用技术驱动无线新商业


一、通过Intent消息机制发送消息,调用系统应用进行,实现apk的安装/卸载    
(1)  调用系统的安装应用,让系统自动进行apk的安装  
?
1
2
3
4
5
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 
?
1
2
3
4
5
6
//通过程序的包名创建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方法修改权限之后再进行升级是可以成功的。

?
1
2
3
4
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
 * 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(修改过的马甲)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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(修改过的马甲)
?
1
2
3
4
5
6
7
8
9
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)马甲准备好之后,就开始实现我们的操作逻辑。
    实现静默安装/卸载的方法,并且注册回调(无论失败成功都会返回对应值)   
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//静默安装
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{
    @Override
    public void packageDeleted(String packageName, int returnCode) {
        // TODO Auto-generated method stub
        Log.d(TAG, "returnCode = "+returnCode);//返回1代表卸载成功
    }
 
}
//静默安装回调
private static class MyPakcageInstallObserver extends IPackageInstallObserver.Stub{
    @Override
    public void packageInstalled(String packageName, int returnCode)
            throws RemoteException {
        // TODO Auto-generated method stub
         Log.i(TAG, "returnCode = " + returnCode);//返回1代表安装成功 
    }
}
    3)主要的逻辑实现之后,在AndroidManifest.xml 添加安装和卸载的权限
?
1
2
<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目录)
?
1
2
3
java -jar  signapk.jar  platform.x509.pem  platform.pk8 FileUpdateControl.apk 1.apk
adb uninstall com.zlc.ipanel.operate
adb  install 1.apk
    5)当下载到系统里面的apk权限不够时(静默安装提示权限问题, 有可能当前apk只有(-rw-------)权限
    可以使用下面三种方式修改权限

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

?
1
2
3
4
5
6
try {
            Runtime.getRuntime().exec("chmod 777 " + file.getCanonicalPath());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.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的安装和卸载 
    1execCommand("pm", "install", "-f", filePath);//安装apk,filePath为apk文件路径,如/sdcard/operate.apk

    2execCommand("pm", "uninstall", packageName);//卸载apk,packageName为包名,如com.zlc.ipanel
Android PackageManagerService 总结(一)应用市场下载安装apk流程 前言: 本篇文章是对系统包安装流程的总结,基于Android12 上 com.android.packageinstaller 源码的分析,第三方应用商城(华为商城,小米商城,应用宝,豌豆荚,酷安等)下载安装应 用,在普通安装和静默安装app两种方式下,对代码流程的梳理和讲解。 触发安装: 当你在商城界面中点击安装按钮,应用会自动下载,下载完成后就会调起系统安装应用的界面,此种触发方式一般是通过Intent 隐式调用的,我们先阅读如下代码: ...... 阅读详情

相关推荐

解决Android在更新安装包时出现“未安装应用”的情况

解决Android在更新安装包时出现“未安装应用”的情况

海阔天空 1万+

apk安装流程

android系统启动之后调用PackageManagerService服务并解析系统特定目录,解析apk文件并安装的过程,这个安装过程实际上是没有图形界面的,底层调用的是我们平时比较熟悉的adb命令,那么我们平时安装apk文件的时候大部分是都过图形界面安装的,那么这种方式安装apk具体的流程是怎样的呢? 本文我们就来具体看一下apk的具体安装过程,通过本文的学习希望帮助大家大概的了解到Android系统安装Apk文件的基本流程。 相信大家都知道如果我们想在代码里执行apk安装,那么一般都是这样: Int

weixin_42904469的博客 1万+

Win11安卓子系统怎么安装卸载安卓APK

微软发布了最新版的Win11测试版,最大的亮点是支持安卓子系统,目前Windows11上的安卓子系统还处在测试阶段,仅适合尝鲜的朋友们。一些朋友在使用后发现无论流畅度和稳定性方面还是不错的,不过也有反馈说老机型有闪屏和闪退的情况,下面为大家带来安卓子系统怎么安装卸载安卓APP的教程。3、比如安装 D:\ZD\Download 目录下的QQ安装包,只需要这么输入。后面的地址,就是刚刚在安卓子系统设置界面显示的那个地址。按下回车键就开始安装了,稍等片刻会显示安装成功。4、打开开始界面,即可看到刚刚安装的。

shengyin714959的博客 1678

application/vnd.android.package-archive到底是什么

在拜读组里北大研二的安卓代码的时候, 读到登录前检测版本后更新的代码。发现了一个不懂的地方。 void update() { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(new File(Environment .getExternalStorageDi

大三狗现在才努力还不算晚吧?! 1万+

apk安装法之三--"application/vnd.android.package-archive"是什么?

转载自:http://blog.csdn.net/heikefangxian23/article/details/38582261 apk安装法之三--"application/vnd.android.package-archive"是什么? 在第二篇中讲明了调用 [java] view plain copy

lv18092081172的博客 5331

Android静默安装卸载APK的代码实现

转载:添加链接描述 1.前言    在实际的终端设备开发中,为保证设备的正常运行,通常会同时运行两个APK,一个用于客户端交互的主APK,另一个是用于监护主APK的辅助APK。    在市面上常见的安卓APK中,为保证该设

明耀的博客 1222

android APK 软件的安装卸载

android APK 软件的安装卸载:   public class ApkInstallUtils { /***      * 安装apk文件,例如  install_apk_withName(this, "test.apk");      * @param context 上下文      * @param fileName 文

浩宇碧海 1366

Android平台静默APK安装卸载实战指南

AIDL(Android Interface Definition Language)是一种接口定义语言,它允许在Android系统中跨越不同进程边界进行通信。AIDL允许你定义多个进程之间进行交互时需要遵守的接口协议。其作用是将客户端和服务端的接口定义标准化,从而使得服务端可以接收来自不同应用的调用请求。// 文件路径:src/main/aidl/com/example/myapplication/IMyAidlInterface.aidl/***/

weixin_35749796的博客 964

如何在Android模拟器上安装卸载APK

<br />玩过了一天Android模拟器,也写了几个小测试程序。突然有个问题出现,如果脱离Eclipse开发环境,如何能将APK包部署给模拟器呢? <br />研究了一下模拟器的内存文件系统,似乎没什么发现,是一个Linux内核。 <br />于是到google问问老外们,终于知道了,吼吼。 <br /><br />【安装APK】 <br />安装APK当然首先是要有模拟器,和要安装APK包,这个不多废话了。直接切入正题,在模拟器安装APK。 <br />首先,将模拟器执行起来,直到正式进入系统。 <b

qikaibinglan的专栏 1007

Android APK安装卸载机制

本文主要介绍Android系统如何实现APK安装卸载、更新等操作。主要内容包括以下内容: 安装卸载APK的方法有哪些,每种方法实现的原理是什么?APK安装卸载过程中,系统数据发生了哪些变化?Android App端常用的Package Manager使用方法简介。 注:本文是在本人阅读、、以及网络中关于Android安装方式的基础上完成的。本人的主要工作在于阅读相关部分的Andr

Jenney_TEN的博客 1万+

adb 安装apk_安卓逆向——APK安装流程

制丨文生整理丨阿星很多学习安卓逆向的朋友大多都会卡在安卓apk上,今天小生就来给大家讲解一下,安装apk的流程,希望能帮助到大家。安装方式:⑴系统程序安装⑵通过Android市场安装⑶手机自带安装⑷使用ADB安装这里出现了一个新名词ADB,它是什么?有什么作用呢?我们一起来去了解一下。ADB的全称为Android Debug Bridge,字面意思就是安卓调试桥接,简单点说,它是Andr...

weixin_29494379的博客 852

Android 安装程序(APK)后并启动程序(APK) 安装 卸载

Android 安装程序(APK)后并启动程序(APK) 安装 卸载

随意而然的专栏 3436

Android教程之如何安装(卸载)apk文件到模拟器

本文是从我的其他博客转载过来的!主要是看在这里对代码很好排版,所以准备搬到这里来,这也是第一篇文章,来测试一下! ——————————首先安装————————一:首先需要启动模拟器二:start -> 运行 ->CMD三:进入andoridsdk下面的tools目录四:adb install c:/*.apk(说明:“c:/*.apk”是要安装的文件的路径) 这样就安装成功了!

LightSun----让成功成为可能! 2306

安卓监听apk安装卸载

1、创建广播类,继承BroadcastReceiver public class PackageBroadCastReceiver extends BroadcastReceiver {   private static final int PACKAGE_NAME_START_INDEX = 8;  @Override  public void onReceive(Context co

酒比花香的专栏 1010

android 安装/卸载apk

1. 卸载: Uri packageURI = Uri.parse("程序完整的路径"); Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI); startActivity(uninstallIntent); 2. 安装: String str = "apk的完整路径"; In

助你打造统一的店铺音乐形象 1019

Android模拟器中APK文件的安装卸载方法

 Android模拟器中安装卸载APK文件 在开发Android应用软件过程中,除了可以在开发环境中直接运行或调试代码,还可以将开发完成及打包好的并准备即将发布的APK文件安装Android模拟器中运行测试。 将APK文件安装到模拟器中的方法如下: 1. 运行android的仿真器(通过手动方式在WINDOWS命令行下运行,或直接利用开发环境中启动运行好的模拟器)  

Shaohuicheng的专栏 2236

Android 使用pm命令安装卸载apk

Android 使用pm命令安装卸载apk

weixin_42602900的博客 1544
上一篇: ProguardGui进行jar包代码混淆
下一篇: [Android]应用语言切换的三种方法
Azhuoyanyan
博客等级 码龄15年 2粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值