ronnie
2022-10-23 eadd9db01b24ccde96a129dafa989d4ec436cdfd
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//调用方法为:
//InstallUtils.install28(MainActivity.this,"/data/local/tmp/test.apk",InstallResultReceiver.class)
 
//需系统签名和添加以下权限
//<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
//<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 
package com.android.settings;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInstaller;
import android.util.Log;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
 
 
public class InstallUtils {
    private static final String TAG = "myLog";
 
    // 适配android9的安装方法。
    public static void install28(Context context, String apkFilePath,Class<InstallResultReceiver> receiver) {
 
        Log.d(TAG,"install28 path="+apkFilePath);
 
        File apkFile = new File(apkFilePath);
 
        PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
 
        PackageInstaller.SessionParams sessionParams
                = new PackageInstaller.SessionParams(PackageInstaller
                .SessionParams.MODE_FULL_INSTALL);
 
        sessionParams.setSize(apkFile.length());
        int sessionId = createSession(packageInstaller, sessionParams);
 
        Log.d(TAG,"install28  sessionId="+sessionId);
 
        if (sessionId != -1) {
            boolean copySuccess = copyInstallFile(packageInstaller, sessionId, apkFilePath);
            Log.d(TAG,"install28  copySuccess="+copySuccess);
            if (copySuccess) {
                execInstallCommand(context,packageInstaller, sessionId,receiver);
            }
        }
    }
 
    private static int createSession(PackageInstaller packageInstaller,
                                    PackageInstaller.SessionParams sessionParams) {
 
        int sessionId = -1;
 
        try {
            sessionId = packageInstaller.createSession(sessionParams);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sessionId;
    }
 
    private static boolean copyInstallFile(PackageInstaller packageInstaller,int sessionId, String apkFilePath) {
 
        InputStream in = null;
        OutputStream out = null;
        PackageInstaller.Session session = null;
        boolean success = false;
 
        try {
 
            File apkFile = new File(apkFilePath);
            session = packageInstaller.openSession(sessionId);
            out = session.openWrite("base.apk", 0, apkFile.length());
            in = new FileInputStream(apkFile);
 
            int total = 0, c;
            byte[] buffer = new byte[65536];
            while ((c = in.read(buffer)) != -1) {
                total += c;
                out.write(buffer, 0, c);
            }
 
            session.fsync(out);
            Log.i(TAG, "streamed " + total + " bytes");
            success = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
 
            try {
                if (out!=null){
                    out.close();
                }
 
                if (in!=null){
                    in.close();
                }
 
                if (session!=null){
                    session.close();
                }
 
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
 
        return success;
    }
 
 
    private static void execInstallCommand(Context context, PackageInstaller packageInstaller, int sessionId, Class<InstallResultReceiver> receiver) {
 
        PackageInstaller.Session session = null;
        try {
            session = packageInstaller.openSession(sessionId);
            Intent intent = new Intent(context, receiver);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
                    1, intent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
 
            session.commit(pendingIntent.getIntentSender());
 
            Log.i(TAG, "begin session");
 
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
}