簡體   English   中英

使用 PackageInstaller 發出 installing.apk

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM