[英]Issue installing .apk with PackageInstaller
我的目標是安裝存儲在設備上的 .apk 文件。 我嘗試使用 ACTION_VIEW 意圖,但我相信它從 Android 10 開始被棄用。
我已經搜索了 web 的一半,但大多數答案要么使用已棄用的意圖 kotlin,要么根本不起作用。
這是我的代碼
private void installApk() throws IOException {
if (!requireContext().getPackageManager().canRequestPackageInstalls()) {
startActivity(new Intent(
Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
Uri.parse("package:" + requireContext().getPackageName())));
} else {
// Log.d(TAG, "File Exists?: " + outputFile.exists() + " ; " + outputFile.getAbsolutePath() + " ; " + "can read?" + outputFile.canRead() + " ; " + "can write?" + outputFile.canWrite());
PackageInstaller packageInstaller = requireContext().getPackageManager().getPackageInstaller();
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller
.SessionParams.MODE_FULL_INSTALL);
int sessionId = packageInstaller.createSession(params);
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
addApkToInstallSession(session);
Intent callbackIntent = new Intent(requireContext(), APKInstallService.class);
PendingIntent pendingIntent = PendingIntent.getService(requireContext(), 0, callbackIntent, 0);
// This is sending the result of the installation to the APKInstallService.
IntentSender statusReceiver = pendingIntent.getIntentSender();
session.commit(statusReceiver);
}
}
這是我在 onClickListener 中調用的方法
private void addApkToInstallSession(PackageInstaller.Session session)
throws IOException {
try (OutputStream packageInSession = session.openWrite("package", 0, -1);
InputStream is = requireContext().getContentResolver().openInputStream(fileURI)) {
byte[] buffer = new byte[16384];
int n;
while ((n = is.read(buffer)) >= 0) {
packageInSession.write(buffer, 0, n);
}
}
}
將文件添加到 session。
import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageInstaller;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
public class APKInstallService extends Service {
private static final String TAG = "APKInstallService";
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999);
switch (status) {
case PackageInstaller.STATUS_PENDING_USER_ACTION:
Log.d(TAG, "Requesting user confirmation for installation");
// This is a way to get the intent that was passed to the service.
//Intent confirmationIntent = intent.getParcelableExtra(Intent.EXTRA_INTENT);
//confirmationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//try {
// startActivity(confirmationIntent);
//} catch (Exception e) {
//No action
// }
break;
case PackageInstaller.STATUS_SUCCESS:
Log.d(TAG, "Installation succeed");
break;
default:
Log.d(TAG, "Installation failed");
break;
}
stopSelf();
return START_NOT_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
得到結果
我對編碼很陌生,如果這是一個愚蠢的問題,我很抱歉
看起來問題在於我的模擬器沒有安裝 gapps,即使沒有在任何地方說明,這顯然是對此類操作的依賴。 盡管我會推薦 CommonsWare 在他的評論中提出的章節,因為它們比稀缺文檔要全面得多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.