+[android] playground auto check for update
Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/1294abff Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/1294abff Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/1294abff Branch: refs/heads/master Commit: 1294abffcde6dab79a0521e917fb444d9a6116fd Parents: 0763bd4 Author: misakuo <misa...@apache.org> Authored: Fri Mar 9 17:32:27 2018 +0800 Committer: misakuo <misa...@apache.org> Committed: Fri Mar 9 17:32:27 2018 +0800 ---------------------------------------------------------------------- .../playground/app/src/main/AndroidManifest.xml | 14 ++ .../java/com/alibaba/weex/IndexActivity.java | 3 + .../alibaba/weex/update/CheckForUpdateUtil.java | 140 +++++++++++++++++++ .../com/alibaba/weex/update/Downloader.java | 112 +++++++++++++++ .../com/alibaba/weex/update/UpdateService.java | 108 ++++++++++++++ .../res/layout/common_update_notify_dialog.xml | 24 ++++ .../app/src/main/res/values-zh-rCN/strings.xml | 8 ++ .../app/src/main/res/values/strings.xml | 8 ++ .../app/src/main/res/xml/filepaths.xml | 6 + 9 files changed, 423 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/1294abff/android/playground/app/src/main/AndroidManifest.xml ---------------------------------------------------------------------- diff --git a/android/playground/app/src/main/AndroidManifest.xml b/android/playground/app/src/main/AndroidManifest.xml index 6e7338a..22128e2 100755 --- a/android/playground/app/src/main/AndroidManifest.xml +++ b/android/playground/app/src/main/AndroidManifest.xml @@ -118,6 +118,20 @@ under the License. android:stateNotNeeded="true"/> <activity android:name="com.alibaba.weex.BenchmarkActivity" android:screenOrientation="portrait"/> + + <service + android:name=".update.UpdateService" + android:exported="false" /> + + <provider + android:name="android.support.v4.content.FileProvider" + android:authorities="com.alibaba.weex.fileprovider" + android:grantUriPermissions="true" + android:exported="false"> + <meta-data + android:name="android.support.FILE_PROVIDER_PATHS" + android:resource="@xml/filepaths" /> + </provider> </application> </manifest> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/1294abff/android/playground/app/src/main/java/com/alibaba/weex/IndexActivity.java ---------------------------------------------------------------------- diff --git a/android/playground/app/src/main/java/com/alibaba/weex/IndexActivity.java b/android/playground/app/src/main/java/com/alibaba/weex/IndexActivity.java index 3cc1c5e..e4bbe99 100644 --- a/android/playground/app/src/main/java/com/alibaba/weex/IndexActivity.java +++ b/android/playground/app/src/main/java/com/alibaba/weex/IndexActivity.java @@ -40,6 +40,7 @@ import android.widget.TextView; import android.widget.Toast; import com.alibaba.weex.commons.AbstractWeexActivity; +import com.alibaba.weex.update.CheckForUpdateUtil; import com.google.zxing.client.android.CaptureActivity; import com.taobao.weex.WXRenderErrorCode; import com.taobao.weex.WXSDKEngine; @@ -103,6 +104,8 @@ public class IndexActivity extends AbstractWeexActivity { }; LocalBroadcastManager.getInstance(this).registerReceiver(mReloadReceiver, new IntentFilter(WXSDKEngine.JS_FRAMEWORK_RELOAD)); + + CheckForUpdateUtil.checkForUpdate(this); } @Override http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/1294abff/android/playground/app/src/main/java/com/alibaba/weex/update/CheckForUpdateUtil.java ---------------------------------------------------------------------- diff --git a/android/playground/app/src/main/java/com/alibaba/weex/update/CheckForUpdateUtil.java b/android/playground/app/src/main/java/com/alibaba/weex/update/CheckForUpdateUtil.java new file mode 100644 index 0000000..219c132 --- /dev/null +++ b/android/playground/app/src/main/java/com/alibaba/weex/update/CheckForUpdateUtil.java @@ -0,0 +1,140 @@ +package com.alibaba.weex.update; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.TextView; + +import com.alibaba.weex.R; +import com.taobao.weex.WXEnvironment; +import com.taobao.weex.WXSDKManager; +import com.taobao.weex.adapter.IWXHttpAdapter; +import com.taobao.weex.common.WXRequest; +import com.taobao.weex.common.WXResponse; +import com.taobao.weex.utils.WXLogUtils; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.List; +import java.util.Map; + +/** + * Created by moxun on 2018/3/9. + */ + +public class CheckForUpdateUtil { + public static void checkForUpdate(final Context context) { + PackageManager pm = context.getPackageManager(); + try { + PackageInfo info = pm.getPackageInfo(context.getPackageName(), 0); + if (info != null) { + int versionCode = info.versionCode; + String updateUrl = "http://dotwe.org/release/latest?v=" + versionCode; + WXRequest request = new WXRequest(); + request.method = "GET"; + request.url = updateUrl; + WXLogUtils.d("Update", "check for update: " + versionCode); + WXSDKManager.getInstance().getIWXHttpAdapter().sendRequest(request, new IWXHttpAdapter.OnHttpListener() { + @Override + public void onHttpStart() { + + } + + @Override + public void onHeadersReceived(int statusCode, Map<String, List<String>> headers) { + + } + + @Override + public void onHttpUploadProgress(int uploadProgress) { + + } + + @Override + public void onHttpResponseProgress(int loadedLength) { + + } + + @Override + public void onHttpFinish(final WXResponse response) { + if (!response.statusCode.equals("200")) { + WXLogUtils.e("Update", "failed: " + response.statusCode); + return; + } + WXSDKManager.getInstance().getWXRenderManager().postOnUiThread(new Runnable() { + @Override + public void run() { + String s = new String(response.originalData); + if (!TextUtils.isEmpty(s)) { + try { + WXLogUtils.d("Update", s); + JSONObject object = new JSONObject(s); + JSONObject params = object.optJSONObject("params"); + if (params != null) { + boolean hasUpdate = params.optBoolean("hasUpdate", false); + if (hasUpdate) { + String version = params.optString("version", "latest"); + String updateDate = params.optString("updateDate", ""); + final String updateUrl = params.optString("updateUrl", ""); + String updateDescription = params.optString("updateDescription", null); + + AlertDialog.Builder builder = new AlertDialog.Builder(context); + + View view = LayoutInflater.from(context).inflate(R.layout.common_update_notify_dialog, null); + TextView textView = (TextView) view.findViewById(R.id.common_update_dialog_msg); + textView.setText(getMsg(version, updateDate, updateDescription)); + builder.setCancelable(false) + .setView(view) + .setPositiveButton(R.string.update_now, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + UpdateService.startActionUpdate(context, updateUrl); + dialog.dismiss(); + } + }); + + builder.setNegativeButton(R.string.update_remind_later, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + + builder.create().show(); + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + }, 0); + } + }); + } + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + } + + private static String getMsg(String v, String date, String desc) { + StringBuilder sb = new StringBuilder(); + sb.append(getStringRes(R.string.update_version)).append(v).append("\n") + .append(getStringRes(R.string.update_date)).append(date).append("\n") + .append(getStringRes(R.string.update_desc)).append(desc); + return sb.toString(); + } + + public static String getStringRes(int id) { + if (WXEnvironment.getApplication() != null) { + return WXEnvironment.getApplication().getString(id); + } + return ""; + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/1294abff/android/playground/app/src/main/java/com/alibaba/weex/update/Downloader.java ---------------------------------------------------------------------- diff --git a/android/playground/app/src/main/java/com/alibaba/weex/update/Downloader.java b/android/playground/app/src/main/java/com/alibaba/weex/update/Downloader.java new file mode 100644 index 0000000..8356652 --- /dev/null +++ b/android/playground/app/src/main/java/com/alibaba/weex/update/Downloader.java @@ -0,0 +1,112 @@ +package com.alibaba.weex.update; + +import com.squareup.okhttp.Callback; +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.Response; +import com.taobao.weex.WXSDKManager; +import com.taobao.weex.utils.WXLogUtils; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Created by moxun on 2018/3/9. + */ + +public class Downloader { + + public static void download(String url, final DownloadCallback callback) { + OkHttpClient client = new OkHttpClient(); + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + client.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(Request request, IOException e) { + callback.onError(e); + } + + @Override + public void onResponse(Response response) throws IOException { + callback.handleResponse(response); + } + }); + } + + public abstract static class DownloadCallback { + private String destDirPath; + private String destFileName; + + public abstract void onProgress(float progress); + + public abstract void onResponse(File file); + + public abstract void onError(Exception e); + + public DownloadCallback(String destDirPath, String destFileName) { + this.destDirPath = destDirPath; + this.destFileName = destFileName; + } + + private void handleResponse(Response response) throws IOException { + final File file = saveToFile(response); + if (file != null && file.exists() && file.length() > 0) { + runOnUiThread(new Runnable() { + @Override + public void run() { + onResponse(file); + } + }); + } else { + onError(new RuntimeException("Failed to save file")); + } + } + + private File saveToFile(Response response) throws IOException { + InputStream is = null; + byte[] buf = new byte[40960]; + int len = 0; + FileOutputStream fos = null; + try { + is = response.body().byteStream(); + final long total = response.body().contentLength(); + long sum = 0; + + WXLogUtils.e(total + ""); + + File dir = new File(destDirPath); + if (!dir.exists()) { + dir.mkdirs(); + } + File file = new File(dir, destFileName); + fos = new FileOutputStream(file); + while ((len = is.read(buf)) != -1) { + sum += len; + fos.write(buf, 0, len); + final long finalSum = sum; + + runOnUiThread(new Runnable() { + @Override + public void run() { + onProgress(finalSum * 1.0f / total); + } + }); + } + fos.flush(); + return file; + } finally { + if (is != null) is.close(); + if (fos != null) fos.close(); + } + } + + private void runOnUiThread(Runnable task) { + WXSDKManager.getInstance().getWXRenderManager().postOnUiThread(task, 0); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/1294abff/android/playground/app/src/main/java/com/alibaba/weex/update/UpdateService.java ---------------------------------------------------------------------- diff --git a/android/playground/app/src/main/java/com/alibaba/weex/update/UpdateService.java b/android/playground/app/src/main/java/com/alibaba/weex/update/UpdateService.java new file mode 100644 index 0000000..390ee47 --- /dev/null +++ b/android/playground/app/src/main/java/com/alibaba/weex/update/UpdateService.java @@ -0,0 +1,108 @@ +package com.alibaba.weex.update; + +import android.app.IntentService; +import android.app.Notification; +import android.app.NotificationManager; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.support.v4.content.FileProvider; +import android.support.v7.app.NotificationCompat; +import android.widget.Toast; + +import com.alibaba.weex.BuildConfig; +import com.alibaba.weex.R; +import com.taobao.weex.WXEnvironment; +import com.taobao.weex.WXSDKManager; +import com.taobao.weex.utils.WXLogUtils; + +import java.io.File; + +public class UpdateService extends IntentService { + + private static final String ACTION_UPDATE = "com.taobao.weex.service.action.UPDATE"; + private static final String EXTRA_URL = "com.taobao.weex.service.extra.URL"; + private final int NOTIFY_ID = 10006024; + + private NotificationManager manager; + private NotificationCompat.Builder builder; + + public static void startActionUpdate(Context context, String url) { + Intent intent = new Intent(context, UpdateService.class); + intent.setAction(ACTION_UPDATE); + intent.putExtra(EXTRA_URL, url); + context.startService(intent); + } + + public UpdateService() { + super("UpdateService"); + } + + @Override + protected void onHandleIntent(Intent intent) { + if (intent != null) { + final String action = intent.getAction(); + if (ACTION_UPDATE.equals(action)) { + final String url = intent.getStringExtra(EXTRA_URL); + handleActionUpdate(url); + } + } + } + + private void handleActionUpdate(String url) { + manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + builder = new NotificationCompat.Builder(this); + builder.setContentTitle(CheckForUpdateUtil.getStringRes(R.string.update_downloading)) + .setContentText(CheckForUpdateUtil.getStringRes(R.string.update_progress) + " 0%") + .setTicker(CheckForUpdateUtil.getStringRes(R.string.update_downloading)) + .setWhen(System.currentTimeMillis()) + .setPriority(Notification.PRIORITY_DEFAULT) + .setSmallIcon(R.mipmap.ic_launcher) + .setProgress(100, 0, false); + manager.notify(NOTIFY_ID, builder.build()); + + WXLogUtils.e("Update", "start download"); + Downloader.download(url, new Downloader.DownloadCallback(getCacheDir().getAbsolutePath(), "playground.apk") { + + @Override + public void onProgress(float progress) { + if (progress * 100 - progress >= 1) { + int p = (int) (progress * 100); + builder.setContentText(CheckForUpdateUtil.getStringRes(R.string.update_progress) + p + "%"); + builder.setProgress(100, p, false); + manager.notify(NOTIFY_ID, builder.build()); + WXLogUtils.d("Update", "progress:" + p); + } + } + + @Override + public void onResponse(File file) { + WXLogUtils.d("Update", "success: " + file.getAbsolutePath()); + manager.cancel(NOTIFY_ID); + Uri uri = Uri.fromFile(file); + Intent installIntent = new Intent(Intent.ACTION_VIEW); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + installIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + Uri contentUri = FileProvider.getUriForFile(WXEnvironment.getApplication(), BuildConfig.APPLICATION_ID + ".fileprovider", file); + installIntent.setDataAndType(contentUri, "application/vnd.android.package-archive"); + } else { + installIntent.setDataAndType(uri, "application/vnd.android.package-archive"); + installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + } + startActivity(installIntent); + } + + @Override + public void onError(final Exception e) { + WXSDKManager.getInstance().getWXRenderManager().postOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(UpdateService.this, "Failed to update:" + e.getMessage(), Toast.LENGTH_SHORT).show(); + } + }, 0); + } + }); + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/1294abff/android/playground/app/src/main/res/layout/common_update_notify_dialog.xml ---------------------------------------------------------------------- diff --git a/android/playground/app/src/main/res/layout/common_update_notify_dialog.xml b/android/playground/app/src/main/res/layout/common_update_notify_dialog.xml new file mode 100644 index 0000000..8b2987b --- /dev/null +++ b/android/playground/app/src/main/res/layout/common_update_notify_dialog.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:padding="16dp"> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:text="@string/update_found_new_version" + android:textColor="#030303" + android:textSize="20sp" /> + + <TextView + android:id="@+id/common_update_dialog_msg" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="14dp" + android:textColor="#030303" + android:textSize="16sp" /> + +</LinearLayout> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/1294abff/android/playground/app/src/main/res/values-zh-rCN/strings.xml ---------------------------------------------------------------------- diff --git a/android/playground/app/src/main/res/values-zh-rCN/strings.xml b/android/playground/app/src/main/res/values-zh-rCN/strings.xml index 162f15c..e912d80 100755 --- a/android/playground/app/src/main/res/values-zh-rCN/strings.xml +++ b/android/playground/app/src/main/res/values-zh-rCN/strings.xml @@ -142,5 +142,13 @@ <string name="wifi_changing_network">è¿æ¥å° Wi-Fi \u2026</string> <string name="cpu_not_support_tip">对ä¸èµ·,æ¨å½åç设å¤æ¯X86æ¶æ.\næ们åªæ¯æARMæ¶æç设å¤!</string> + <string name="update_found_new_version">åç°æ°çæ¬</string> + <string name="update_downloading">æ£å¨ä¸è½½æ´æ°</string> + <string name="update_progress">è¿åº¦ï¼</string> + <string name="update_now">ç«å³æ´æ°</string> + <string name="update_remind_later">ç¨åæé</string> + <string name="update_version">çæ¬å·ï¼</string> + <string name="update_date">æ´æ°æ¥æï¼</string> + <string name="update_desc">æ´æ°å 容ï¼</string> </resources> http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/1294abff/android/playground/app/src/main/res/values/strings.xml ---------------------------------------------------------------------- diff --git a/android/playground/app/src/main/res/values/strings.xml b/android/playground/app/src/main/res/values/strings.xml index f352c18..f3160cb 100755 --- a/android/playground/app/src/main/res/values/strings.xml +++ b/android/playground/app/src/main/res/values/strings.xml @@ -40,4 +40,12 @@ under the License. "WXMainActivity" </string> <string name="title_activity_dynamic">DynamicActivity</string> + <string name="update_found_new_version">New version is available</string> + <string name="update_downloading">Downloading updates</string> + <string name="update_progress">Progress: </string> + <string name="update_now">Update Now</string> + <string name="update_remind_later">Remind Later</string> + <string name="update_version">Version: </string> + <string name="update_date">Date: </string> + <string name="update_desc">Updates: </string> </resources> http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/1294abff/android/playground/app/src/main/res/xml/filepaths.xml ---------------------------------------------------------------------- diff --git a/android/playground/app/src/main/res/xml/filepaths.xml b/android/playground/app/src/main/res/xml/filepaths.xml new file mode 100644 index 0000000..8b373df --- /dev/null +++ b/android/playground/app/src/main/res/xml/filepaths.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<paths> + <cache-path + name="local_apk_cache" + path="."/> +</paths> \ No newline at end of file