Android中的Install/Unistall from shell命令

Android中的Install/Unistall from shell命令,android,silent-installer,Android,Silent Installer,我想在Android中实现apk文件和unistaller包中的静默安装程序。 这个话题已经在某某和其他地方进行了大量的讨论,但由于某种原因,我无法应用任何内容。 这个范围显然很难实现,因为如果成功的话,这将是安卓系统严重的安全漏洞。但是,我需要为一个特殊项目实施它,而不是为消费市场。 有两种方法: 通过调整PackageManager安装程序(实际上只是为了删除用户接受对话框),从源代码(例如AOSP或Cyanogen mod)生成自定义ROM 通过以超级用户身份创建一个进程并执行“adb s

我想在Android中实现apk文件和unistaller包中的静默安装程序。 这个话题已经在某某和其他地方进行了大量的讨论,但由于某种原因,我无法应用任何内容。 这个范围显然很难实现,因为如果成功的话,这将是安卓系统严重的安全漏洞。但是,我需要为一个特殊项目实施它,而不是为消费市场。 有两种方法:

  • 通过调整PackageManager安装程序(实际上只是为了删除用户接受对话框),从源代码(例如AOSP或Cyanogen mod)生成自定义ROM
  • 通过以超级用户身份创建一个进程并执行“adb shell pm安装”,以编程方式完成此任务。我以前在/system/xbin中安装了'su',并在运行时测试了RootTools.rootIsAvailable()
  • 对于第一种情况,我深入研究了Froyo源代码,但使用@hide标记的方法陷入了死胡同。 第二次,我首先尝试了终端的命令

    adb shell pm install /mnt/sdcard/HelloAndroid.apk
    

    两个都可以。然后,我使用了以下代码,在根仿真器(2.2-Froyo)上测试开发:

    为了避免打字错误和其他错误,我对安装命令的apk文件参数进行了硬编码;在“case R.id.btn安装”上,未执行命令,退出为“Failure”,退出值为1,表示“找不到类”;不知道那意味着什么。。。 我感谢你的帮助


    编辑:我有干净的解决方案,一旦我有时间和正确形式的代码,我将尽快发布A-Z的答案

    您也可以直接使用PackageManager(需要root访问权限)执行此操作:

    • 使用具有公开接口的平台sdk创建应用程序(创建或下载,并配置eclipse)
    • 在应用程序中,直接调用允许静默安装/删除的隐藏API函数
    • 通过将APK复制到/system/app(需要root用户),将其作为系统应用程序安装到设备上

    看到这个:

    不知道,但只是一个想法:

    我认为您是在standarout中编写的,没有执行命令,也没有通过其输入向进程提供额外的数据。我认为应该是:

    Runtime.getRuntime().exec("pm install /mnt/sdcard/HelloAndroid.apk\n"); 
    

    希望这会有所帮助。

    正如我在这里承诺的,这是解决这个问题的方法,除了必须在/system/app目录中安装整个应用程序之外,不必对系统进行任何强制操作。我遵循了,然后对这里的优秀文章做了一些修改:。我已经下载了文章中引用的zip文件(我尽量保持类名不变):

  • 创建一个新项目和一个主要活动作为入口点
  • 在/src中创建包com.example.instuninshelper。我在那里添加了ApplicationManager.java和OnInstalledPackage.java文件
  • 在ApplicationManager类中插入以下代码:
  • 在同一com.example.instuninsHelper包下创建了文件OnDeletedPackage.java,代码如下:
  • 在android.content.pm包(名称空间不应更改)中,我修改了IPackageDeleteObserver.java,结果如下:
  • 在Eclipse中构建应用程序并将其部署到模拟器
  • 在emulator中:home button>Settings>applications>…卸载应用程序(因为它没有安装在/system/app中,我们只需要生成apk文件)
  • 对仿真器执行以下操作(以便我们可以在/system/app中写入;我使用的另一个解决方案是生成一个自定义ROM,其中该应用包含在/system/app中):
    • 从这里下载su文件。将其重命名为su.zip
    • 然后从控制台: *adb外壳安装-o rw,重新安装-t yaffs2/dev/block/mtdblock03/system *adb推送su.zip/system/xbin/su *adb壳牌chmod 06755/系统 *adb壳牌chmod 06755/system/xbin/su
  • 从控制台转到项目的/bin目录,然后输入: *adb push.apk/system/app
  • 最后,始终从控制台输入: *adb shell am start-n com.example.silentinsunist/com.example.silentinsunist.main活动
  • 享受吧
    /system/app
    目录中安装基本上与要求root相同

    假设你有根,检查。然后你可以做:

    if (RootTools.isAccessGiven()) {
        CommandCapture command = new CommandCapture(0, "pm install " + PATH_TO_APK);
        RootTools.getShell(true).add(command).waitForFinish();
    }
    
    请注意,
    waitForFinish()
    是一个阻塞调用

    Runtime.getRuntime().exec(“pm安装/mnt/sdcard/HelloAndroid.apk\n”)

    这对我来说很有效,不过还需要做两个额外的细节:

  • 在AndroidManifest.xml中添加android:sharedUserId=“android.uid.system”

  • 使用系统密钥签署apk

    但这样看来,似乎无法判断安装是否成功,因此我稍后将尝试@Ginger的方法


  • 对于所有仍有问题的用户:您将需要一个根设备并使用它

    Process result = Runtime.getRuntime().exec("pm install -r -d MyApp.apk /system/app")
    
    如果您收到结果代码9(错误代码9),则需要从设备中删除apk并将其推回(推而不是安装!)

    转到设备外壳并按下apk

    launcher=MyApp.apk
    $adb shell su -c "mount -o remount,rw -t rfs /dev/stl5 /system"
    $adb push $launcher /sdcard/$launcher
    $adb shell su -c "chmod 644 /system/app/$launcher"
    

    现在,您可以使用pm安装而不会出现错误。希望它能帮助别人。

    很抱歉,我似乎不了解你的知识水平:我不理解“公开接口”。您的建议与此帖子完全一致:。只是我运行了他的示例,但失败了(似乎是一个签名问题)。如果你能详细介绍一下,我将不胜感激。为什么上面的代码是错误的?“未找到类”错误是什么意思?该博客正在讨论其他内容。感谢RvdK,我找到了解决方案并很快解释了它。它是基于那篇文章的原则,很抱歉,当你做挂载的时候,没有弄清楚它允许你挂载吗?您的设备是否允许rw。换句话说,在default.prop文件中,您的值是rosecure=0而不是1?当我尝试运行remount命令时
    
    private OnDeletedPackage onDeletedPackage;
    class PackageDeleteObserver extends IPackageDeleteObserver.Stub { 
    
            public void packageDeleted(boolean succeeded) throws RemoteException {
                if (onDeletedPackage != null) {
                    onDeletedPackage.packageDeleted(succeeded);
                }
            }
    
        }
    
    
    package com.example.instuninsthelper;
    public interface OnDeletedPackage {
        public void packageDeleted(boolean succeeded);
    }
    
    
    package android.content.pm;
    
    public interface IPackageDeleteObserver extends android.os.IInterface {
    
        public abstract static class Stub extends android.os.Binder implements android.content.pm.IPackageDeleteObserver {
            public Stub() {
                throw new RuntimeException("Stub!");
            }
    
            public static android.content.pm.IPackageDeleteObserver asInterface(android.os.IBinder obj) {
                throw new RuntimeException("Stub!");
            }
    
            public android.os.IBinder asBinder() {
                throw new RuntimeException("Stub!");
            }
    
            public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)
                    throws android.os.RemoteException {
                throw new RuntimeException("Stub!");
            }
        }
    
        public abstract void packageDeleted(boolean succeeded)
                throws android.os.RemoteException;
    }
    
    if (RootTools.isAccessGiven()) {
        CommandCapture command = new CommandCapture(0, "pm install " + PATH_TO_APK);
        RootTools.getShell(true).add(command).waitForFinish();
    }
    
    Process result = Runtime.getRuntime().exec("pm install -r -d MyApp.apk /system/app")
    
    launcher=MyApp.apk
    $adb shell su -c "mount -o remount,rw -t rfs /dev/stl5 /system"
    $adb push $launcher /sdcard/$launcher
    $adb shell su -c "chmod 644 /system/app/$launcher"