默认安装应用程序,授予INSTALL_PACKAGES权限
我试图默默安装apk到系统中。 我的应用程序位于/系统/应用程序,并成功授予“android.permission.INSTALL_PACKAGES”权限
但是,我无法find任何地方如何使用此权限。 我试图复制文件到/数据/应用程序,并没有成功。 此外,我尝试使用此代码
Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType( Uri.parse("file:///sdcard/app.apk"), "application/vnd.android.package-archive"); startActivity(intent);
但是这个代码打开标准安装对话框。 如何在没有授予android.permission.INSTALL_PACKAGES
情况下以默认方式安装应用程序?
PS我正在写一个应用程序,将在第一次启动时从文件夹安装许多apks到系统(replace安装向导)。 我需要它来使固件更轻。
如果您认为我正在编写病毒:所有程序都安装到/ data / app中。 权限Install_packages只能授予位于/ system / app中的系统级程序或使用系统密钥签名。 所以病毒无法到达那里。
正如所说的http://www.mail-archive.com/android-porting@googlegroups.com/msg06281.html应用程序可以无提示安装,如果他们有install_packages权限。 此外,您不需要Install_packages权限就可以不安静地安装软件包。 加上http://www.androidzoom.com/android_applications/tools/silent-installer_wgqi.html
你的第一个select是查看Android的本地PackageInstaller 。 我会build议您修改该应用程序的方式,或者只是提取所需的function。
具体而言,如果您查看PackageInstallerActivity及其onClickListener
方法:
public void onClick(View v) { if(v == mOk) { // Start subactivity to actually install the application Intent newIntent = new Intent(); ... newIntent.setClass(this, InstallAppProgress.class); ... startActivity(newIntent); finish(); } else if(v == mCancel) { // Cancel and finish finish(); } }
然后你会注意到实际的安装程序位于InstallAppProgress类中。 检查这个类,你会发现initView
是核心安装程序的function,最后它是调用PackageManager
的installPackage
函数:
public void initView() { ... pm.installPackage(mPackageURI, observer, installFlags, installerPackageName); }
下一步是检查PackageManager ,它是抽象类。 你会在installPackage(...)
findinstallPackage(...)
函数。 坏消息是它用@hide标记。 这意味着它不是直接可用的(您将无法通过调用此方法进行编译)。
/** * @hide * .... */ public abstract void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,String installerPackageName);
但是你可以通过reflection来访问这个方法。
如果您对PackageManager
的installPackage
函数的实现感兴趣,请查看PackageManagerService 。
概要
你需要通过Context
的getPackageManager()
来获得包pipe理器对象。 然后你会通过reflection调用installPackage
函数。
我已经检查过ADB如何安装应用程序。
– 它将APK复制到/ data / local / tmp
– 它运行'shell:pm install /data/local/tmp/app.apk'
我试图通过这样做来复制这个行为:(在pc上,使用usb-cable)
adb push app.apk /sdcard/app.apk
adb shell
$ pm install /sdcard/app.apk
这工作。 该应用程序已安装。
我做了一个应用程序(名为AppInstall),它应该安装其他应用程序。
(正常安装,无根设备)
它确实:
Runtime.getRuntime().exec("pm install /sdcard/app.apk").waitFor();
但是这给了错误:
java.lang.SecurityException: Neither user 10019 nor current process has android.permission.INSTALL_PACKAGES.
这似乎是错误是由下午,而不是由AppInstall抛出。
因为AppInstall没有捕获SecurityException,应用程序不会崩溃。
我已经尝试了一个根植设备(相同的应用程序和AppInstall)同样的事情,它的工作就像一个魅力。
(也正常安装,不在/系统或任何东西)
AppInstall甚至没有问根权限。
但是,这是因为shell在该设备上总是#
而不是$
。
顺便说一句,你需要root安装在/系统中的应用程序,正确的?
我尝试adb重新安装在没有根的设备上,得到:
remount failed: Operation not permitted.
这就是为什么我不能在非根设备上尝试/系统的东西。
结论:你应该使用一个根植的设备
希望这可以帮助 :)
你应该定义
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
在你的清单中,如果你是在系统分区(/ system / app)中,或者你有你的应用程序由制造商签名,你将有INSTALL_PACKAGES权限。
我的build议是创build一个具有1.5兼容性级别的小型Android项目,用于通过reflection调用installPackages,并导出包含安装包的方法和调用真实方法的jar。 然后,通过将jar导入到您的项目中,您将准备好安装软件包。
我不知道该怎么做,因为没有人回答这个问题,而且我也没有发现有关这个许可的文件。 所以我find了自己的解决scheme。 你的身体比较好,但这是一个解决办法。
我安装了busybox,设置777权限/ data / app(我不关心安全性)。 然后刚从应用程序执行“busybox安装”。 这工作,但有一个很大的安全漏洞。 如果您设置权限777,则不需要root用户。
这是一个非常好的post在这个问题上。 它帮了我很多。
您可以简单地使用adb install命令来静默安装/更新APK。 示例代码如下
public static void InstallAPK(String filename){ File file = new File(filename); if(file.exists()){ try { String command; filename = StringUtil.insertEscape(filename); command = "adb install -r " + filename; Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", command }); proc.waitFor(); } catch (Exception e) { e.printStackTrace(); } } }
我尝试了扎根的Android 4.2.2,这种方法适用于我:
private void installApk(String filename) { File file = new File(filename); if(file.exists()){ try { final String command = "pm install -r " + file.getAbsolutePath(); Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", command }); proc.waitFor(); } catch (Exception e) { e.printStackTrace(); } } }
您可以通过reflection使用隐藏的API android.content.pm.IPackageInstallObserver
:
public class PackageManagement { public static final int INSTALL_REPLACE_EXISTING = 0x00000002; public static final int INSTALL_SUCCEEDED = 1; private static Method installPackageMethod; private static Method deletePackageMethod; static { try { installPackageMethod = PackageManager.class.getMethod("installPackage", Uri.class, IPackageInstallObserver.class, Integer.TYPE, String.class); } catch (NoSuchMethodException e) { e.printStackTrace(); } } public static void installPackage(PackageManager pm, Uri mPackageUri, IPackageInstallObserver observer, int installFlags, String installerPackageName) { try { installPackageMethod.invoke(pm, mPackageUri, observer, installFlags, installerPackageName); } catch (Exception e) { e.printStackTrace(); } } }
将android.content.pm.IPackageInstallObserver
导入到您的项目中。 你的应用程序必须是系统。 您必须在清单文件中激活权限android.permission.INSTALL_PACKAGES
。
我最近一直在没有用户同意的情况下实施安装 – 这是一个API级21+的自助terminal应用程序,我可以完全控制环境。
基本要求是
- API等级21+
- root访问权限来将更新程序安装为系统特权应用程序。
以下方法从InputStream读取并安装APK:
public static boolean installPackage(Context context, InputStream in, String packageName) throws IOException { 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); OutputStream out = session.openWrite("COSU", 0, -1); byte[] buffer = new byte[65536]; int c; while ((c = in.read(buffer)) != -1) { out.write(buffer, 0, c); } session.fsync(out); in.close(); out.close(); Intent intent = new Intent(context, MainActivity.class); intent.putExtra("info", "somedata"); // for extra data if needed.. Random generator = new Random(); PendingIntent i = PendingIntent.getActivity(context, generator.nextInt(), intent,PendingIntent.FLAG_UPDATE_CURRENT); session.commit(i.getIntentSender()); return true; }
以下代码调用安装
try { InputStream is = getResources().openRawResource(R.raw.someapk_source); installPackage(MainActivity.this, is, "com.example.apk"); } catch (IOException e) { Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show(); }
对于整个工作你拼命需要INSTALL_PACKAGES
权限,否则上面的代码将失败默默
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
要获得这个权限,你必须安装你的APK作为系统应用程序,它需要root (但是,当你已经安装了你的更新应用程序,它似乎没有根工作)
要作为系统应用程序安装,我创build了一个签名的APK,并将其推送
adb push updater.apk /sdcard/updater.apk
然后将其移至system/priv-app
– 这需要重新安装FS(这就是为什么需要root)
adb shell su mount -o rw,remount /system mv /sdcard/updater.apk /system/priv-app chmod 644 /system/priv-app/updater.apk
由于某种原因,它不适用于简单的debugging版本,但是如果您的应用程序在priv-app
由于某种原因未被拾取, logcat将显示有用的信息。
我使用PackageManager.installPackage方法为静默安装制作了一个testing应用程序。
我通过reflection得到了installPackage方法,并在我的src文件夹中制作了android.content.pm.IPackageInstallObserver接口(因为它隐藏在android.content.pm包中)。
当我运行installPackage时,我得到SecurityException和string指示,我的应用程序没有android.permission.INSTALL_PACKAGES,但它在AndroidManifest.xml中定义。
所以,我认为,这是不可能的。
PS。 我在Android SDK 2.3和4.0上进行了testing。 也许它会适用于早期版本。
在pm安装之前试试这个LD_LIBRARY_PATH=/vendor/lib:/system/lib
。 它运作良好。
!/斌/庆典
f=/home/cox/myapp.apk #or $1 if input from terminal. #backup env var backup=$LD_LIBRARY_PATH LD_LIBRARY_PATH=/vendor/lib:/system/lib myTemp=/sdcard/temp.apk adb push $f $myTemp adb shell pm install -r $myTemp #restore env var LD_LIBRARY_PATH=$backup
这对我有用。 我运行在Ubuntuterminal上的Ubuntu 12.04。
- XCode:7应用程序安装失败:找不到此可执行文件的有效设置configuration文件
- 什么是INSTALL_PARSE_FAILED_NO_CERTIFICATES错误?
- 用android studio找不到jvm,JAVA_HOME已经设置好了
- Visual Studio安装问题 – “加载安装程序组件时遇到问题。 取消设置。
- IntelliJ IDEA是否在64位Windows系统上工作?
- 我如何安装博托?
- 未findgcloud命令 – 安装Google Cloud SDK
- 如何从下载源安装golang第三方项目?
- 当试图安装pecl扩展时,在mac os x 10.7.3上出现$ PHP_AUTOCONF错误