Android9.0无法通过以下两种方式实现静默安装:

1.runtime执行shell cmd
2.PackageInstall 反射机制

但是Google已经给我们推荐了相关的APIDemos,所以建议大家多看看源码~

在frameworks/base/core/java/android/content/pm/PackageInstaller.java有段关于该类的介绍:

  1. The ApiDemos project contains examples of using this API:
  2. <code>ApiDemos/src/com/example/android/apis/content/InstallApk*.java</code>.
/**
 * Offers the ability to install, upgrade, and remove applications on the
 * device. This includes support for apps packaged either as a single
 * "monolithic" APK, or apps packaged as multiple "split" APKs.
 * <p>
 * An app is delivered for installation through a
 * {@link PackageInstaller.Session}, which any app can create. Once the session
 * is created, the installer can stream one or more APKs into place until it
 * decides to either commit or destroy the session. Committing may require user
 * intervention to complete the installation.
 * <p>
 * Sessions can install brand new apps, upgrade existing apps, or add new splits
 * into an existing app.
 * <p>
 * Apps packaged as multiple split APKs always consist of a single "base" APK
 * (with a {@code null} split name) and zero or more "split" APKs (with unique
 * split names). Any subset of these APKs can be installed together, as long as
 * the following constraints are met:
 * <ul>
 * <li>All APKs must have the exact same package name, version code, and signing
 * certificates.
 * <li>All APKs must have unique split names.
 * <li>All installations must contain a single base APK.
 * </ul>
 * <p>
 * ###########此处告诉开发者如何调用API安装apk##############
 * The ApiDemos project contains examples of using this API:
 * <code>ApiDemos/src/com/example/android/apis/content/InstallApk*.java</code>.  
 */
public class PackageInstaller

翻阅源码,InstallApk*.java相关的一共两个demo
InstallApkSessionApi.java //静默安装
InstallApk.java //普通安装,调用系统install intent进行安装

下面是InstallApkSessionApi.java的具体demo

package com.example.android.apis.content;

// Need the following import to get access to the app resources, since this
// class is in a sub-package.
import com.example.android.apis.R;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageInstaller;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;


/**
 * Demonstration of package installation and uninstallation using the package installer Session
 * API.
 *
 * @see InstallApk for a demo of the original (non-Session) API.
 */
public class InstallApkSessionApi extends Activity {
  private static final String PACKAGE_INSTALLED_ACTION =
      "com.example.android.apis.content.SESSION_API_PACKAGE_INSTALLED";

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.install_apk_session_api);

    // Watch for button clicks.
    Button button = (Button) findViewById(R.id.install);
    button.setOnClickListener(new OnClickListener() {
      public void onClick(View v) {
        PackageInstaller.Session session = null;
        try {
          PackageInstaller packageInstaller = getPackageManager().getPackageInstaller();
          PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
              PackageInstaller.SessionParams.MODE_FULL_INSTALL);
          int sessionId = packageInstaller.createSession(params);
          session = packageInstaller.openSession(sessionId);

          addApkToInstallSession("HelloActivity.apk", session);

          // Create an install status receiver.
          Context context = InstallApkSessionApi.this;
          Intent intent = new Intent(context, InstallApkSessionApi.class);
          intent.setAction(PACKAGE_INSTALLED_ACTION);

          //此处也可以使用getBoradcast或者getService回调通知
          PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
          IntentSender statusReceiver = pendingIntent.getIntentSender();

          // Commit the session (this will start the installation workflow).
          session.commit(statusReceiver);
        } catch (IOException e) {
          throw new RuntimeException("Couldn't install package", e);
        } catch (RuntimeException e) {
          if (session != null) {
            session.abandon();
          }
          throw e;
        }
      }
    });
  }

  private void addApkToInstallSession(String assetName, PackageInstaller.Session session)
      throws IOException {
    // It's recommended to pass the file size to openWrite(). Otherwise installation may fail
    // if the disk is almost full.
    try (OutputStream packageInSession = session.openWrite("package", 0, -1);
       InputStream is = getAssets().open(assetName)) {
      byte[] buffer = new byte[16384];
      int n;
      while ((n = is.read(buffer)) >= 0) {
        packageInSession.write(buffer, 0, n);
      }
    }
  }

  // Note: this Activity must run in singleTop launchMode for it to be able to receive the intent
  // in onNewIntent().
  @Override
  protected void onNewIntent(Intent intent) {
    Bundle extras = intent.getExtras();
    if (PACKAGE_INSTALLED_ACTION.equals(intent.getAction())) {
      int status = extras.getInt(PackageInstaller.EXTRA_STATUS);
      String message = extras.getString(PackageInstaller.EXTRA_STATUS_MESSAGE);

      switch (status) {
        case PackageInstaller.STATUS_PENDING_USER_ACTION:
          // This test app isn't privileged, so the user has to confirm the install.
          Intent confirmIntent = (Intent) extras.get(Intent.EXTRA_INTENT);
          startActivity(confirmIntent);
          break;

        case PackageInstaller.STATUS_SUCCESS:
          Toast.makeText(this, "Install succeeded!", Toast.LENGTH_SHORT).show();
          break;

        case PackageInstaller.STATUS_FAILURE:
        case PackageInstaller.STATUS_FAILURE_ABORTED:
        case PackageInstaller.STATUS_FAILURE_BLOCKED:
        case PackageInstaller.STATUS_FAILURE_CONFLICT:
        case PackageInstaller.STATUS_FAILURE_INCOMPATIBLE:
        case PackageInstaller.STATUS_FAILURE_INVALID:
        case PackageInstaller.STATUS_FAILURE_STORAGE:
          Toast.makeText(this, "Install failed! "   status   ", "   message,
              Toast.LENGTH_SHORT).show();
          break;
        default:
          Toast.makeText(this, "Unrecognized status received from installer: "   status,
              Toast.LENGTH_SHORT).show();
      }
    }
  }
}

另外,权限要求:

需要系统签名
permission

<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

 到此这篇关于Android P实现静默安装的方法示例(官方Demo)的文章就介绍到这了,更多相关Android P 静默安装 内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Android P实现静默安装的方法示例(官方Demo)的更多相关文章

  1. Android P实现静默安装的方法示例(官方Demo)

    这篇文章主要介绍了Android P实现静默安装,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

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

    这篇文章主要介绍了Android9.0 静默安装源码的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. 在Ubuntu 16.04 LTS上安装MySQL 5.7的非交互式(静默)

    MySQL5.7(实际上是5.6)改变了MysqL_secure_installation的工作方式.这使得很难找到Ubuntu16.04LTS的工作,静默,脚本安装.如何以脚本化非交互方式安全地安装MysqL?下面的完整脚本可以放入我们称之为“install.sh”的文件中,并执行以下操作:关于以下脚本:>请记住通过用密码替换第4行上的问号来设置MysqL_ROOT_PASSWORD.>如果以r

  4. CentOS 7.1静默安装11.2.0.3 64位单机数据库软件

    第1章CentOS7.1静默安装11.2.0.364位单机数据库软件1.1安装前的准备工作1.1.1软件准备1.1.2检查硬件注意这里的内存应该满足要求,不然可能引起数据库在安装过程中长时间的挂起等待。。。。1.1.3.1配置固定IPDEVICE=ens33IPADDR=192.168.59.51NETMASK=255.255.255.0NETWORK=192.168.59.0broADCAST=192.168.59.255GATEWAY=192.168.59.2ONBOOT=yesUSERCTL=noB

  5. CentOS静默安装Oracle数据库

    1、安装RPM包#yuminstallbinutils\compat-libstdc++-33\elfutils-libelf\elfutils-libelf-devel\expat\gcc\gcc-c++\glibc\glibc-common\glibc-devel\glibc-headers\libaio\libaio-devel\libgcc\libstdc++\libstdc++-devel\make\pdksh\sysstat\unixODBC\unixODBC-devel备注:部分机器估计li

  6. ColdFusion 9静默安装在Windows 8上调用GUI安装程序

    ColdFusion9GUI安装程序在Windows8上不起作用(这是一个已知问题).为了避免这种情况,我尝试使用“无声”安装程序,详见AdobeColdFusion博客:“PerformingasilentinstallationofColdFusion9”.我有这个installer.properties文件:这一切似乎都没问题……我对我在第二次猜测SILENT_WEbroOT_FOLDER值

  7. centos6.5上静默安装oracle11g

    centos6.5上静默安装oracle11g通过SSH远程连接oracle服务器主机,上传oracle11g安装包,在centos6.5上无图形化界面静默安装oracle11g。

  8. / v / qn参数对windows静默安装程序有什么作用?

    Thispage说要通过参数/s/v/qn进行静默安装.它提到/s的作用–静默安装–但不是/v/qn的作用.那它是做什么用的?为何奇怪的格式?

  9. windows – 如何在一个方向上“静默”TCP连接?

    我有2个通过TCP进行通信的应用程序.他们通过30秒的心跳保持联系.我需要模拟一方无法发送此心跳来测试超时的情况.Windows中有没有任何程序或工具来做这样的事情?断开以太网电缆的连接不起作用,因为程序从Windows接收断开连接事件有几种可能的方法可以做到这一点:>尝试在其中一台计算机上设置防火墙,并阻止来自另一方的数据包.>如果您无法安装防火墙,请尝试与上面相同的方法,使用另一个盒子(pc有两个接口,路由器……

  10. group-policy – GPO静默软件部署

    解决与组策略相关的问题时,您的第一站应该是客户端计算机的应用程序事件日志,后续是策略的结果集工具.从组策略调用时,WindowsInstaller将自动在受限用户界面模式下运行–您无需对MSI文件执行任何操作.(如果MSI作者是恶意或愚蠢的,他们可能会调用自定义操作,即使在有限的UI模式下运行也会显示UI,但这不太可能……

随机推荐

  1. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Android单选按钮RadioButton的使用详解

    今天小编就为大家分享一篇关于Android单选按钮RadioButton的使用详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

  3. 解决android studio 打包发现generate signed apk 消失不见问题

    这篇文章主要介绍了解决android studio 打包发现generate signed apk 消失不见问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  4. Android 实现自定义圆形listview功能的实例代码

    这篇文章主要介绍了Android 实现自定义圆形listview功能的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. 详解Android studio 动态fragment的用法

    这篇文章主要介绍了Android studio 动态fragment的用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Android用RecyclerView实现图标拖拽排序以及增删管理

    这篇文章主要介绍了Android用RecyclerView实现图标拖拽排序以及增删管理的方法,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下

  7. Android notifyDataSetChanged() 动态更新ListView案例详解

    这篇文章主要介绍了Android notifyDataSetChanged() 动态更新ListView案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

  8. Android自定义View实现弹幕效果

    这篇文章主要为大家详细介绍了Android自定义View实现弹幕效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. Android自定义View实现跟随手指移动

    这篇文章主要为大家详细介绍了Android自定义View实现跟随手指移动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Android实现多点触摸操作

    这篇文章主要介绍了Android实现多点触摸操作,实现图片的放大、缩小和旋转等处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部