欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android P實(shí)現(xiàn)靜默安裝的方法示例(官方Demo)

 更新時(shí)間:2020年02月27日 08:31:36   作者:WagonWagon  
這篇文章主要介紹了Android P實(shí)現(xiàn)靜默安裝,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

Android9.0無(wú)法通過(guò)以下兩種方式實(shí)現(xiàn)靜默安裝:

1.runtime執(zhí)行shell cmd
2.PackageInstall 反射機(jī)制

但是Google已經(jīng)給我們推薦了相關(guān)的APIDemos,所以建議大家多看看源碼~

在frameworks/base/core/java/android/content/pm/PackageInstaller.java有段關(guān)于該類(lèi)的介紹:

  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>
 * ###########此處告訴開(kāi)發(fā)者如何調(diào)用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相關(guān)的一共兩個(gè)demo
InstallApkSessionApi.java //靜默安裝
InstallApk.java //普通安裝,調(diào)用系統(tǒng)install intent進(jìn)行安裝

下面是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回調(diào)通知
          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();
      }
    }
  }
}

另外,權(quán)限要求:

需要系統(tǒng)簽名
permission

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

 到此這篇關(guān)于Android P實(shí)現(xiàn)靜默安裝的方法示例(官方Demo)的文章就介紹到這了,更多相關(guān)Android P 靜默安裝 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android 更新RecyclerView的好方法

    Android 更新RecyclerView的好方法

    在使用RecyclerView的時(shí)候不免要修改RecyclerView的數(shù)據(jù),使用notifyDataSetChanged()來(lái)刷新界面,但是當(dāng)數(shù)據(jù)多,而只是修改了一點(diǎn)的數(shù)據(jù),或者刷新比較頻繁,這樣就會(huì)導(dǎo)致界面卡頓,用戶交互特別不好,這時(shí)可以使用RecyclerView方法解決,具體實(shí)現(xiàn)代碼大家參考下本文吧
    2017-06-06
  • Android自定義Chronometer實(shí)現(xiàn)短信驗(yàn)證碼秒表倒計(jì)時(shí)功能

    Android自定義Chronometer實(shí)現(xiàn)短信驗(yàn)證碼秒表倒計(jì)時(shí)功能

    這篇文章主要介紹了Android自定義ChronometerView實(shí)現(xiàn)類(lèi)似秒表倒計(jì)時(shí),短信驗(yàn)證碼倒計(jì)時(shí)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Android編程開(kāi)發(fā)實(shí)現(xiàn)多線程斷點(diǎn)續(xù)傳下載器實(shí)例

    Android編程開(kāi)發(fā)實(shí)現(xiàn)多線程斷點(diǎn)續(xù)傳下載器實(shí)例

    這篇文章主要介紹了Android編程開(kāi)發(fā)實(shí)現(xiàn)多線程斷點(diǎn)續(xù)傳下載器,涉及Android多線程,文件傳輸及斷點(diǎn)續(xù)傳的相關(guān)技巧,需要的朋友可以參考下
    2016-01-01
  • 在Android中訪問(wèn)WebService接口的方法

    在Android中訪問(wèn)WebService接口的方法

      最近公司有個(gè)項(xiàng)目需要從Android平臺(tái)訪問(wèn)WebService接口,實(shí)現(xiàn)向發(fā)布的函數(shù)傳遞對(duì)象。在網(wǎng)上找了一些資料,發(fā)現(xiàn)使用ksoap2可以調(diào)用WebService傳遞對(duì)象。
    2013-05-05
  • Android中傳遞圖片的2種方法

    Android中傳遞圖片的2種方法

    這篇文章主要介紹了Android中傳遞圖片的2種方法,本文分別給出種方法的操作代碼實(shí)例,需要的朋友可以參考下
    2015-04-04
  • Android底部導(dǎo)航欄的三種風(fēng)格實(shí)現(xiàn)

    Android底部導(dǎo)航欄的三種風(fēng)格實(shí)現(xiàn)

    這篇文章主要介紹了Android底部導(dǎo)航欄的三種風(fēng)格實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Android GridView實(shí)現(xiàn)動(dòng)畫(huà)效果實(shí)現(xiàn)代碼

    Android GridView實(shí)現(xiàn)動(dòng)畫(huà)效果實(shí)現(xiàn)代碼

    這篇文章主要介紹了 Android GridView實(shí)現(xiàn)動(dòng)畫(huà)效果實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Android異常 java.lang.IllegalStateException解決方法

    Android異常 java.lang.IllegalStateException解決方法

    這篇文章主要介紹了Android異常 java.lang.IllegalStateException解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Android Studio實(shí)現(xiàn)音樂(lè)播放器

    Android Studio實(shí)現(xiàn)音樂(lè)播放器

    這篇文章主要為大家詳細(xì)介紹了Android Studio實(shí)現(xiàn)音樂(lè)播放器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • android自定義View之復(fù)合控件

    android自定義View之復(fù)合控件

    這篇文章主要為大家詳細(xì)介紹了android自定義View之復(fù)合控件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06

最新評(píng)論