App Center 散發 – Android 應用程式內更新
重要
Visual Studio App Center 已排定於 2025 年 3 月 31 日淘汰。 雖然您可以繼續使用 Visual Studio App Center,直到完全淘汰為止,但有數個建議的替代方案可以考慮移轉至。
App Center 散發套件可讓您的使用者透過 App Center 發佈應用程式時,安裝新版本的應用程式。 當有新版本的應用程式可用時,SDK 會向用戶顯示更新對話框,以下載或延後新版本。 一旦他們選擇更新,SDK 就會開始更新您的應用程式。
警告
Google Play 會將應用程式內更新程式代碼視為惡意行為,即使它未在運行時間使用也一樣。 使用 本節 中指示的散發 SDK 變體,或完全移除包含應用程式內更新程式代碼的散發 SDK,再將您的應用程式提交至 Google Play。 若無法這麼做,可能會導致應用程式不符合規範,並從Google Play 移除應用程式。
注意
如果您執行自動化 UI 測試,啟用的應用程式內更新將會封鎖自動化 UI 測試,因為它們會嘗試向 App Center 後端進行驗證。 建議您不要為您的UI測試啟用App Center散發。
如果您尚未在應用程式中設定並啟動 SDK,請遵循 開始使用 一節。
App Center SDK 是使用模組化方法所設計,開發人員只需要整合他們感興趣的服務模組。
開啟專案的 app 層級 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,您需要以編譯取代 實作。
儲存 build.gradle 檔案,並確定在 Android Studio 中觸發 Gradle 同步處理。
DownloadManager 可用來下載更新。 App Center SDK 會強制執行 TLS 1.2 以改善安全性。
若要使用 App Center,請加入您想要使用的模組 () 。 根據預設,不會啟動任何模組,而且您必須在啟動 SDK 時明確呼叫每個模組。
將 Distribute 類別新增至 AppCenter.start()
方法,以啟動 App Center 散發服務。
AppCenter.start(getApplication(), "{Your App Secret}", Distribute.class);
AppCenter.start(application, "{Your App Secret}", Distribute::class.java)
請確定您已使用您的應用程式秘密取代 {Your App Secret}
上述程式碼範例中的 。 當您將類別的參考新增至 Distribute
start()
方法時,Android Studio 會自動建議必要的 import 語句,但如果您看到無法辨識類別名稱的錯誤,請將下列幾行新增至活動類別中的 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 會將應用程式內更新程式代碼視為惡意行為,即使它未在運行時間使用也一樣。 使用本節中指示的散發 SDK 變體,或完全移除包含應用程式內更新程式代碼的散發 SDK,再將您的應用程式提交至 Google Play。 若無法這麼做,可能會導致應用程式不符合規範,並從Google Play 移除應用程式。 為了更容易,我們提供 App Center 散發 SDK 版本與 Stubbed API,因此您唯一的變更是相依性交換。
開啟專案的應用程式層級 build.gradle 檔案, (
app/build.gradle
) 。藉由新增產品類別來設定組建變體:
android { flavorDimensions "distribute" productFlavors { appCenter { dimension "distribute" } googlePlay { dimension "distribute" } } }
修改相依性區塊,以根據產品類別取用不同的相依性:
dependencies { def appCenterSdkVersion = "5.0.4" appCenterImplementation "com.microsoft.appcenter:appcenter-distribute:${appCenterSdkVersion}" googlePlayImplementation "com.microsoft.appcenter:appcenter-distribute-play:${appCenterSdkVersion}" }
儲存 build.gradle 檔案,並確定在 Android Studio 中觸發 Gradle 同步處理。
您可以在 [ 建 > 置][選取建置變體 ] 下拉功能表或工具視窗欄中的 [建置變體 ] 中變更組建變體。
您可以在 Android 檔中深入瞭解如何設定組建變體。
根據預設,「散發」會使用公用通訊群組。 如果您想要使用私人通訊群組,您必須透過 setUpdateTrack
API 明確設定。
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,並在有新版本可用時顯示更新對話方塊。
注意
即使啟用自動更新,更新呼叫的手動檢查仍可運作。 如果已經完成另一項檢查,則會忽略更新的手動檢查。 如果使用者已延後更新 (,除非最新版本是強制更新) ,否則不會處理更新的手動檢查。
如果您想要變更或本地化更新對話框中顯示的文字,您可以輕鬆地提供自己的資源字串。 查看 此資源檔中的字串檔案。 使用相同的字串名稱/索引鍵,並指定要反映在您自己應用程式資源檔中對話框的當地語系化值。
您可以實 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()
}
}
如範例所示,如果接聽程式傳true
回 ,您必須呼叫 Distribute.notifyUpdateAction(UpdateAction.UPDATE);
或 Distribute.notifyUpdateAction(UpdateAction.POSTPONE);
。
如果您未呼叫 notifyUpdateAction
,回呼會在每次活動變更時重複。
如果活動在收到 SDK 通知之前發生變更,則可以使用相同的版本再次呼叫接聽程式。
需要此行為,才能涵蓋下列案例:
- 您的應用程式會傳送至背景 (,例如按 HOME) 然後在不同的活動中繼續。
- 您的活動會由另一個活動所涵蓋,而不需離開應用程式 (,例如按下某些通知) 。
- 其他類似的案例。
在此情況下,裝載對話框的活動可能會被取代,而不需要用戶互動。 因此,SDK 會再次呼叫接聽程式,以便還原自定義對話方塊。
如果 SDK 會檢查更新,而且找不到任何更新比目前使用的更新還新的更新, onNoReleaseAvailable
則會從 DistributeListener
介面回呼叫用 。 這可讓您在這類案例中執行自定義程式碼。 上述範例示範如何在找不到更新時顯示快顯通知訊息。
您可以在執行時間啟用和停用 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 散發套件是否已啟用:
Distribute.isEnabled();
Distribute.isEnabled()
此 API 是異步的,您可以在 我們的 App Center 異步 API 指南 中深入瞭解。
注意
這個方法只能在啟動之後 Distribute
使用,它一律會在開始之前傳回 false
。
根據預設,App Center 只會針對發行組建啟用應用程式內更新。
若要在偵錯組建中啟用應用程式內更新,請在 之前 AppCenter.start
呼叫下列方法:
Distribute.setEnabledForDebuggableBuild(true);
Distribute.setEnabledForDebuggableBuild(true)
注意
這個方法只會影響偵錯組建,而且不會影響發行組建。
偵錯組建表示 android:debuggable
旗標會設定為 true
(,通常是由 gradle 預先定義的偵錯組建變體) 自動設定。 否則,這是發行組建。
注意
若要讓應用程式內更新能夠運作,應該從鏈接下載應用程式組建。 如果從 IDE 或手動安裝,它將無法運作。
應用程式內更新功能的運作方式如下:
這項功能預設僅適用於使用App Center散發服務散發的發行組建 () 。
一旦您整合 SDK、建置應用程式的發行版本並上傳至 App Center,該通訊群組中的使用者將會透過電子郵件收到新版本的通知。
當使用者在其電子郵件中開啟連結時,應用程式將會安裝在其裝置上。 請務必使用電子郵件連結來安裝 - 我們不支援側載。 從鏈接下載應用程式時,SDK 會儲存來自 Cookie 的重要資訊,以便稍後檢查更新,否則 SDK 沒有該重要資訊。
如果應用程式將追蹤設定為私人,瀏覽器將會開啟以驗證使用者並啟用應用程式內更新。 只要驗證資訊保持有效狀態,即使切換回公用曲目,稍後再切換回私人,瀏覽器也不會再次開啟。 如果瀏覽器驗證成功,用戶會自動重新導向回應用程式。 如果追蹤是公用 (,這是預設) ,則下一個步驟會直接發生。
新版本的應用程式會顯示應用程式內更新對話方塊,要求使用者更新您的應用程式是否為:
- 或的值
versionCode
較高 - 的相等值
versionCode
,但的值不同。versionName
- 或的值
提示
如果您第二次上傳相同的 APK, 對話框將不會顯示為 相同版本。
您必須上傳發行組建 (,以使用App Center SDK的散發模組) 至 App Center 入口網站,以測試應用程式內更新,每次增加版本號碼。
- 如果您尚未這麼做,請在App Center入口網站中建立您的應用程式。
- 建立新的通訊群組並將其命名為 ,因此您可以辨識其適用於測試應用程式內更新功能。
- 將自己新增 (或您想要包含在應用程式內更新功能測試的所有人員) 。 針對此情況使用新的或擲回電子郵件位址,但未用於App Center上的該應用程式。 這可確保您的體驗接近實際測試人員的體驗。
- 建立包含 App Center散發 的應用程式新組建,並包含上述的安裝邏輯。 如果群組是私人的,請記得在開始使用 setUpdateTrack API 之前設定私人應用程式內更新追蹤。
- 按兩下入口網站中的 [ 散發新版本 ] 按鈕,並上傳應用程式的組建。
- 上傳完成後,按 [ 下一步 ],然後選取您建立的 [通訊群組 ] 作為該應用程式散發的 [目的地 ]。
- 檢閱散發套件,並將組建散發至您的應用程式內測試群組。
- 該群組中的 人員 將會收到應用程式測試人員的邀請。 一旦他們接受邀請,就可以從其行動裝置從App Center入口網站下載應用程式。 安裝應用程式內更新之後,您就可以開始測試應用程式內更新。
versionCode
提高應用程式的 。- 建置應用程式的發行版本,並上傳您應用程式的新組建,就像您在上一個步驟中所做的一樣,並將它發佈至您稍早建立的 通訊群組 。 下次應用程式啟動時,將會提示通訊群組的成員輸入新版本。
提示
如需有關通訊群組等詳細資訊,請參閱如何使用App Center散發的相關信息。雖然您可以使用App Center散發來散發新版本的應用程式,而不新增任何程式代碼,但將App Center Distribute 新增至您應用程式的程式代碼,會導致測試人員和使用者在取得應用程式內更新體驗時獲得更順暢的體驗。