不建议使用installPackage
来检查Android(AOSP)的来源,并检查Android的PackageManager应用程序,它使用PackageInstaller
类创建一个PackageInstaller.Session
实例来执行APK的安装。
我正在尝试在我的应用程序中执行相同的操作。我已使用系统密钥签名,并且确实在清单中包括了INSTALL_PACKAGES
权限。
这是我的代码:
val packageName = "com.spotify.music"
val inputStream = File(filesDir, "spotify.apk").inputStream()
// ...
val packageInstaller = context.packageManager.packageInstaller
val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
params.setAppPackageName(packageName)
val sessionId = packageInstaller.createSession(params)
val session = packageInstaller.openSession(sessionId)
val out = session.openWrite("COSU", 0, -1)
inputStream.copyTo(out)
session.fsync(out)
inputStream.close()
out.close()
session.commit(null)
但是,我得到了以下奇怪的空指针异常:
Error while installing: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.AppOpsManager.checkPackage(int, java.lang.String)' on a null object reference
有人知道这里出了什么问题吗?
答案 0 :(得分:1)
以下代码段应为您工作(我没有对其进行测试,但是欢迎您进一步调试和编辑任何必要的更改)。
方法参数:
代码如下:
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class PackageInstaller {
public static void installPackage(Context context, String installSessionId,
String packageName,
InputStream apkStream) throws IOException {
PackageManager packageManger = context.getPackageManager();
android.content.pm.PackageInstaller packageInstaller =
packageManger.getPackageInstaller();
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
params.setAppPackageName(packageName);
android.content.pm.PackageInstaller.Session session = null;
try {
int sessionId = packageInstaller.createSession(params);
session = packageInstaller.openSession(sessionId);
OutputStream out = session.openWrite(installSessionId, 0, -1);
byte buffer[] = new byte[1024];
int length;
int count = 0;
while ((length = apkStream.read(buffer)) != -1) {
out.write(buffer, 0, length);
count += length;
}
session.fsync(out);
out.close();
Intent intent = new Intent(Intent.ACTION_PACKAGE_ADDED);
session.commit(PendingIntent.getBroadcast(context, sessionId,
intent, PendingIntent.FLAG_UPDATE_CURRENT).getIntentSender());
} finally {
if (session != null) {
session.close();
}
}
}
}
答案 1 :(得分:0)
您不能将null
传递给session.commit()
。请参阅Android Developers上的文档。您需要的是一个IntentSender,它是从PendingIntent中获得的,而该PendingIntent中应该包含一个您的应用程序可以接收的意图(可以在Activity,Service或BroadcastReceiver中)。
提交会话后,结果将作为额外内容包括在收到的意图中。