編輯:關於android開發
應用寶省流量更新(SDK),是應用寶提供給開發者輕松實現應用省流量更新的功能,可以幫助開發者縮短更新過程,提高應用下載量。在每次應用升級更新時,只需更新部分數據而無需下載完整大小的安裝包,幫用戶節省了流量,也大大提高了產品升級速度。
進入騰訊開放平台
點擊移動應用
,進入登錄界面
使用QQ號碼登錄或注冊新賬號,登錄後進入注冊開發者界面,可選擇注冊為個人或公司開發者
注冊成功後,進入管理中心,點擊創建應用
填寫應用信息,提交審核
郵件申請渠道號
添加引用TMAssistantSDK_selfUpdate_201407240950
修改AndroidManifest.xml
添加服務
添加權限
添加檢查更新代碼
SoftwareUpgrade.java
軟件升級管理對象
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import com.tencent.tmassistantsdk.common.TMAssistantDownloadSDKTaskState;
import com.tencent.tmassistantsdk.selfUpdateSDK.ITMSelfUpdateSDKListener;
import com.tencent.tmassistantsdk.selfUpdateSDK.TMSelfUpdateSDK;
import com.tencent.tmassistantsdk.selfUpdateSDK.TMSelfUpdateSDKUpdateInfo;
import java.text.DecimalFormat;
/**
* 軟件升級,利用應用寶的接口進行軟件版本檢查、軟件升級
*/
public class SoftwareUpgrade {
private Context ctx = null;
private static final String TAG = "SoftwareUpgrade";
/**
* AppID,應用上線後獲得
*/
private static final long APP_ID = 0000000000;
/**
* 渠道ID,郵件申請省流量更新後獲得
*/
private static final String CHANNEL_ID = "0000000";
/**
* 省流量更新SDK
*/
private TMSelfUpdateSDK sdk = null;
/**
* 線程操作對象
*/
private Handler handler = null;
/**
* 是否需要提醒更新(自動檢查更新時需要)
*/
private boolean isNeedNotify = false;
/**
* 軟件更新的信息
*/
private SoftwareUpdateInfo updateInfo = null;
public static SoftwareUpdateInfo getUpdateInfo() {
if (instance != null) {
return instance.updateInfo;
}
return null;
}
/**
* 更新提示對話框
*/
private UpgradeDialog updateDialog = null;
/**
* 單例模式
*/
private static SoftwareUpgrade instance = null;
public static SoftwareUpgrade getInstance() {
if (instance == null) {
instance = new SoftwareUpgrade();
}
if (instance.sdk == null) { // 初始化失敗,無法使用自動更新功能
instance = null;
}
return instance;
}
/**
* 初始化檢查更新(軟件啟動時調用)
*/
private SoftwareUpgrade() {
// 得到主線程的Looper實例
Looper looper = Looper.getMainLooper();
handler = new Handler(looper);
try {
sdk = TMSelfUpdateSDK.getInstance();
sdk.initTMSelfUpdateSDK(App.getInstance().getApplicationContext()
, APP_ID, CHANNEL_ID, selfUpdateSDKListener);
} catch (Exception ex) {
sdk = null;
LogUtil.d(TAG, "Init TMSelfUpdateSDK failed!");
}
}
/**
* 釋放(退出軟件時調用)
*/
public static void release() {
if (instance != null && instance.sdk != null) {
instance.sdk.destroySelfUpdateSDK(instance.selfUpdateSDKListener);
instance = null;
}
}
/**
* 檢查軟件是否需要更新(靜默檢查,不彈出提示對話框)
*/
public static void checkNeedUpdate() {
if (instance != null && instance.sdk != null) {
instance.isNeedNotify = false;
instance.sdk.checkNeedUpdate();
}
}
/**
* 檢查軟件是否需要更新(若有更新,則提醒用戶更新)
*/
public static void checkNeedUpdateNeedNotify(Context context) {
if (instance != null && instance.sdk != null) {
instance.ctx = context;
instance.isNeedNotify = true;
instance.sdk.checkNeedUpdate();
}
}
/**
* 開始省流量更新
* 1、彈出更新信息對話框,詢問用戶是否更新
* 2、若未安裝應用寶,詢問用戶是否安裝
* 3、跳轉到應用寶更新軟件
* @param ctx
*/
public static void startSaveUpdate(final Context ctx) {
if (instance != null && instance.sdk != null) {
instance.updateDialog = new UpgradeDialog(ctx);
instance.updateDialog.setVersion(instance.updateInfo.newVersion);
instance.updateDialog.setUpdateContent(instance.updateInfo.updateContent);
instance.updateDialog.setUpdateSize(instance.updateInfo.updateSize);
instance.updateDialog.setUpdateButtonOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
// 檢查應用寶是否安裝
int yybInstalled = instance.sdk.checkYYBInstalled();
if (yybInstalled == TMAssistantDownloadSDKTaskState.UN_INSTALLED) {
// 未安裝應用寶,提示用戶需要安裝應用寶
DialogUtil.showWarnDialog(ctx,
R.string.msg_no_yyb, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
instance.sdk.startSaveUpdate(ctx);
}
});
} else {
// 打開應用寶更新
instance.sdk.startSaveUpdate(ctx);
instance.updateDialog.dismiss();
}
} catch (Exception e) {
LogUtil.e(e);
}
}
});
}
}
/**
* 省流量更新調用
* 應用寶已經下載安裝完畢,回到調用方的頁面,調用方可以選擇是否調用該方法,call起應用寶下載管理頁去更新
*/
public static void onResume() {
if (instance != null && instance.sdk != null) {
instance.sdk.onResume(App.getInstance().getApplicationContext());
}
}
private ITMSelfUpdateSDKListener selfUpdateSDKListener = new ITMSelfUpdateSDKListener() {
/**
* 使用sdk自更新前,調用方法checkNeedUpdate檢查是否需要更新時回調
* 如果有更新包,則返回新包大小、增量包大小
* @param tmSelfUpdateSDKUpdateInfo 這個參數,當繼續往下走,下載 完成時,要傳回來給接口
*/
@Override
public void OnCheckNeedUpdateInfo(final TMSelfUpdateSDKUpdateInfo tmSelfUpdateSDKUpdateInfo) {
updateInfo = new SoftwareUpdateInfo();
if (tmSelfUpdateSDKUpdateInfo != null
&& tmSelfUpdateSDKUpdateInfo.getStatus() == TMSelfUpdateSDKUpdateInfo.STATUS_OK
&& tmSelfUpdateSDKUpdateInfo.getNewApkSize() > 0) {
// 解析版本號
String url = tmSelfUpdateSDKUpdateInfo.getUpdateDownloadUrl();
String version = "";
if (url != null && url.length() > 0) {
String[] temp = url.split("_");
if (temp.length > 2) {
version = temp[1];
}
}
updateInfo.hasNewVersion = true;
updateInfo.newVersion = version;
updateInfo.updateContent = tmSelfUpdateSDKUpdateInfo.getNewFeature();
updateInfo.updateSize = getDataSize(tmSelfUpdateSDKUpdateInfo.getNewApkSize());
}
if (isNeedNotify) { // 如果需要更新,則跳轉到關於界面
if (updateInfo.hasNewVersion) {
DialogUtil.showWarnDialog(ctx,
R.string.msg_has_new_version, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 跳轉到關於界面進行更新
MainActivity mainActivity = (MainActivity) ctx;
if (mainActivity != null) {
mainActivity.startActivity(new Intent(mainActivity, AboutActivity.class));
}
}
});
} else {
App.getInstance().toast(R.string.msg_current_lastest_version_software);
}
}
}
/**
* 省流量更新時回調
* 檢查應用寶狀態,若未安裝,則開始自動安裝
* @param url 指定任務的url
* @param state 下載狀態
* @param errorCode 錯誤碼
* @param errorMsg 錯誤描述
*/
@Override
public void OnDownloadYYBStateChanged(String url, final int state,int errorCode, String errorMsg) {
handler.post(new Runnable() {
@Override
public void run() {
switch (state) {
case TMAssistantDownloadSDKTaskState.DownloadSDKTaskState_WAITING:
if (updateDialog != null) {
updateDialog.startProgress();
updateDialog.setProgressText(R.string.msg_waiting_install_yyb);
}
break;
case TMAssistantDownloadSDKTaskState.DownloadSDKTaskState_DOWNLOADING:
// 下方提供進度更新顯示,此處不需要
// if (updateDialog != null) {
// updateDialog.setProgressText("正在下載應用寶");
// }
break;
case TMAssistantDownloadSDKTaskState.DownloadSDKTaskState_PAUSED:
// if (updateDialog != null) {
// updateDialog.setProgressText("應用寶下載暫停");
// }
break;
case TMAssistantDownloadSDKTaskState.DownloadSDKTaskState_SUCCEED:
if (updateDialog != null) {
updateDialog.setProgressText(R.string.msg_download_yyb_success);
updateDialog.dismiss();
}
break;
case TMAssistantDownloadSDKTaskState.DownloadSDKTaskState_FAILED:
if (updateDialog != null) {
updateDialog.dismiss();
App.getInstance().toast(R.string.msg_download_yyb_failed);
}
break;
default:
// App.getInstance().toast(state);
break;
}
}
});
}
/**
* 省流量更新時回調
* 下載應用寶的進度
* @param url 指定任務的url
* @param receiveDataLen 已經接收的數據長度
* @param totalDataLen 全部需要接收的數據長度(如果無法獲取目標文件的總長度,此參數返回-1)
*/
@Override
public void OnDownloadYYBProgressChanged(final String url,final long receiveDataLen, final long totalDataLen) {
handler.post(new Runnable() {
@Override
public void run() {
if (updateDialog != null) {
updateDialog.setProgress((int) (receiveDataLen * 100 / (double) totalDataLen));
updateDialog.setProgressText(
getDataSize(receiveDataLen) + " / " + getDataSize(totalDataLen));
}
}
});
}
};
/**
* 計算數據大小,將bit轉換為k或M的單位輸出
* @param dataSize
* @return
*/
private String getDataSize(long dataSize) {
long kb = dataSize / 1024; // 單位k
if (kb < 1024) {
return kb + "k";
}
double mb = dataSize / 1024.0 / 1024.0 + 0.05; // 轉換為M,保留一位小數,四捨五入
return new DecimalFormat(".0").format(mb) + "M";
}
/**
* 軟件更新信息
*/
public class SoftwareUpdateInfo {
/**
* 是否有新版本
*/
public boolean hasNewVersion = false;
/**
* 新版本號
*/
public String newVersion = "";
/**
* 更新內容
*/
public String updateContent = "";
/**
* 更新大小
*/
public String updateSize = "";
}
}
UpgradeDialog.java
軟件升級信息對話框
import android.app.AlertDialog;
import android.content.Context;
import android.support.annotation.StringRes;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
public class UpgradeDialog {
private Context ctx = null;
private AlertDialog dialog = null;
private TextView tvVersion = null;
private TextView tvUpdateContent = null;
private LinearLayout layoutUpdateButton = null;
private Button btnNotUpdate = null;
private Button btnUpdate = null;
private LinearLayout layoutUpdateProgress = null;
private ProgressBar progressBar = null;
private TextView tvUpdateProgress = null;
public UpgradeDialog(Context context) {
ctx = context;
LayoutInflater layoutInflater = LayoutInflater.from(ctx);
View view = layoutInflater.inflate(R.layout.dialog_notify_update, null);
if (view != null) {
tvVersion = (TextView) view.findViewById(R.id.tv_version);
tvUpdateContent = (TextView) view.findViewById(R.id.tv_update_content);
layoutUpdateButton = (LinearLayout) view.findViewById(R.id.layout_update_button);
btnNotUpdate = (Button) view.findViewById(R.id.btn_not_update);
btnUpdate = (Button) view.findViewById(R.id.btn_update);
layoutUpdateProgress = (LinearLayout) view.findViewById(R.id.layout_update_progress);
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
tvUpdateProgress = (TextView) view.findViewById(R.id.tv_update_progress);
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setTitle(R.string.layout_update_software_notify);
builder.setView(view);
dialog = builder.create();
dialog.setCancelable(false);
dialog.show();
btnNotUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
progressBar.setMax(100);
}
}
public void setVersion(String version) {
if (tvVersion != null) {
tvVersion.setText(version);
}
}
public void setUpdateContent(String updateContent) {
if (tvUpdateContent != null) {
tvUpdateContent.setText(updateContent);
}
}
public void setUpdateSize(String newApkSize) {
if (btnUpdate != null) {
btnUpdate.setText(ctx.getString(R.string.layout_update_software_update_now, newApkSize));
}
}
public void setUpdateButtonOnClickListener(View.OnClickListener listener) {
if (btnUpdate != null) {
btnUpdate.setOnClickListener(listener);
}
}
public void dismiss() {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
}
public void setProgress(int value) {
if (progressBar != null) {
progressBar.setProgress(value);
}
}
public void setProgressText(@StringRes int progress) {
if (tvUpdateProgress != null) {
tvUpdateProgress.setText(progress);
}
}
public void setProgressText(String progress) {
if (tvUpdateProgress != null) {
tvUpdateProgress.setText(progress);
}
}
public void startProgress() {
if (layoutUpdateProgress != null) {
layoutUpdateProgress.setVisibility(View.VISIBLE);
}
if (progressBar != null) {
progressBar.setProgress(0);
}
if (layoutUpdateButton != null) {
layoutUpdateButton.setVisibility(View.GONE);
}
}
}
dialog_notify_update.xml
軟件升級提示界面
MainActivity.xml
主界面中初始化和釋放軟件升級管理對象
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainView = LayoutInflater.from(this).inflate(R.layout.activity_main, null);
setContentView(mainView);
// 初始化軟件更新對象
SoftwareUpgrade softwareUpgrade = SoftwareUpgrade.getInstance();
if (softwareUpgrade == null) {
app.setCanAutoUpdate(false); // 公共變量,用於標識自動更新對象是否初始化成功,若不成功,則屏蔽相關功能
app.toast(R.string.msg_init_auto_update_software_failed);
} else {
app.setCanAutoUpdate(true);
// 檢查軟件更新
if (app.isAutoCheckSoftwareUpdate()) { // 是否開啟自動檢查更新功能
SoftwareUpgrade.checkNeedUpdateNeedNotify(this); // 彈框提醒更新
} else {
SoftwareUpgrade.checkNeedUpdate(); // 不彈框提醒
}
}
}
@Override
protected void onDestroy() {
// 釋放軟件更新對象
SoftwareUpgrade.release();
super.onDestroy();
}
}
SoftwareSetupFragment.java
軟件設置界面,包含“自動檢查更新”開關配置,關於。
public class SoftwareSetupFragment extends BaseFragment {
@Bind(R.id.btn_auto_check_software_update)
ButtonSettingLayout btnAutoCheckSoftwareUpdate;
@Bind(R.id.btn_about)
ButtonSettingLayout btnAbout;
@Override
protected int getContentLayoutId() {
return R.layout.fragment_software_setup;
}
/**
* 自動檢查更新的配置key
*/
public static final String PREF_AUTO_CHECK_SOFTWARE_UPDATE = "auto_check_software_update";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = super.onCreateView(inflater, container, savedInstanceState);
initialize(rootView);
return rootView;
}
@Override
protected void initialize(View rootView) {
ButterKnife.bind(this, rootView);
// 自動檢查軟件更新
btnAutoCheckSoftwareUpdate.setVisibility(app.isCanAutoUpdate() ? View.VISIBLE : View.GONE);
btnAutoCheckSoftwareUpdate.setChecked(app.isAutoCheckSoftwareUpdate());
btnAutoCheckSoftwareUpdate.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
prefs.edit().putBoolean(PREF_AUTO_CHECK_SOFTWARE_UPDATE, isChecked).commit();
app.setAutoCheckSoftwareUpdate(isChecked);
}
});
// 關於
if (SoftwareUpgrade.getUpdateInfo() != null && SoftwareUpgrade.getUpdateInfo().hasNewVersion) {
btnAbout.setIconColor(Color.RED);
}
btnAbout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
parent.startActivityFromFragment(SoftwareSetupFragment.this,
new Intent(getActivity(), AboutActivity.class), 0);
}
});
}
@Override
protected void release() {
ButterKnife.unbind(this);
}
}
AboutActivity.java
關於界面,提供軟件升級功能
public class AboutActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
btnCheckUpdate.setVisibility(app.isCanAutoUpdate() ? View.VISIBLE : View.GONE);
if (SoftwareUpgrade.getUpdateInfo() != null) {
if (SoftwareUpgrade.getUpdateInfo().hasNewVersion) {
btnCheckUpdate.setText(getString(
R.string.layout_update_software_update_now, SoftwareUpgrade.getUpdateInfo().newVersion));
btnCheckUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SoftwareUpgrade.startSaveUpdate(AboutActivity.this);
}
});
} else {
btnCheckUpdate.setText(R.string.msg_current_lastest_version_software);
}
}
}
@Override
protected void onResume() {
super.onResume();
SoftwareUpgrade.onResume();
}
}
strings.xml
初始化自動更新功能失敗!
當前為最新版本
更新(%1$s)
軟件升級提醒
新版特性
暫不更新
未安裝應用寶,將開始安裝應用寶!
軟件有新版本,是否更新?
等待安裝應用寶
應用寶下載成功,開始安裝應用寶
下載應用寶失敗,請檢查網絡連接
進入應用
點擊基礎服務中的更多
,可進入省流量更新
省流量更新頁面中,點擊查看詳情
,進入省流量更新詳情頁<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjxpbWcgYWx0PQ=="查看詳情" src="http://www.bkjia.com/uploads/allimg/160409/0419222215-13.png" title="\" />
Activity詳解二 activity數據傳遞,activity詳解首先看效果圖: 1.Bundle類的作用 Bundle類用作攜帶數據,它類似於M
MVP模式在Android項目中的使用,mvp模式android項目 以前在寫項目的時候,沒有過多考慮架構模式的問題,因為之前一直做J2EE開發,而J2EE都是采用MV
ArrayAdapter適配器的用法,模擬QQ發消息界面。,arrayadapter適配器 1 import java.util.ArrayList; 2 3 im
安卓應用的界面編程(2),安卓應用界面編程第一組UI組件:布局管理器(以ViewGroup為基類派生的布局管理器) 1.線性布局 LinearLayout類 1 <
安卓開發學習經歷2--《第一行代碼》coolweather項目SQL語句