似乎已经在API 21(Lollipop)中添加了PackageInstaller(https://developer.android.com/reference/android/content/pm/PackageInstaller.html),但是我还没有找到任何关于如何安装的可靠代码示例通过此API的APK.任何代码帮助将不胜感激.
我正在调查针对Android M Preview的COSU/Kiosk应用程序,并且正在尝试实施新功能"设备所有者静默安装和卸载应用程序"(https://developer.android.com/preview/api-overview.html# afw)通过PackageInstaller API.
找到这些,但没有帮助:如何使用Android L中的"PackageInstaller"类安装/更新/删除APK? Lollipop上的"PackageInstaller"类是什么,以及如何使用它?
没有找到任何Android示例应用程序.
提前致谢.
silent-installer kiosk-mode device-owner packageinstaller android-6.0-marshmallow
我想让我的应用程序自动安装apk.这适用于api <24.但对于24岁,它失败了.Android实现了额外的安全性:
对于定位到Android 7.0的应用,Android框架会强制执行StrictMode API策略,该策略禁止在应用外部公开file:// URI.如果包含文件URI的intent离开了您的应用程序,则该应用程序将失败并出现FileUriExposedException异常.
所以我尝试了这个:
Uri myuri;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N){
myuri = Uri.parse("file://"+outapk);
} else {
File o = new File(outapk);
myuri = FileProvider.getUriForFile(con, con.getApplicationContext().getPackageName() + ".provider", o);
}
Intent promptInstall = new Intent(Intent.ACTION_VIEW).setDataAndType(myuri,"application/vnd.android.package-archive");
con.startActivity(promptInstall);
Run Code Online (Sandbox Code Playgroud)
但得到一个致命的例外:
com.android.packageinstaller "Caused by: java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{b42ee8a 6826:com.android.packageinstaller/u0a15} (pid=6826, uid=10015) that is not exported from uid 10066".
Run Code Online (Sandbox Code Playgroud)
我的清单中有export = true.
问题似乎是packageinstaller无法使用content:// uri.
有没有办法允许应用程序以编程方式安装带有api24的apk?
uri securityexception apk packageinstaller android-7.0-nougat
我的应用程序具有自动更新功能,可下载APK,然后使用Intent.ACTION_VIEW打开软件包安装程序.
最多7个它完美地工作(通过向正常文件提供Intent://)
使用Android 7,我不得不改为使用FileProvider.代码的唯一区别是:
Intent installIntent = new Intent(Intent.ACTION_VIEW);
if (android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
installIntent.setDataAndType(uri,
manager.getMimeTypeForDownloadedFile(downloadId));
} else {
Uri apkUri = FileProvider.getUriForFile(AutoUpdate.this,
BuildConfig.APPLICATION_ID, file);
installIntent.setDataAndType(apkUri,manager.getMimeTypeForDownloadedFile(downloadId));
}
activity.startActivity(installIntent);
Run Code Online (Sandbox Code Playgroud)
一旦调用了startActivity,我每次都会得到这个
这是Android 7的错误吗?或者某些/许可缺少我的一面?
编辑AndroidManifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_LOGS" />
<application ...>
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.myapp"
android:exported="false"
android:enabled="true"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
</application>
Run Code Online (Sandbox Code Playgroud)
路径xmlfile
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="myfolder" path="."/> …Run Code Online (Sandbox Code Playgroud) 我是macOS Development的新手,但我确实有iOS开发经验.我正在开发一个包的安装程序应用程序XYZ.pkg
我想用我自己的GUI而不是默认的macOS安装程序来安装这个包.该程序包在我的应用程序包中可用,当我尝试通过命令安装它时崩溃.
guard let pathOfResource = Bundle.main.path(forResource: "SomePackageName", ofType: ".pkg") else {
return
}
self.loadingView.alphaValue = 1
self.loadingView.layer?.isHidden = false
self.activityIndicator.startAnimation(sender)
let argumentString = "-pkg " + pathOfResource
let argumentString1 = "-target /"
let path = "/usr/sbin/installer "
let arguments = [argumentString,argumentString1]
let task = Process.launchedProcess(launchPath: path, arguments: arguments )
task.waitUntilExit()
self.activityIndicator.stopAnimation(sender)
self.loadingView.alphaValue = 0
Run Code Online (Sandbox Code Playgroud) 我正在开发一个作为设备所有者运行的应用程序,我想在其中构建一个自动更新程序.
为此,我使用PackageInstaller,因为我拥有使用它的权限,因为我的设备所有者位置.
private void installPackage(InputStream inputStream)
throws IOException {
notifyLog("Inizio aggiornamento...");
PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
int sessionId = packageInstaller.createSession(new PackageInstaller
.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL));
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
long sizeBytes = 0;
OutputStream out = null;
out = session.openWrite("my_app_session", 0, sizeBytes);
int total = 0;
byte[] buffer = new byte[65536];
int c;
while ((c = inputStream.read(buffer)) != -1) {
total += c;
out.write(buffer, 0, c);
}
session.fsync(out);
inputStream.close();
out.close();
session.commit(createIntentSender(sessionId));
}
private IntentSender createIntentSender(int sessionId) {
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
sessionId,
new …Run Code Online (Sandbox Code Playgroud) android android-pendingintent device-owner packageinstaller cosu
我正在尝试使用常规Runtime.getRuntime.exec()例程在Android 7(三星和索尼)中安装APK 。安装失败,但logcat中出现以下异常:
09-04 14:14:33.932 16623-16623/? D/AndroidRuntime: Calling main entry com.android.commands.pm.Pm
09-04 14:14:33.939 3695-3876/? D/PackageInstaller: installation of android.content.pm.PackageInstaller$SessionParams@a4d2f0e for non-container user 0
09-04 14:14:33.940 16623-16623/? E/Pm: Error
java.lang.NullPointerException
at android.os.Parcel.readException(Parcel.java:1699)
at android.os.Parcel.readException(Parcel.java:1646)
at android.content.pm.IPackageInstaller$Stub$Proxy.createSession(IPackageInstaller.java:249)
at com.android.commands.pm.Pm.doCreateSession(Pm.java:530)
at com.android.commands.pm.Pm.runInstall(Pm.java:369)
at com.android.commands.pm.Pm.run(Pm.java:142)
at com.android.commands.pm.Pm.main(Pm.java:99)
at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:301)
09-04 14:14:33.941 16623-16623/? I/art: System.exit called, status: 1
09-04 14:14:33.941 16623-16623/? I/AndroidRuntime: VM exiting with result code 1
Run Code Online (Sandbox Code Playgroud)
我尝试实现这一点:
Process proc = Runtime.getRuntime().exec("pm install /sdcard/imo.apk");
Run Code Online (Sandbox Code Playgroud)
所以:
Process proc = Runtime.getRuntime().exec(new String[]{"/system/bin/sh","-c","/system/bin/pm …Run Code Online (Sandbox Code Playgroud) 我需要在android 8手机上开始安装apk,但这不应该保持沉默(adb install)。该行为应类似于用户已触摸设备上的apk文件。在android 8之前,可以通过adb启动apk的安装,如下所示:
adb shell am start -d file:"///sdcard/foobar.apk" -p com.google.android.packageinstaller
Run Code Online (Sandbox Code Playgroud)
在android 8上这不再可行。根据日志文件,需要android.permission.REQUEST_INSTALL_PACKAGES权限。
09-25 16:39:55.691 6066 6066 E InstallStart: Requesting uid 2000 needs to declare permission android.permission.REQUEST_INSTALL_PACKAGES
Run Code Online (Sandbox Code Playgroud)
我知道,由于要求安装其他应用程序的 android 8 应用程序需要此权限,但是通过adb进行操作不应该是这种情况,对吧?
这是Android 8中的错误吗?是否有可能以其他方式做到这一点?
我只是尝试使用PackageInstaller和PackageManager API在我的设备上安装软件包(从运行它的设备所有者应用程序).我一直在寻找例子但找不到符合我需要的东西.
以下是我安装Facebook应用程序的代码示例:
PackageManager pm = getPackageManager();
PackageInstaller mPackageInstaller = pm.getPackageInstaller();
PackageInstaller.SessionParams mSessionParams = new PackageInstaller.SessionParams(SessionParams.MODE_FULL_INSTALL);
mSessionParams.setReferrerUri(Uri.parse("file:///mnt/sdcard/Download/Facebook.apk"));
int mSessionId = mPackageInstaller.createSession( mSessionParams );
PackageInstaller.Session mPkgSession = PackageInstaller.openSession(mSessionId);
OutputStream mOStream = mPkgSession.openWrite("com.facebook.katana", 0, -1);
mPkgSession.fsync(mOStream);
Run Code Online (Sandbox Code Playgroud)
我想,我需要启动的下一个功能是"提交(IntentSender statusReceiver)".
所以请告诉我如何使用commit(),特别是如何声明一个正确的IntentSender来安装存储在/ sdcard中的APK.
谢谢 !!
android android-package-managers android-install-apk android-5.0-lollipop packageinstaller
我知道这个问题有很多堆栈溢出帖子,但我无法使用其中任何一个来解决我的问题。
我的应用程序仅适用于有限的人群(公司内部应用程序),因此我无法在应用程序商店中发布它,并且我希望当我在应用程序服务器上发布新版本时它会自动更新。
这是一个device admin没有root权限的应用程序。我发现这种方法可以实现这个目标,但它不起作用。
我的文件中有此权限AndroidManifest.xml来安装软件包:
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void installPackage(Context context, String filePath, String packageName)
throws IOException
{
Log.d(TAG, "installPackage: start");
PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
params.setAppPackageName(packageName);
// set params
int sessionId = packageInstaller.createSession(params);
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
//
InputStream in = new FileInputStream(new File(filePath));
OutputStream out = session.openWrite(packageName, 0, -1);
IOUtils.copyStream(in, out);
//
session.fsync(out);
in.close();
out.close();
//
session.commit(PendingIntent.getActivity(context, 112233, new Intent(context, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT).getIntentSender()); …Run Code Online (Sandbox Code Playgroud) 卸载 Android 应用程序的旧方法ACTION_UNINSTALL_PACKAGE在 API 级别 29 中已弃用。现在建议改用PackageInstaller.uninstall(packageName: String, statusReceiver: IntentSender)。这是到目前为止的想法:
fun uninstal(){
val packageName = "some package name"
val packageInstaller = this.packageManager.packageInstaller
val intent = Intent(this, this::class.java)
val sender = PendingIntent.getActivity(this, 0, intent, 0)
packageInstaller.uninstall(packageName, sender.intentSender)
}
Run Code Online (Sandbox Code Playgroud)
我不知道如何提供IntentSender. 我尝试在当前活动中创建一个意图,但这些代码所做的只是重新创建该活动。有什么想法吗?谢谢
我有一个试图访问(TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);它的登录片段适用于Lollipop 5.1之前的设备.当我在Marshmallow 6.01中尝试它时,它显示了安全性异常.所以我从android docs添加了代码来请求运行时权限.这是代码
int permissionCheck = ContextCompat.checkSelfPermission(getActivity(),Manifest.permission.READ_SMS);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.READ_SMS)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(getActivity(),new String[]{Manifest.permission.READ_SMS},REQUEST_SMS);
// REQUEST_SMS is an
// app-defined int constant. …Run Code Online (Sandbox Code Playgroud) android android-package-managers android-permissions packageinstaller android-6.0-marshmallow
我使用 PackageInstaller 和 PackageInstaller.Session 从我的应用程序安装应用程序。我想在安装失败时在我的应用程序中显示一条消息(例如,如果 apk 签名错误)。我如何获得安装会话的结果?
packageinstaller ×12
android ×8
apk ×3
device-owner ×2
auto-update ×1
cosu ×1
crash ×1
installation ×1
java ×1
kiosk-mode ×1
macos ×1
runtime.exec ×1
swift ×1
uri ×1