android 自动安装apk 权限,本文主要介绍程序如何利用root权限静默安装APK,如何自动选择普通安装还是静默安装以及扩展PackageUtils实现静默删除APK。...

本文主要介绍程序如何利用root权限静默安装(卸载)APK,如何自动选择普通安装(卸载)还是静默安装(卸载)。

1、root权限静默安装(卸载)调用

该函数返回PackageUtils.INSTALL_SUCCEEDED表示安装成功,失败则返回相应错误码,可以得到失败的详细原因,包括文件不存在,apk无效,系统内存不足,签名不正确,缺少公共库,share user错误等等判断。

注意对于较大apk安装过程非常耗时,所以最好新启线程去调用PackageUtils.installSlient。

2、root权限静默安装实现

PackageUtils.installSlient的实现实际使用的是su pm install -r filePath命令。核心代码如下:

PackageUtils.installSlient的实现代码

Java

public static final String COMMAND_SU = "su";

public static final String COMMAND_SH = "sh";

public static final String COMMAND_EXIT = "exit\n";

public static final String COMMAND_LINE_END = "\n";

public static CommandResult execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg) {

int result = -1;

if (commands == null || commands.length == 0) {

return new CommandResult(result, null, null);

}

Process process = null;

BufferedReader successResult = null;

BufferedReader errorResult = null;

StringBuilder successMsg = null;

StringBuilder errorMsg = null;

DataOutputStream os = null;

try {

process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);

os = new DataOutputStream(process.getOutputStream());

for (String command : commands) {

if (command == null) {

continue;

}

// donnot use os.writeBytes(commmand), avoid chinese charset error

os.write(command.getBytes());

os.writeBytes(COMMAND_LINE_END);

os.flush();

}

os.writeBytes(COMMAND_EXIT);

os.flush();

result = process.waitFor();

// get command result

if (isNeedResultMsg) {

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 (IOException e) {

e.printStackTrace();

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

if (os != null) {

os.close();

}

if (successResult != null) {

successResult.close();

}

if (errorResult != null) {

errorResult.close();

}

} catch (IOException e) {

e.printStackTrace();

}

if (process != null) {

process.destroy();

}

}

return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null

: errorMsg.toString());

}

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

publicstaticfinalStringCOMMAND_SU="su";

publicstaticfinalStringCOMMAND_SH="sh";

publicstaticfinalStringCOMMAND_EXIT="exit\n";

publicstaticfinalStringCOMMAND_LINE_END="\n";

publicstaticCommandResultexecCommand(String[]commands,booleanisRoot,booleanisNeedResultMsg){

intresult=-1;

if(commands==null||commands.length==0){

returnnewCommandResult(result,null,null);

}

Processprocess=null;

BufferedReadersuccessResult=null;

BufferedReadererrorResult=null;

StringBuildersuccessMsg=null;

StringBuildererrorMsg=null;

DataOutputStreamos=null;

try{

process=Runtime.getRuntime().exec(isRoot?COMMAND_SU:COMMAND_SH);

os=newDataOutputStream(process.getOutputStream());

for(Stringcommand:commands){

if(command==null){

continue;

}

// donnot use os.writeBytes(commmand), avoid chinese charset error

os.write(command.getBytes());

os.writeBytes(COMMAND_LINE_END);

os.flush();

}

os.writeBytes(COMMAND_EXIT);

os.flush();

result=process.waitFor();

// get command result

if(isNeedResultMsg){

successMsg=newStringBuilder();

errorMsg=newStringBuilder();

successResult=newBufferedReader(newInputStreamReader(process.getInputStream()));

errorResult=newBufferedReader(newInputStreamReader(process.getErrorStream()));

Strings;

while((s=successResult.readLine())!=null){

successMsg.append(s);

}

while((s=errorResult.readLine())!=null){

errorMsg.append(s);

}

}

}catch(IOExceptione){

e.printStackTrace();

}catch(Exceptione){

e.printStackTrace();

}finally{

try{

if(os!=null){

os.close();

}

if(successResult!=null){

successResult.close();

}

if(errorResult!=null){

errorResult.close();

}

}catch(IOExceptione){

e.printStackTrace();

}

if(process!=null){

process.destroy();

}

}

returnnewCommandResult(result,successMsg==null?null:successMsg.toString(),errorMsg==null?null

:errorMsg.toString());

}

其中commands为pm install -r . 从中可以看出主要就是使用su切换到root环境下,再调用pm install -r进行安装。

3、普通安装,系统权限静默安装,root权限静默安装的自动选择

查看PackageUtils源码会发现我还提供了其他几个安装函数,其中PackageUtils.install(PackageUtils.uninstall)函数会根据是否是系统应用以及是否拥有root权限,从而确定调用哪种安装方式(普通安装方式、root静默安装方式还是系统权限静默安装),源码如下:

Java

/**

* install according conditions

*

*

if system application or rooted, see {@link #installSilent(Context, String)}

*

else see {@link #installNormal(Context, String)}

*

*

* @param context

* @param filePath

* @return

*/

public static final int install(Context context, String filePath) {

if (!PackageUtils.isSystemApplication(context) && !ShellUtils.checkRootPermission()) {

return installNormal(context, filePath) ? INSTALL_SUCCEEDED : INSTALL_FAILED_INVALID_URI;

}

return installSilent(context, filePath);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

/**

* install according conditions

*

*

if system application or rooted, see {@link #installSilent(Context, String)}

*

else see {@link #installNormal(Context, String)}

*

*

* @param context

* @param filePath

* @return

*/

publicstaticfinalintinstall(Contextcontext,StringfilePath){

if(!PackageUtils.isSystemApplication(context)&&!ShellUtils.checkRootPermission()){

returninstallNormal(context,filePath)?INSTALL_SUCCEEDED:INSTALL_FAILED_INVALID_URI;

}

returninstallSilent(context,filePath);

}

如果是系统应用记得添加权限,从而走普通安装方式,不用申请root权限进行静默安装。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值