App Center 散發– Android 應用程式內更新

App Center 散發可讓您的使用者在透過 App Center 發佈應用程式時,安裝新版本的應用程式。 使用新版本的應用程式時,SDK 將會向使用者顯示更新對話方塊,以下載或延期新的版本。 一旦選擇更新,SDK 就會開始更新您的應用程式。

警告

Google Play 將應用程式內更新程式碼視為惡意行為,即使在執行時間未使用也一樣。 如 本節 所述,使用散發 sdk 的變體,或完全移除包含應用程式內更新程式碼的散發 sdk,然後再將您的應用程式提交至 Google Play。 若未這麼做,可能會導致應用程式不相容,且無法從 Google Play 移除。

注意

如果您正在執行自動化的 UI 測試,啟用的應用程式內更新將會封鎖您的自動化 UI 測試,因為它們會嘗試對 App Center 後端進行驗證。 建議您不要為 UI 測試啟用 App Center 散發。

將應用程式內更新新增至您的應用程式

如果您尚未在您的應用程式中設定和啟動 SDK,請遵循 「開始使用」一節

1. 新增 App Center 散發模組

App Center SDK 是以模組化方法設計,而開發人員只需要整合其感興趣的服務模組。

  1. 開啟專案的應用層級 gradle 檔案 (app/build.gradle) ,然後在之後新增下列幾行 apply plugin

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

    注意

    如果 Android Gradle 外掛程式的版本低於3.0.0,您必須以 compile 取代 作為。

  2. 儲存 gradle 檔案,並確定在 Android Studio 中觸發 gradle 同步處理。

  3. DownloadManager 可用來下載更新。 App Center SDK 會強制執行 TLS 1.2 來改善安全性。

2. 啟動 App Center 散發

若要使用 App Center,請選擇您想要使用的模組 (s) 。 依預設,不會啟動任何模組,而且您必須在啟動 SDK 時明確地呼叫每個模組。

將散發類別新增至您的 AppCenter.start() 方法,以啟動 App Center 散發服務。

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

請確定您已 {Your App Secret} 在上述程式碼範例中,使用您的應用程式密碼來取代。 Android Studio 在您將類別的參考新增至方法之後,自動建議所需的匯入語句 Distribute start() ,但如果您看到無法辨識類別名稱的錯誤,請將下列幾行新增至活動類別中的 import 語句:

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

準備您的 Google Play 組建

Google Play 將應用程式內更新程式碼視為惡意行為,即使在執行時間未使用也一樣。 如本節所述,使用散發 SDK 的變體,或完全移除包含應用程式內更新程式碼的散發 SDK,然後再將您的應用程式提交至 Google Play。 若未這麼做,可能會導致應用程式不相容,且無法從 Google Play 移除。 為了讓您更輕鬆,我們會提供使用 stub Api 的 App Center 散發 SDK 版本,因此您唯一的變更是相依性交換。

  1. 開啟專案的應用層級 gradle 檔案 (app/build.gradle) 。

  2. 藉由新增產品類別來設定組建變體:

    android {
        flavorDimensions "distribute"
        productFlavors {
            appCenter {
                dimension "distribute"
            }
            googlePlay {
                dimension "distribute"
            }
        }
    }
    
  3. 修改相依性區塊,以根據產品類別使用不同的相依性:

    dependencies {
        def appCenterSdkVersion = "3.3.0"
        appCenterImplementation "com.microsoft.appcenter:appcenter-distribute:${appCenterSdkVersion}"
        googlePlayImplementation "com.microsoft.appcenter:appcenter-distribute-play:${appCenterSdkVersion}"
    }
    
  4. 儲存 gradle 檔案,並確定在 Android Studio 中觸發 gradle 同步處理。

  5. 您可以在 [組建 > 在 [工具] 視窗列中 選取 [建立變數 ] 下拉式功能表或 [ 組建 變化] 來變更組建變化。

您可以在 Android 檔中深入瞭解如何設定組建變體。

使用私人通訊群組

依預設,「散發」會使用公用通訊群組。 如果您想要使用私人通訊群組,您必須透過 API 明確設定它 setUpdateTrack

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

注意

預設值是 UpdateTrack.PUBLIC。 只能在方法呼叫之前呼叫這個方法 AppCenter.start 。 當應用程式處理常式重新開機時,不會保存更新播放軌的變更,因此如果在呼叫之前不一律呼叫方法 AppCenter.start ,則預設為公開。

當應用程式在) 之後的前景 (中 Distribute.setUpdateTrack(UpdateTrack.PRIVATE); AppCenter.start ,會開啟瀏覽器視窗來驗證使用者。 所有後續的更新檢查都會取得私人曲目上的最新版本。

如果使用者是在私用 曲目 上,這表示在成功驗證之後,他們會從其所屬的任何私人通訊群組取得最新版本。 如果使用者在 公開播放軌 上,表示他們會從任何公用通訊群組取得最新版本。

停用自動檢查更新

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 來取代 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 就會叫用 from 介面回呼。 這可讓您在這類案例中執行自訂程式碼。 上述範例顯示當找不到任何更新時,如何顯示快顯訊息。

在執行時間啟用或停用 App Center 散發

您可以在執行時間啟用和停用 App Center 散發。 如果您停用它,SDK 將不會提供任何應用程式內的更新功能,但您仍然可以在 App Center 入口網站中使用發佈服務。

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

若要再次啟用 App Center 散發,請使用相同的 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)

注意

這個方法只會影響 debug 組建,而且對發行組建沒有任何影響。 Debug build 表示旗標 android:debuggable 設定為 (, true 通常會透過 gradle 預先定義的 debug build variant) 自動設定。 否則,這會是發行組建。

應用程式內更新如何運作?

注意

若要讓應用程式內更新能夠運作,您應該從連結下載應用程式組建。 如果從 IDE 或以手動方式安裝,則無法運作。

應用程式內更新功能的運作方式如下:

  1. 這項功能僅適用于使用 App Center 散發 服務散發 (預設) 的 發行 組建。

  2. 當您整合 SDK、組建發行版本的應用程式,並上傳至 App Center 之後,該通訊群組中的使用者將會透過電子郵件收到新發行的通知。

  3. 當每位使用者在其電子郵件中開啟連結時,應用程式將會安裝在其裝置上。 請務必使用電子郵件連結來安裝-我們不支援側載。 從連結下載應用程式時,SDK 會儲存 cookie 中的重要資訊,以在稍後檢查更新,否則 SDK 沒有該金鑰資訊。

  4. 如果應用程式將追蹤設定為私用,瀏覽器將會開啟以驗證使用者,並啟用應用程式內更新。 只要驗證資訊仍然有效,即使在稍後切換回公開播放軌,然後再次回到私用,瀏覽器也不會再次開啟。 如果瀏覽器驗證成功,系統會自動將使用者重新導向回到應用程式。 如果這是預設) 的公用 (,則會直接執行下一個步驟。

  5. 應用程式的新版本會顯示應用程式內更新對話方塊,要求使用者更新您的應用程式(如果有的話):

    • 或的值較高 versionCode
    • 的相等值, versionCode 但不同的值 versionName

提示

如果您第二次上傳相同的 APK,則 會出現此對話方塊,因為版本完全相同。

如何? 測試應用程式內更新?

您必須將發行組建 (使用 App Center SDK 的散發模組) 至 App Center 入口網站來測試應用程式內更新,每次都增加版本號碼。

  1. 在 App Center 入口網站中建立您的應用程式(如果您尚未這樣做)。
  2. 建立新的通訊群組,並為其命名,以便您可以辨識其目的是要測試應用程式內的更新功能。
  3. 新增您自己的 (或您想要包含在應用程式內更新功能) 測試的所有人員。 針對此應用程式,請使用新的或捨棄的電子郵件地址,該位址不會用於 App Center 上的該應用程式。 這可確保您的經驗接近您真正的測試人員體驗。
  4. 建立應用程式的新組建,其中包含 App Center 散發 ,並包含如上所述的安裝邏輯。 如果群組是私用的,請記得先設定私用應用程式內更新追蹤,再開始使用 SETUPDATETRACK API
  5. 按一下入口網站中的 [ 發佈新的發行 ] 按鈕,然後上傳您的應用程式組建。
  6. 上傳完成後,請按 [下一步] ,然後選取您所建立的 通訊群組 作為該應用程式散發的 目的地
  7. 檢查散發套件,並將組建散發至您的應用程式內測試群組。
  8. 該群組中的人員會收到邀請,作為應用程式的測試人員。 他們接受邀請後,就可以從 App Center 入口網站中的行動裝置下載應用程式。 一旦安裝了應用程式內更新,您就可以開始測試應用程式內更新。
  9. versionCode讓您的應用程式更平滑。
  10. 建立應用程式的發行版本,並上傳應用程式的新組建(如同您在上一個步驟中所做的一樣),並將其散發至您稍早建立的 通訊群組 。 當應用程式下次啟動時,系統會提示通訊群組的成員輸入新版本。

提示

如需有關 通訊群組 的詳細資訊,請參閱如何 使用 App Center 散發的相關資訊。雖然您可以使用 App Center 散發來散發應用程式的新版本,而不需要新增任何程式碼,但是在應用程式的程式碼中新增 App Center 散發可讓您的測試人員和使用者獲得更順暢的體驗,因為它們會取得應用程式內的更新體驗。