App Center の配布 – Android アプリ内更新プログラム

重要

Visual Studio App Center は、2025 年 3 月 31 日に廃止される予定です。 完全に廃止されるまで Visual Studio App Center を引き続き使用できますが、移行を検討できる推奨される代替手段がいくつかあります。

詳細については、サポートタイムラインと代替手段に関するページを参照してください。

App Center 配布を使用すると、App Center 経由で配布するときに、ユーザーは新しいバージョンのアプリをインストールできます。 利用可能な新しいバージョンのアプリでは、SDK によって、新しいバージョンをダウンロードまたは延期するための更新ダイアログがユーザーに表示されます。 更新を選択すると、SDK によってアプリケーションの更新が開始されます。

警告

Google Play では、実行時に使用されていなくても、アプリ内更新コードは悪意のある動作と見なされます。 このセクションの指示にしたがって、配布 SDK のバリエーションを使用するか、アプリ内更新コードを含む Distribute SDK を完全に削除してから、アプリを Google Play に送信します。 これを行わないと、準拠していない状態になり、Google Play からアプリが削除される可能性があります。

注意

自動 UI テストを実行している場合、アプリ内更新を有効にすると、App Center バックエンドに対する認証が試行されるため、自動 UI テストはブロックされます。 UI テストで App Center Distribute を有効にしないことをお勧めします。

アプリ内更新プログラムをアプリに追加する

まだアプリケーションで SDK を設定して開始していない場合は、「 はじめ に」セクションに従います。

1. App Center の配布モジュールを追加する

App Center SDK はモジュール形式のアプローチで設計されています。開発者は、関心のあるサービスのモジュールのみを統合する必要があります。

  1. プロジェクトのアプリ レベルの build.gradle ファイル (app/build.gradle) を開き、 の後 apply pluginに次の行を追加します。

    dependencies {
       def appCenterSdkVersion = '5.0.4'
       implementation "com.microsoft.appcenter:appcenter-distribute:${appCenterSdkVersion}"
    }
    

    注意

    Android Gradle プラグインのバージョンが 3.0.0 未満の場合は、 実装コンパイルに置き換える必要があります。

  2. build.gradle ファイルを保存し、Android Studio で Gradle 同期をトリガーしてください。

  3. DownloadManager は、更新プログラムをダウンロードするために使用されます。 App Center SDK では、セキュリティを向上させるために TLS 1.2 が適用されます。

2. App Center の配布を開始する

App Center を使用するには、使用するモジュールにオプトインします。 既定では、モジュールは起動されません。SDK の起動時に、各モジュールを明示的に呼び出す必要があります。

Distribute クラスをメソッドに AppCenter.start() 追加して、App Center Distribute サービスを開始します。

AppCenter.start(getApplication(), "{Your App Secret}", Distribute.class);
AppCenter.start(application, "{Your App Secret}", Distribute::class.java)

上記のコード サンプルで、アプリ シークレットに置き換えてください {Your App Secret} 。 メソッドにクラスへの Distribute 参照を追加すると、Android Studio によって必要な import ステートメントが自動的に start() 提案されますが、クラス名が認識されないというエラーが表示された場合は、アクティビティ クラスの import ステートメントに次の行を追加します。

import com.microsoft.appcenter.AppCenter;
import com.microsoft.appcenter.distribute.Distribute;
import com.microsoft.appcenter.AppCenter
import com.microsoft.appcenter.distribute.Distribute

注意

Android 10 以降では、バックグラウンドからの起動アクティビティに制限があります。 バックグラウンドからのアクティビティの開始に関する制限に関する記事を参照してください。

注意

Android 10 (Go エディション) で実行されているアプリは 、SYSTEM_ALERT_WINDOW アクセス許可を受け取ることができません。 Go デバイスでのSYSTEM_ALERT_WINDOWに関する記事を参照してください。

注意

Android 11 以降では、 ACTION_MANAGE_OVERLAY_PERMISSION 意図によって常にユーザーが最上位の [設定] 画面に移動し、ユーザーはアプリのアクセス許可を SYSTEM_ALERT_WINDOW 付与または取り消すことができます。 Android 11 でのアクセス許可の更新に関する記事を参照してください。

Google Play ビルドを準備する

Google Play では、実行時に使用されていなくても、アプリ内更新コードは悪意のある動作と見なされます。 このセクションの指示にしたがって、配布 SDK のバリエーションを使用するか、アプリ内更新コードを含む Distribute SDK を完全に削除してから、アプリを Google Play に送信します。 これを行わないと、準拠していない状態になり、Google Play からアプリが削除される可能性があります。 簡単にするために、App Center Distribute SDK のバージョンにスタブ API が用意されているため、依存関係のスワップのみが変更されます。

  1. プロジェクトのアプリ レベルの build.gradle ファイル (app/build.gradle) を開きます。

  2. 製品のフレーバーを追加してビルド バリアントを構成します。

    android {
        flavorDimensions "distribute"
        productFlavors {
            appCenter {
                dimension "distribute"
            }
            googlePlay {
                dimension "distribute"
            }
        }
    }
    
  3. 依存関係ブロックを変更して、製品のフレーバーに基づいて異なる依存関係を使用します。

    dependencies {
        def appCenterSdkVersion = "5.0.4"
        appCenterImplementation "com.microsoft.appcenter:appcenter-distribute:${appCenterSdkVersion}"
        googlePlayImplementation "com.microsoft.appcenter:appcenter-distribute-play:${appCenterSdkVersion}"
    }
    
  4. build.gradle ファイルを保存し、Android Studio で Gradle 同期をトリガーしてください。

  5. ビルド バリアントは、ツール ウィンドウ バーの [Build > Select Build Variant ]\(ビルドバリアントの選択\) ドロップダウン メニューまたは [Build Variants]\(バリアントのビルド \) で変更できます。

ビルドバリアントの構成の詳細については、 Android のドキュメントを参照してください

プライベート配布グループを使用する

既定では、配布ではパブリック配布グループが使用されます。 プライベート配布グループを使用する場合は、API を使用して setUpdateTrack 明示的に設定する必要があります。

Distribute.setUpdateTrack(UpdateTrack.PRIVATE);
Distribute.setUpdateTrack(UpdateTrack.PRIVATE)

注意

既定値は UpdateTrack.PUBLIC です。 このメソッドは、メソッド呼び出しの AppCenter.start 前にのみ呼び出すことができます。 更新トラックの変更は、アプリケーション プロセスの再起動時に保持されないため、メソッドが呼び出しの前に常に AppCenter.start 呼び出されない場合は、既定でパブリックになります。

アプリがフォアグラウンド (および AppCenter.startの後Distribute.setUpdateTrack(UpdateTrack.PRIVATE);) にある場合は、ブラウザー ウィンドウが開いてユーザーを認証します。 以降のすべての更新チェックでは、プライベート トラックの最新リリースが取得されます。

ユーザーが プライベート トラックにいる場合は、認証が成功した後、メンバーになっているすべてのプライベート配布グループから最新のリリースが取得されることを意味します。 ユーザーが パブリック トラックにいる場合は、すべてのパブリック配布グループから最新のリリースを取得することを意味します。

自動更新の自動チェックを無効にする

既定では、SDK は新しいリリースを自動的にチェックします。

  • アプリケーションの起動時。
  • バックグラウンドに移動した後にアプリケーションがフォアグラウンドに入ったとき。
  • 以前に無効になっている場合は、配布モジュールを有効にする場合。

新しいリリースを手動でチェックする場合は、更新プログラムの自動チェックを無効にすることができます。 これを行うには、SDK の開始前に次のメソッドを呼び出します。

Distribute.disableAutomaticCheckForUpdate();
Distribute.disableAutomaticCheckForUpdate()

注意

このメソッドは、メソッド呼び出しの前に呼び出す AppCenter.start 必要があります。

その後、次の checkForUpdate セクションで説明する API を使用できます。

手動で更新プログラムを確認する

Distribute.checkForUpdate();
Distribute.checkForUpdate()

これにより、App Center に要求が送信され、新しいリリースが利用可能な場合に備えて更新ダイアログが表示されます。

注意

自動更新が有効になっている場合でも、更新呼び出しの手動チェックが機能します。 別のチェックが既に実行されている場合、更新の手動チェックは無視されます。 更新プログラムの手動チェックは、ユーザーが更新プログラムを延期した場合は処理されません (最新バージョンが必須の更新プログラムでない限り)。

アプリ内更新ダイアログをカスタマイズまたはローカライズする

1. テキストをカスタマイズまたはローカライズする

更新ダイアログに表示されるテキストを変更またはローカライズする場合は、独自のリソース文字列を簡単に指定できます。 このリソース ファイル内の文字列ファイルを確認します。 同じ文字列名/キーを使用し、独自のアプリ リソース ファイルのダイアログに反映されるローカライズされた値を指定します。

2. 更新ダイアログをカスタマイズする

インターフェイスを実装することで、既定の更新ダイアログの外観を DistributeListener カスタマイズできます。 次の例に示すように、 を呼び出す AppCenter.start 前にリスナーを登録する必要があります。

Distribute.setListener(new MyDistributeListener());
AppCenter.start(...);
Distribute.setListener(MyDistributeListener())
AppCenter.start(...)

SDK ダイアログをカスタムダイアログに置き換えるリスナー実装の例を次に示します。

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.net.Uri;

import com.microsoft.appcenter.distribute.Distribute;
import com.microsoft.appcenter.distribute.DistributeListener;
import com.microsoft.appcenter.distribute.ReleaseDetails;
import com.microsoft.appcenter.distribute.UpdateAction;

public class MyDistributeListener implements DistributeListener {

    @Override
    public boolean onReleaseAvailable(Activity activity, ReleaseDetails releaseDetails) {

        // Look at releaseDetails public methods to get version information, release notes text or release notes URL
        String versionName = releaseDetails.getShortVersion();
        int versionCode = releaseDetails.getVersion();
        String releaseNotes = releaseDetails.getReleaseNotes();
        Uri releaseNotesUrl = releaseDetails.getReleaseNotesUrl();

        // Build our own dialog title and message
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity);
        dialogBuilder.setTitle("Version " + versionName + " available!"); // you should use a string resource instead, this is just a simple example
        dialogBuilder.setMessage(releaseNotes);

        // Mimic default SDK buttons
        dialogBuilder.setPositiveButton(com.microsoft.appcenter.distribute.R.string.appcenter_distribute_update_dialog_download, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {

                // This method is used to tell the SDK what button was clicked
                Distribute.notifyUpdateAction(UpdateAction.UPDATE);
            }
        });

        // We can postpone the release only if the update isn't mandatory
        if (!releaseDetails.isMandatoryUpdate()) {
            dialogBuilder.setNegativeButton(com.microsoft.appcenter.distribute.R.string.appcenter_distribute_update_dialog_postpone, new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {

                    // This method is used to tell the SDK what button was clicked
                    Distribute.notifyUpdateAction(UpdateAction.POSTPONE);
                }
            });
        }
        dialogBuilder.setCancelable(false); // if it's cancelable you should map cancel to postpone, but only for optional updates
        dialogBuilder.create().show();

        // Return true if you're using your own dialog, false otherwise
        return true;
    }
    
    @Override
    public void onNoReleaseAvailable(Activity activity) {
        Toast.makeText(activity, activity.getString(R.string.no_updates_available), Toast.LENGTH_LONG).show();
    }
}
import android.app.Activity
import android.app.AlertDialog
import com.microsoft.appcenter.distribute.Distribute
import com.microsoft.appcenter.distribute.DistributeListener
import com.microsoft.appcenter.distribute.ReleaseDetails
import com.microsoft.appcenter.distribute.UpdateAction

class MyDistributeListener : DistributeListener {

    override fun onReleaseAvailable(activity: Activity, releaseDetails: ReleaseDetails): Boolean {

        // Look at releaseDetails public methods to get version information, release notes text or release notes URL
        val versionName = releaseDetails.shortVersion
        val versionCode = releaseDetails.version
        val releaseNotes = releaseDetails.releaseNotes
        val releaseNotesUrl = releaseDetails.releaseNotesUrl

        // Build our own dialog title and message
        val dialogBuilder = AlertDialog.Builder(activity)
        dialogBuilder.setTitle("Version $versionName available!") // you should use a string resource instead, this is just a simple example
        dialogBuilder.setMessage(releaseNotes)

        // Mimic default SDK buttons
        dialogBuilder.setPositiveButton(
            com.microsoft.appcenter.distribute.R.string.appcenter_distribute_update_dialog_download
        ) { dialog, which ->
            // This method is used to tell the SDK what button was clicked
            Distribute.notifyUpdateAction(UpdateAction.UPDATE)
        }

        // We can postpone the release only if the update isn't mandatory
        if (!releaseDetails.isMandatoryUpdate) {
            dialogBuilder.setNegativeButton(
                com.microsoft.appcenter.distribute.R.string.appcenter_distribute_update_dialog_postpone
            ) { dialog, which ->
                // This method is used to tell the SDK what button was clicked
                Distribute.notifyUpdateAction(UpdateAction.POSTPONE)
            }
        }
        dialogBuilder.setCancelable(false) // if it's cancelable you should map cancel to postpone, but only for optional updates
        dialogBuilder.create().show()

        // Return true if you're using your own dialog, false otherwise
        return true
    }

    override fun onNoReleaseAvailable(activity: Activity) {
        Toast.makeText(activity, activity.getString(R.string.no_updates_available), Toast.LENGTH_LONG).show()
    }
}

例に示すように、 を呼び出すか、リスナーが を返す場合は を呼び出Distribute.notifyUpdateAction(UpdateAction.UPDATE);Distribute.notifyUpdateAction(UpdateAction.POSTPONE);true必要があります。

を呼び出 notifyUpdateActionさない場合、コールバックはすべてのアクティビティ変更で繰り返されます。

ユーザー アクションが SDK に通知される前にアクティビティが変更された場合は、同じリリースでリスナーを再度呼び出すことができます。

この動作は、次のシナリオに対応するために必要です。

  • アプリケーションがバックグラウンドに送信され ( HOME キーを押すなど)、別のアクティビティで再開されます。
  • アクティビティは、アプリケーションを終了せずに別のアクティビティの対象となります (一部の通知をクリックするなど)。
  • その他の同様のシナリオ。

その場合、ダイアログをホストするアクティビティは、ユーザーの操作なしで置き換えられる可能性があります。 そのため、SDK はリスナーを再度呼び出して、カスタム ダイアログを復元できるようにします。

SDK で更新プログラムが確認され、現在使用されている更新プログラムよりも新しい更新プログラムが見つからない場合は、 onNoReleaseAvailable インターフェイスからの DistributeListener コールバックが呼び出されます。 これにより、このようなシナリオでカスタム コードを実行できます。 上記の例は、更新プログラムが見つからないときにトースト メッセージを表示する方法を示しています。

実行時に App Center の配布を有効または無効にする

実行時に App Center の配布を有効または無効にすることができます。 無効にした場合、SDK はアプリ内更新機能を提供しませんが、App Center ポータルで引き続き配布サービスを使用できます。

Distribute.setEnabled(false);
Distribute.setEnabled(false)

App Center Distribute を再度有効にするには、同じ API を使用しますが、パラメーターとして を渡します true

Distribute.setEnabled(true);
Distribute.setEnabled(true)

状態は、アプリケーションの起動間でデバイスのストレージに保持されます。

この API は非同期です。詳細については、 App Center の非同期 API ガイドを参照してください。

注意

このメソッドは、開始後 Distribute にのみ使用する必要があります。

App Center の配布が有効になっているかどうかを確認する

App Center の配布が有効になっているかどうかをチェックすることもできます。

Distribute.isEnabled();
Distribute.isEnabled()

この API は非同期です。詳細については、 App Center の非同期 API ガイドを参照してください。

注意

このメソッドは、開始後 Distribute にのみ使用する必要があり、常に開始前に戻ります false

デバッグ ビルドのアプリ内更新を有効にする

既定では、App Center ではリリース ビルドに対してのみアプリ内更新が有効になります。

デバッグ ビルドでアプリ内更新を有効にするには、 の前 AppCenter.startに次のメソッドを呼び出します。

Distribute.setEnabledForDebuggableBuild(true);
Distribute.setEnabledForDebuggableBuild(true)

注意

このメソッドはデバッグ ビルドにのみ影響し、リリース ビルドには影響しません。 デバッグ ビルドは、 フラグが android:debuggabletrue 設定されていることを意味します (これは通常、gradle の定義済みのデバッグ ビルド バリアントによって自動的に設定されます)。 それ以外の場合は、これはリリース ビルドです。

アプリ内更新はどのように機能しますか?

注意

アプリ内の更新プログラムを機能させるには、アプリ ビルドをリンクからダウンロードする必要があります。 IDE からインストールされている場合、または手動でインストールされている場合は機能しません。

アプリ内更新機能は次のように機能します。

  1. この機能は、App Center Distribute サービスを使用して配布される RELEASE ビルド (既定) でのみ機能します。

  2. SDK を統合し、アプリのリリース バージョンをビルドし、App Center にアップロードすると、その配布グループ内のユーザーにメールで新しいリリースの通知が送信されます。

  3. 各ユーザーがメールでリンクを開くと、アプリケーションがデバイスにインストールされます。 電子メール リンクを使用してインストールすることが重要です。サイドローディングはサポートされていません。 アプリケーションがリンクからダウンロードされると、SDK は Cookie から更新のために重要な情報をチェックに保存します。それ以外の場合、SDK にはそのキー情報がありません。

  4. アプリケーションによってトラックがプライベートに設定されている場合、ブラウザーが開き、ユーザーを認証し、アプリ内更新を有効にします。 パブリック トラックに切り替えても認証情報が有効なままで、後でもう一度プライベートに戻る場合でも、ブラウザーは再び開きません。 ブラウザー認証が成功すると、ユーザーは自動的にアプリケーションにリダイレクトされます。 トラックがパブリック (既定値) の場合は、次の手順が直接実行されます。

  5. アプリの新しいリリースでは、アプリ内更新ダイアログが表示され、次の場合にアプリケーションを更新するようユーザーに求められます。

    • または の値が versionCode 大きい
    • の等しい値 versionCode ですが、 の値 versionNameは異なります。

ヒント

同じ APK を 2 回目にアップロードした場合、バージョンが同一の場合、ダイアログは表示 されません

操作方法アプリ内更新プログラムをテストしますか?

リリース ビルド (App Center SDK の配布モジュールを使用) を App Center Portal にアップロードしてアプリ内更新プログラムをテストし、毎回バージョン番号を増やす必要があります。

  1. まだ作成していない場合は、App Center ポータルでアプリを作成します。
  2. 新しい配布グループを作成し、名前を付けて、アプリ内更新機能をテストすることを認識できるようにします。
  3. 自分自身 (またはアプリ内更新機能のテストに含めるすべてのユーザー) を追加します。 これには、App Center でそのアプリに使用されなかった新しいメール アドレスまたは捨てメール アドレスを使用します。 これにより、実際のテスト担当者のエクスペリエンスに近いエクスペリエンスが保証されます。
  4. App Center Distribute を含み、上記のようにセットアップ ロジックを含むアプリの新しいビルドを作成します。 グループがプライベートの場合は、 setUpdateTrack API の使用を開始する前に、アプリ内のプライベート更新トラックを設定することを忘れないでください。
  5. ポータルで [ 新しいリリースの配布 ] ボタンをクリックし、アプリのビルドをアップロードします。
  6. アップロードが完了したら、[次へ] をクリックし、そのアプリ配布の [宛先] として作成した配布グループを選択します。
  7. [配布] を確認し、アプリ内テスト グループにビルドを配布します。
  8. そのグループのPeopleは、アプリのテスト担当者への招待を受け取ります。 招待を承諾すると、モバイル デバイスから App Center ポータルからアプリをダウンロードできます。 アプリ内更新プログラムがインストールされたら、アプリ内更新プログラムをテストする準備が整います。
  9. アプリの を versionCode バンプします。
  10. アプリのリリース バージョンをビルドし、前の手順で行ったようにアプリの新しいビルドをアップロードし、前に作成した 配布グループに配布 します。 配布グループのメンバーは、次回アプリを起動すると、新しいバージョンの入力を求められます。

ヒント

配布グループなどに関する詳細な情報については、App Center の配布を利用する方法に関する情報をご覧ください。App Center Distribute を使用して、コードを追加せずに新しいバージョンのアプリを配布することは可能ですが、アプリのコードに App Center Distribute を追加すると、テスト担当者とユーザーがアプリ内更新エクスペリエンスを取得する際によりシームレスなエクスペリエンスが得られます。