微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Android中从shell命令安装/ Unistall

我想在 Android中实现一个安静的安装程序 – 从apk文件和unistaller-package.
主题在很大程度上已经在SO和其他地方讨论过,但是由于某些我失踪的原因我无法申请.
这个范围显然很难实现,因为如果成功,Android将会是严重的安全漏洞.但是,我需要实施一个特殊的项目,而不是为了消费市场.
有两种方法

>通过调整PackageManager安装程序(实际上只是删除用户接受对话框),从源代码(例如AOSP或Cyanogen mod)生成自定义ROM.
>以编程方式通过创建超级用户进程并执行“adb shell pm install”进行编程.我以前在/ system / xbin中安装了’su’,我在运行时测试了Roottools.rootIsAvailable().

对于第一种情况,我研究了Froyo的源代码,但是用@hide标记方法进入了一个死胡同.
我第一次尝试终端命令

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

adb shell pm uninstall com.example.helloandroid

两个工作都可以.然后,我使用以下代码,开发正在根深蒂固的仿真器(2.2 – Froyo)上进行测试:

@Override
    public void onClick(View v) {
        switch (v.getId())
           {
              case R.id.btnInstall:
                  try {  
                      install = Runtime.getRuntime().exec("su\n");   
                      DataOutputStream os = new DataOutputStream(install.getoutputStream());
                      os.writeBytes("pm install /mnt/sdcard/HelloAndroid.apk\n"); 
                      os.writeBytes("exit\n"); 
                      os.flush();
                      install.waitFor();

                              if (install.exitValue() == 0) {  
                                  Toast.makeText(MainActivity.this,"Success!",Toast.LENGTH_LONG).show();
                              }  
                              else {  
                                  Toast.makeText(MainActivity.this,"Failure. Exit code: "+String.valueOf(install.exitValue()),Toast.LENGTH_LONG).show();
                              }
                  }
                  catch (InterruptedException e) {  
                      logError(e);
                  }
                  catch (IOException e) {  
                  logError(e);
                  } 
                  break;

              case R.id.btnUninstall:
                  try {
                      install = Runtime.getRuntime().exec("su\n"); 
                      install=Runtime.getRuntime().exec("pm uninstall "+txtPackageName.getText().toString()+"\n");

                } catch (Exception e) {
                    logError(e);
                }
                  break;
           }

    }

为了避免拼写错误和其他修剪,我硬编码了安装命令的apk文件参数; on’case R.id.btnInstall’命令不执行,退出是“失败”,退出值为1,意思是“该类无法找到”;不知道这是什么意思
我感谢您的帮助!

EDITED:我有干净的解决方案,一旦我有时间和代码正确的形式,我会发布A-Z的答案!

解决方法

正如我在这里所答应的那样,解决了这个问题,而不必对系统进行任何强制,而不必在/ system / app目录中安装整个应用程序.我已经跟着,然后在这里做了一些很好的文章http://paulononaka.wordpress.com/2011/07/02/how-to-install-a-application-in-background-on-android/.我已经下载了文章中引用的zip文件,(我尽可能保持相同的类名):

>创建了一个新项目和主要活动作为入口点

package com.example.silentinstuninst;

import java.io.File;
import java.lang.reflect.InvocationTargetException;

import com.example.instuninsthelper.ApplicationManager;
import com.example.instuninsthelper.OnDeletedPackage;
import com.example.instuninsthelper.OnInstalledPackage;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

    Process install;
    Button btnInstall,btnUninstall;
    EditText txtApkFileName,txtPackageName; 

    public static final String TAG = "SilentInstall/Uninstall";

    private static ApplicationManager am;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initializeValues();

    }

    private void initializeValues() {

        btnInstall = (Button) findViewById(R.id.btnInstall);
        btnUninstall = (Button) findViewById(R.id.btnUninstall);
        txtApkFileName = (EditText) findViewById(R.id.txtApkFilePath);
        txtPackageName = (EditText) findViewById(R.id.txtPackageName);

        btnInstall.setonClickListener(this);
        btnUninstall.setonClickListener(this);

        try {
            am = new ApplicationManager(this);
            am.setonInstalledPackage(new OnInstalledPackage() {

                public void packageInstalled(String packageName,int returnCode) {
                    if (returnCode == ApplicationManager.INSTALL_SUCCEEDED) {
                        Log.d(TAG,"Install succeeded");
                    } else {
                        Log.d(TAG,"Install Failed: " + returnCode);
                    }
                }
            });

            am.setonDeletedPackage(new OnDeletedPackage() {
                public void packageDeleted(boolean succeeded) {
                    Log.d(TAG,"Uninstall succeeded");  
                }
            });

        } catch (Exception e) {
            logError(e);
        }
    }

    private void logError(Exception e) {
        e.printstacktrace();
        Toast.makeText(this,R.string.error+e.getMessage(),Toast.LENGTH_LONG).show();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId())
           {
              case R.id.btnInstall:
                  // InstallUninstall.Install(txtApkFileName.getText().toString());
            try {
                am.installPackage(Environment.getExternalStorageDirectory() +
                        File.separator + txtApkFileName.getText().toString());
            } catch (IllegalArgumentException e1) {
                // Todo Auto-generated catch block
                e1.printstacktrace();
            } catch (illegalaccessexception e1) {
                // Todo Auto-generated catch block
                e1.printstacktrace();
            } catch (InvocationTargetException e1) {
                // Todo Auto-generated catch block
                e1.printstacktrace();
            } // install package
                  break;

              case R.id.btnUninstall:
                  // InstallUninstall.Uninstall(txtPackageName.getText().toString());
            try {
                am.uninstallPackage(txtPackageName.getText().toString());
            } catch (IllegalArgumentException e) {
                // Todo Auto-generated catch block
                e.printstacktrace();
                logError(e);
            } catch (illegalaccessexception e) {
                // Todo Auto-generated catch block
                e.printstacktrace();
                logError(e);
            } catch (InvocationTargetException e) {
                // Todo Auto-generated catch block
                e.printstacktrace();
                logError(e);
            }
                  break;
           }    
    }
}

>在/ src中创建com.example.instuninsthelper包.我已经添加了ApplicationManager.java和OnInstalledPackage.java文件
>在ApplicationManager类中插入以下代码

private OnDeletedPackage onDeletedPackage;
class PackageDeleteObserver extends IPackageDeleteObserver.Stub { 

        public void packageDeleted(boolean succeeded) throws remoteexception {
            if (onDeletedPackage != null) {
                onDeletedPackage.packageDeleted(succeeded);
            }
        }

    }

>创建,在同一个com.example.instuninsthelper下使用以下代码打包OnDeletedPackage.java文件

package com.example.instuninsthelper;
public interface OnDeletedPackage {
    public void packageDeleted(boolean succeeded);
}

>在android.content.pm包中(命名空间应该不要更改)我修改了IPackageDeleteObserver.java,结果如下:

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;
}

>在Eclipse中构建应用程序并将其部署到仿真器
>在模拟器中:主页按钮>设置>应用> …卸载应用程序(因为它没有安装在/ system / app中,我们只需要生成apk文件)
>执行以下操作来根除模拟器(以便我们可以在/ system / app中编写;我使用的其他解决方案是生成一个包含在/ system / app中的此应用程序的自定义ROM):

>从这里下载su文件http://forum.xda-developers.com/showthread.php?t=682828http://forum.xda-developers.com/showthread.php?t=682828.将其重命名为su.zip
>然后从控制台:
* adb shell mount -o rw,remount -t yaffs2 / dev / block / mtdblock03 / system
* adb push su.zip / system / xbin / su
* adb shell chmod 06755 / system
* adb shell chmod 06755 / system / xbin / su

>从控制台,转到项目的/ bin目录,然后输入:* adb push .apk / system / app>最后,总是从控制台输入:* adb shell am start -n com.example.silentinstuninst / com.example.silentinstuninst.MainActivity>享受!

原文地址:https://www.jb51.cc/android/311888.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐