繁体   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