当前位置: 移动技术网 > IT编程>移动开发>Android > Android9.0 静默安装源码的实现

Android9.0 静默安装源码的实现

2020年03月09日  | 移动技术网IT编程  | 我要评论

花生仁的功效与作用,唐伯虎点秋香2之四大才子,简短冷笑话大全爆笑

网上基本都停在8.0就没人开始分析android9.0如何静默apk的代码,这是我自己之前研究9.0的framework整理出来的,真实源码整理

import android.content.broadcastreceiver;
import android.content.context;
import android.content.iintentreceiver;
import android.content.iintentsender;
import android.content.intent;
import android.content.intentfilter;
import android.content.intentsender;
import android.content.pm.applicationinfo;
import android.content.pm.packageinfo;
import android.content.pm.packageinstaller;
import android.content.pm.packagemanager;
import android.net.uri;
import android.os.bundle;
import android.os.environment;
import android.os.ibinder;
import android.os.remoteexception;
import android.util.log;

import java.io.file;
import java.io.fileinputstream;
import java.io.ioexception;
import java.io.inputstream;
import java.io.outputstream;
import java.lang.reflect.constructor;
import java.lang.reflect.field;
import java.lang.reflect.invocationtargetexception;
import java.util.concurrent.synchronousqueue;
import java.util.concurrent.timeunit;

/**
 * 作者 :
 * 邮箱 : 709847739#qq.com
 * 时间  : 2019/2/21-9:21
 * desc  :
 * version: 1.0
 */
public class packagemanagercompatp {

  private final static string tag = packagemanagercompatp.class.getsimplename();


  public static final long max_wait_time = 25 * 1000;

  public static final long wait_time_incr = 5 * 1000;

  private static final string secure_containers_prefix = "/mnt/asec";

  private context mcontext;

  public packagemanagercompatq(context context) {
    this.mcontext = context;
  }


  private static class localintentreceiver {
    private final synchronousqueue<intent> mresult = new synchronousqueue<>();

    private iintentsender.stub mlocalsender = new iintentsender.stub() {
      @override
      public void send(int code, intent intent, string resolvedtype, ibinder whitelisttoken,
               iintentreceiver finishedreceiver, string requiredpermission, bundle options) {
        try {
          mresult.offer(intent, 5, timeunit.seconds);
        } catch (interruptedexception e) {
          throw new runtimeexception(e);
        }
      }
    };

    public intentsender getintentsender() {
      class<?> aclass = null;
      try {
        aclass = class.forname("android.content.intentsender");
      } catch (classnotfoundexception e) {
        e.printstacktrace();
      }
      if (aclass == null) {
        return null;
      }
      try {
        constructor<?>[] declaredconstructors = aclass.getdeclaredconstructors();
        for (constructor<?> declaredconstructor : declaredconstructors) {
          log.i(tag, "declaredconstructor.tostring():" + declaredconstructor.tostring());
          log.i(tag, "declaredconstructor.getname():" + declaredconstructor.getname());
          class<?>[] parametertypes = declaredconstructor.getparametertypes();
          for (class<?> parametertype : parametertypes) {
            class aclass1 = parametertype.getclass();
            log.i(tag, "parametertypes...aclass1:" + aclass1.getname());
          }
        }
      } catch (exception e) {
        e.printstacktrace();
      }
      constructor constructor = null;
      try {
        constructor = aclass.getdeclaredconstructor(iintentsender.class);
      } catch (nosuchmethodexception e) {
        e.printstacktrace();
      }
      if (constructor == null) {
        return null;
      }
      object o = null;
      try {
        o = constructor.newinstance((iintentsender) mlocalsender);
      } catch (illegalaccessexception e) {
        e.printstacktrace();
      } catch (instantiationexception e) {
        e.printstacktrace();
      } catch (invocationtargetexception e) {
        e.printstacktrace();
      }
      return (intentsender) o;
//         new intentsender((iintentsender) mlocalsender)
    }

    public intent getresult() {
      try {
        return mresult.take();
      } catch (interruptedexception e) {
        throw new runtimeexception(e);
      }
    }
  }

  private packagemanager getpm() {
    return mcontext.getpackagemanager();
  }

  private packageinstaller getpi() {
    return getpm().getpackageinstaller();
  }

  private void writesplittoinstallsession(packageinstaller.session session, string inpath,
                      string splitname) throws remoteexception {
    long sizebytes = 0;
    final file file = new file(inpath);
    if (file.isfile()) {
      sizebytes = file.length();
    } else {
      return;
    }

    inputstream in = null;
    outputstream out = null;
    try {
      in = new fileinputstream(inpath);
      out = session.openwrite(splitname, 0, sizebytes);

      int total = 0;
      byte[] buffer = new byte[65536];
      int c;
      while ((c = in.read(buffer)) != -1) {
        total += c;
        out.write(buffer, 0, c);
      }
      session.fsync(out);
    } catch (ioexception e) {
      e.printstacktrace();
    } finally {
      ioutils.closequietly(out);
      ioutils.closequietly(in);
      ioutils.closequietly(session);
    }
  }

  /**
   * 入口方法
   * string apkpackagename = ""; //填写安装的包名
   * string apkpath = "";//填写安装的路径
   **/
  public void testreplaceflagsdcardinternal(string apkpackagename, string apkpath) throws exception {
    // do not run on devices with emulated external storage.
    if (environment.isexternalstorageemulated()) {
      return;
    }

    int iflags = 0x00000008;// packagemanager.install_external 0x00000008
    int rflags = 0;
    //这个暂时用不上
    //installparams ip = sampleinstallfromrawresource(iflags, false);
    uri uri = uri.fromfile(new file(apkpath));
    genericreceiver receiver = new replacereceiver(apkpackagename);
    int replaceflags = rflags | 0x00000002;//packagemanager.install_replace_existing 0x00000002
    try {
      invokeinstallpackage(uri, replaceflags, receiver, true);
      //assertinstall(ip.pkg, iflags, ip.pkg.installlocation);
    } catch (exception e) {
      log.e(tag, "failed with exception : " + e);
    } finally {
//      cleanupinstall(ip);
    }
  }

//  class installparams {
//    uri packageuri;
//
//    packageparser.package pkg;
//
//    installparams(string outfilename, int rawresid) throws packageparserexception {
//      this.pkg = getparsedpackage(outfilename, rawresid);
//      this.packageuri = uri.fromfile(new file(pkg.codepath));
//    }
//
//    installparams(packageparser.package pkg) {
//      this.packageuri = uri.fromfile(new file(pkg.codepath));
//      this.pkg = pkg;
//    }
//
//    long getapksize() {
//      file file = new file(pkg.codepath);
//      return file.length();
//    }
//  }
//
//  private installparams sampleinstallfromrawresource(int flags, boolean cleanup)
//      throws exception {
//    return installfromrawresource("install.apk", android.r.raw.install, flags, cleanup, false, -1,
//        packageinfo.install_location_unspecified);
//  }

//  private void cleanupinstall(installparams ip) {
//
//  }


  private void cleanupinstall(string pkgname) throws exception {
    if (pkgname == null) {
      return;
    }
    log.i(tag, "deleting package : " + pkgname);
    try {
      final applicationinfo info = getpm().getapplicationinfo(pkgname,
          packagemanager.match_uninstalled_packages);
      if (info != null) {
        //packagemanager.delete_all_users
        final localintentreceiver localreceiver = new localintentreceiver();
        //这是卸载,不调用
//        getpi().uninstall(pkgname,
//            0x00000002,
//            localreceiver.getintentsender());
        localreceiver.getresult();
        assertuninstalled(info);
      }
    } catch (illegalargumentexception | packagemanager.namenotfoundexception e) {
      e.printstacktrace();
    }
  }

  private static void assertuninstalled(applicationinfo info) throws exception {
    file nativelibraryfile = new file(info.nativelibrarydir);
    log.e(tag, "native library directory " + info.nativelibrarydir
        + " should be erased" + nativelibraryfile.exists());
  }

  private void invokeinstallpackage(uri packageuri, int flags, genericreceiver receiver,
                   boolean shouldsucceed) {
    mcontext.registerreceiver(receiver, receiver.filter);
    synchronized (receiver) {
      final string inpath = packageuri.getpath();
      packageinstaller.session session = null;
      try {
        final packageinstaller.sessionparams sessionparams =
            new packageinstaller.sessionparams(packageinstaller.sessionparams.mode_full_install);
        try {
          //sessionparams.installflags = flags;
          field installflags = sessionparams.getclass().getdeclaredfield("installflags");
          installflags.set(sessionparams, flags);
        } catch (nosuchfieldexception e) {
          e.printstacktrace();
        } catch (illegalaccessexception e) {
          e.printstacktrace();
        }
        final int sessionid = getpi().createsession(sessionparams);
        session = getpi().opensession(sessionid);
        writesplittoinstallsession(session, inpath, "base.apk");
        final localintentreceiver localreceiver = new localintentreceiver();
        session.commit(localreceiver.getintentsender());
        final intent result = localreceiver.getresult();
        final int status = result.getintextra(packageinstaller.extra_status,
            packageinstaller.status_failure);
        if (shouldsucceed) {
          if (status != packageinstaller.status_success) {
            log.e(tag, "installation should have succeeded, but got code " + status);
          }
        } else {
          if (status == packageinstaller.status_success) {
            log.e(tag, "installation should have failed");
          }
          // we'll never get a broadcast since the package failed to install
          return;
        }
        // verify we received the broadcast
        long waittime = 0;
        while ((!receiver.isdone()) && (waittime < max_wait_time)) {
          try {
            receiver.wait(wait_time_incr);
            waittime += wait_time_incr;
          } catch (interruptedexception e) {
            log.i(tag, "interrupted during sleep", e);
          }
        }
        if (!receiver.isdone()) {
          log.e(tag, "timed out waiting for package_added notification");
        }
      } catch (illegalargumentexception | ioexception | remoteexception e) {
        log.e(tag, "failed to install package; path=" + inpath, e);
      } finally {
        ioutils.closequietly(session);
        mcontext.unregisterreceiver(receiver);
      }
    }
  }


  private abstract static class genericreceiver extends broadcastreceiver {
    private boolean doneflag = false;

    boolean received = false;

    intent intent;

    intentfilter filter;

    abstract boolean notifynow(intent intent);

    @override
    public void onreceive(context context, intent intent) {
      if (notifynow(intent)) {
        synchronized (this) {
          received = true;
          doneflag = true;
          this.intent = intent;
          notifyall();
        }
      }
    }

    public boolean isdone() {
      return doneflag;
    }

    public void setfilter(intentfilter filter) {
      this.filter = filter;
    }
  }

  class replacereceiver extends genericreceiver {
    string pkgname;

    final static int invalid = -1;

    final static int removed = 1;

    final static int added = 2;

    final static int replaced = 3;

    int removed = invalid;

    // for updated system apps only
    boolean update = false;

    replacereceiver(string pkgname) {
      this.pkgname = pkgname;
      filter = new intentfilter(intent.action_package_removed);
      filter.addaction(intent.action_package_added);
      if (update) {
        filter.addaction(intent.action_package_replaced);
      }
      filter.adddatascheme("package");
      super.setfilter(filter);
    }

    public boolean notifynow(intent intent) {
      string action = intent.getaction();
      uri data = intent.getdata();
      string installedpkg = data.getencodedschemespecificpart();
      if (pkgname == null || !pkgname.equals(installedpkg)) {
        return false;
      }
      if (intent.action_package_removed.equals(action)) {
        removed = removed;
      } else if (intent.action_package_added.equals(action)) {
        if (removed != removed) {
          return false;
        }
        boolean replacing = intent.getbooleanextra(intent.extra_replacing, false);
        if (!replacing) {
          return false;
        }
        removed = added;
        if (!update) {
          return true;
        }
      } else if (intent.action_package_replaced.equals(action)) {
        if (removed != added) {
          return false;
        }
        removed = replaced;
        return true;
      }
      return false;
    }
  }

}

就这一个类的封装,我也是看framework扣出来的

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网