@aks-dev/easyui 1.0.26 → 1.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,5 +16,17 @@
16
16
  </action>
17
17
  </intent>
18
18
  </queries>
19
+
20
+ <application>
21
+ <provider
22
+ android:name="androidx.core.content.FileProvider"
23
+ android:authorities="com.sg.upgrade.provider"
24
+ android:exported="false"
25
+ android:grantUriPermissions="true">
26
+ <meta-data
27
+ android:name="android.support.FILE_PROVIDER_PATHS"
28
+ android:resource="@xml/file_paths" />
29
+ </provider>
30
+ </application>
19
31
  </manifest>
20
32
 
@@ -2,28 +2,70 @@
2
2
  * @Author: shiguo
3
3
  * @Date: 2022-05-05 13:57:25
4
4
  * @LastEditors: shiguo
5
- * @LastEditTime: 2022-05-07 11:41:32
6
- * @FilePath: /@aks/easyui/android/src/main/java/com/easyui/UpgradeModule.java
5
+ * @LastEditTime: 2022-05-20 17:43:52
6
+ * @FilePath: /@aks-dev/easyui/android/src/main/java/com/easyui/UpgradeModule.java
7
7
  */
8
8
  package com.easyui;
9
9
 
10
+ import android.Manifest;
11
+ import android.app.Activity;
12
+ import android.app.AlertDialog;
13
+ import android.app.ProgressDialog;
10
14
  import android.content.Context;
15
+ import android.content.ContextWrapper;
16
+ import android.content.Intent;
11
17
  import android.content.pm.PackageInfo;
12
18
  import android.content.pm.PackageManager;
19
+ import android.graphics.Color;
20
+ import android.graphics.drawable.ColorDrawable;
21
+ import android.net.Uri;
22
+ import android.os.AsyncTask;
23
+ import android.os.Build;
24
+ import android.os.Environment;
25
+ import android.os.Handler;
26
+ import android.os.Looper;
27
+ import android.os.PowerManager;
28
+ import android.view.Display;
29
+ import android.view.View;
30
+ import android.view.Window;
31
+ import android.view.WindowManager;
32
+ import android.widget.Button;
33
+ import android.widget.TextView;
34
+ import android.widget.Toast;
13
35
 
14
36
  import androidx.annotation.NonNull;
37
+ import androidx.core.app.ActivityCompat;
38
+ import androidx.core.content.FileProvider;
15
39
 
16
40
  import com.facebook.react.bridge.Promise;
17
41
  import com.facebook.react.bridge.ReactApplicationContext;
18
42
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
19
43
  import com.facebook.react.bridge.ReactMethod;
44
+ import com.facebook.react.bridge.ReadableMap;
20
45
 
21
46
  import org.jetbrains.annotations.NotNull;
22
47
 
48
+ import java.io.File;
49
+ import java.io.FileOutputStream;
50
+ import java.io.IOException;
51
+ import java.io.InputStream;
52
+ import java.io.OutputStream;
53
+ import java.net.HttpURLConnection;
54
+ import java.net.URL;
55
+ import java.util.HashMap;
56
+
23
57
  public class UpgradeModule extends ReactContextBaseJavaModule {
24
58
 
25
- private Context context;
59
+ private ReactApplicationContext context;
60
+ public static final int EXTERNAL_STORAGE_REQ_CODE = 10 ;
61
+ private static Handler mHandler = new Handler(Looper.getMainLooper());
62
+ private ProgressDialog mProgressDialog;
63
+ private String mDownloadFile;
64
+
26
65
 
66
+ private static void runOnMainThread(Runnable runnable) {
67
+ mHandler.postDelayed(runnable, 0);
68
+ }
27
69
 
28
70
  @NonNull
29
71
  @NotNull
@@ -36,19 +78,303 @@ public class UpgradeModule extends ReactContextBaseJavaModule {
36
78
  public UpgradeModule(ReactApplicationContext reactContext) {
37
79
  super(reactContext);
38
80
  this.context = reactContext;
81
+
39
82
  }
40
83
 
41
- @ReactMethod
42
- public void getAppVersion(final Promise promise) {
84
+
85
+ private String getAppVersionName() {
43
86
  try {
44
87
  PackageManager manager = context.getPackageManager();
45
88
  PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
46
- promise.resolve(info.versionName);
89
+ return info.versionName;
47
90
  } catch (PackageManager.NameNotFoundException e) {
48
91
  e.printStackTrace();
49
- promise.reject("1.0.0", "getAppVersion error");
92
+ return "1.0.0";
93
+ }
94
+ }
95
+
96
+ @ReactMethod
97
+ public void getAppVersion(final Promise promise) {
98
+ promise.resolve(this.getAppVersionName());
99
+ }
100
+
101
+
102
+ @ReactMethod
103
+ public void upgrade(final ReadableMap info, final Promise promise) {
104
+ HashMap hashMap = info.toHashMap();
105
+ String version = (String) hashMap.get("version");
106
+ String downloadUrl = (String) hashMap.get("downloadUrl");
107
+ String note = (String) hashMap.get("note");
108
+ Boolean force = (Boolean) hashMap.get("force");
109
+ if (!checkUpdate(version, this.getAppVersionName())) {
110
+ promise.resolve("已是最新版本");
111
+ }
112
+ Activity currentActivity = context.getCurrentActivity();
113
+ int permission = ActivityCompat.checkSelfPermission(context.getApplicationContext(),
114
+ Manifest.permission.WRITE_EXTERNAL_STORAGE);
115
+
116
+ if (permission != PackageManager.PERMISSION_GRANTED) {
117
+ // 请求权限
118
+ ActivityCompat.requestPermissions(currentActivity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
119
+ EXTERNAL_STORAGE_REQ_CODE);
120
+ }
121
+
122
+
123
+ runOnMainThread(new Runnable() {
124
+ @Override
125
+ public void run() {
126
+ View view = View.inflate(currentActivity, R.layout.update_dialog, null);
127
+ AlertDialog.Builder builder = new AlertDialog.Builder(currentActivity);
128
+ builder.setView(view);
129
+ if (force) {
130
+ builder.setCancelable(false);
131
+ }
132
+ final AlertDialog dialog = builder.show();
133
+
134
+ WindowManager m = currentActivity.getWindowManager();
135
+ Display d = m.getDefaultDisplay();
136
+ WindowManager.LayoutParams p = dialog.getWindow().getAttributes();
137
+ p.width = (int) (d.getWidth() * 0.90);
138
+ p.height = p.width * 780 / 680;
139
+ dialog.getWindow().setAttributes(p);
140
+ Window window = dialog.getWindow();
141
+ window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
142
+
143
+ TextView contentView = view.findViewById(R.id.content);
144
+ Button confirmBtn = view.findViewById(R.id.btn_comfirm);
145
+ Button cancelBtn = view.findViewById(R.id.btn_cancel);
146
+
147
+ contentView.setText(note);
148
+ confirmBtn.setOnClickListener(new View.OnClickListener() {
149
+ @Override
150
+ public void onClick(View v) {
151
+ dialog.dismiss();
152
+ start(downloadUrl);
153
+ }
154
+ });
155
+ cancelBtn.setOnClickListener(new View.OnClickListener() {
156
+ @Override
157
+ public void onClick(View v) {
158
+ if (force) {
159
+ android.os.Process.killProcess(android.os.Process.myPid());
160
+ } else {
161
+ dialog.dismiss();
162
+ }
163
+ }
164
+ });
165
+ }
166
+ });
167
+ }
168
+
169
+ /**
170
+ * 版本更新檢查
171
+ *
172
+ * @param remoteVersion
173
+ * @param localVersion
174
+ * @return true 需要更新 false 不需要更新
175
+ */
176
+ public boolean checkUpdate(String remoteVersion, String localVersion) {
177
+
178
+ if (localVersion == null || localVersion.length() == 0 || remoteVersion == null || remoteVersion.length() == 0) {
179
+ return false;
180
+ }
181
+ String[] localVers = localVersion.split("\\.");
182
+ String[] remoteVers = remoteVersion.split("\\.");
183
+ // 对比主版本
184
+ if (compareVersion(localVers, remoteVers, 0) > 0) {
185
+ return false;
50
186
  }
187
+ if (compareVersion(localVers, remoteVers, 0) < 0) {
188
+ return true;
189
+ }
190
+ // 对比子版本
191
+ if (compareVersion(localVers, remoteVers, 1) > 0) {
192
+ return false;
193
+ }
194
+ if (compareVersion(localVers, remoteVers, 1) < 0) {
195
+ return true;
196
+ }
197
+ // 对比fix版本
198
+ if (compareVersion(localVers, remoteVers, 2) < 0) {
199
+ return true;
200
+ }
201
+ return false;
202
+ }
203
+
204
+ /**
205
+ * 判断是否需要更新
206
+ *
207
+ * @param localVers 本地版本
208
+ * @param remoteVers 远程版本
209
+ * @param idx 版本索引
210
+ * @return
211
+ */
212
+ public int compareVersion(String[] localVers, String[] remoteVers, int idx) {
213
+ if (remoteVers.length > idx && localVers.length <= idx) {
214
+ return -1;
215
+ }
216
+ if (remoteVers.length <= idx && localVers.length > idx) {
217
+ return 1;
218
+ }
219
+ if (remoteVers.length <= idx && localVers.length <= idx) {
220
+ return 0;
221
+ }
222
+ Integer localVer = Integer.parseInt(localVers[idx]);
223
+ Integer remoteVer = Integer.parseInt(remoteVers[idx]);
224
+ return localVer.compareTo(remoteVer);
225
+ }
51
226
 
227
+ /**
228
+ * 开始更新
229
+ *
230
+ * @param downloadUrl
231
+ */
232
+ public void start(String downloadUrl) {
233
+ Activity currentActivity = context.getCurrentActivity();
234
+ mProgressDialog = new ProgressDialog(currentActivity);
235
+ mProgressDialog.setCanceledOnTouchOutside(false);
236
+ mProgressDialog.setTitle("升级文件下载中,请稍候...");
237
+ mProgressDialog.setIndeterminate(true);
238
+ mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
239
+ mProgressDialog.setCancelable(false);
240
+ final DownloadTask downloadTask = new DownloadTask(currentActivity);
241
+ downloadTask.execute(downloadUrl);
52
242
  }
53
243
 
244
+ private void updateApk() {
245
+ //安装应用
246
+ Intent intent = new Intent(Intent.ACTION_VIEW);
247
+ //sg
248
+ ContextWrapper cw = new ContextWrapper(getReactApplicationContext());
249
+ File directory = cw.getExternalFilesDir(Environment.DIRECTORY_MUSIC);
250
+ Activity currentActivity = context.getCurrentActivity();
251
+ //判断是否是AndroidN以及更高的版本
252
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
253
+ Uri contentUri = FileProvider.getUriForFile(currentActivity,"com.sg.upgrade.provider", new File(directory, mDownloadFile));
254
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
255
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
256
+ intent.setDataAndType(contentUri,"application/vnd.android.package-archive");
257
+ } else {
258
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
259
+ intent.setDataAndType(Uri.fromFile(new File(directory, mDownloadFile)),
260
+ "application/vnd.android.package-archive");
261
+ }
262
+ currentActivity.startActivity(intent);
263
+ }
264
+
265
+ /**
266
+ * 下载应用
267
+ *
268
+ * @author Administrator
269
+ */
270
+ class DownloadTask extends AsyncTask<String, Integer, String> {
271
+
272
+ private Context context;
273
+ private PowerManager.WakeLock mWakeLock;
274
+
275
+ public DownloadTask(Context context) {
276
+ this.context = context;
277
+ }
278
+
279
+ @Override
280
+ protected String doInBackground(String... sUrl) {
281
+ InputStream input = null;
282
+ OutputStream output = null;
283
+ HttpURLConnection connection = null;
284
+ File file = null;
285
+ try {
286
+ URL url = new URL(sUrl[0]);
287
+ connection = (HttpURLConnection) url.openConnection();
288
+ connection.connect();
289
+ // expect HTTP 200 OK, so we don't mistakenly save error
290
+ // report
291
+ // instead of the file
292
+ if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
293
+ return "Server returned HTTP "
294
+ + connection.getResponseCode() + " "
295
+ + connection.getResponseMessage();
296
+ }
297
+ // this will be useful to display download percentage
298
+ // might be -1: server did not report the length
299
+ int fileLength = connection.getContentLength();
300
+
301
+ mDownloadFile = "app_" + String.valueOf(System.currentTimeMillis()) + ".apk";
302
+ //sg
303
+ ContextWrapper cw = new ContextWrapper(getReactApplicationContext());
304
+ File directory = cw.getExternalFilesDir(Environment.DIRECTORY_MUSIC);
305
+ file = new File(directory, mDownloadFile);
306
+ //
307
+ if (!file.exists()) {
308
+ // 判断父文件夹是否存在
309
+ if (!file.getParentFile().exists()) {
310
+ file.getParentFile().mkdirs();
311
+ }
312
+ }
313
+ input = connection.getInputStream();
314
+ output = new FileOutputStream(file);
315
+ byte data[] = new byte[4096];
316
+ long total = 0;
317
+ int count;
318
+ while ((count = input.read(data)) != -1) {
319
+ // allow canceling with back button
320
+ if (isCancelled()) {
321
+ input.close();
322
+ return null;
323
+ }
324
+ total += count;
325
+ // publishing the progress....
326
+ if (fileLength > 0) // only if total length is known
327
+ publishProgress((int) (total * 100 / fileLength));
328
+ output.write(data, 0, count);
329
+
330
+ }
331
+ } catch (Exception e) {
332
+ System.out.println(e.toString());
333
+ return e.toString();
334
+
335
+ } finally {
336
+ try {
337
+ if (output != null)
338
+ output.close();
339
+ if (input != null)
340
+ input.close();
341
+ } catch (IOException ignored) {
342
+ }
343
+ if (connection != null)
344
+ connection.disconnect();
345
+ }
346
+ return null;
347
+ }
348
+
349
+ @Override
350
+ protected void onPreExecute() {
351
+ super.onPreExecute();
352
+ PowerManager pm = (PowerManager) context
353
+ .getSystemService(Context.POWER_SERVICE);
354
+ mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
355
+ getClass().getName());
356
+ mWakeLock.acquire();
357
+ mProgressDialog.show();
358
+ }
359
+
360
+ @Override
361
+ protected void onProgressUpdate(Integer... progress) {
362
+ super.onProgressUpdate(progress);
363
+ // if we get here, length is known, now set indeterminate to false
364
+ mProgressDialog.setIndeterminate(false);
365
+ mProgressDialog.setMax(100);
366
+ mProgressDialog.setProgress(progress[0]);
367
+ }
368
+
369
+ @Override
370
+ protected void onPostExecute(String result) {
371
+ mWakeLock.release();
372
+ mProgressDialog.dismiss();
373
+ if (result != null) {
374
+ Toast.makeText(context, "您未打开SD卡权限" + result, Toast.LENGTH_LONG).show();
375
+ } else {
376
+ updateApk();
377
+ }
378
+ }
379
+ }
54
380
  }
@@ -0,0 +1,51 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
+ android:id="@+id/update_root"
4
+ android:orientation="vertical" android:layout_width="match_parent"
5
+ android:layout_height="wrap_content"
6
+ android:background="@drawable/upgrade_bg">
7
+
8
+ <LinearLayout
9
+ android:layout_width="match_parent"
10
+ android:layout_height="190dp"
11
+ android:layout_alignParentBottom="true"
12
+ android:paddingLeft="15dp"
13
+ android:paddingRight="15dp">
14
+
15
+ <TextView
16
+ android:id="@+id/content"
17
+ android:layout_width="wrap_content"
18
+ android:layout_height="wrap_content"
19
+ android:singleLine="false"
20
+ android:text="1.升级说明123123\\n2.升级说明22222"/>
21
+
22
+ </LinearLayout>
23
+
24
+ <LinearLayout
25
+ android:layout_width="match_parent"
26
+ android:layout_height="120dp"
27
+ android:layout_alignParentBottom="true"
28
+ android:gravity="center"
29
+ android:orientation="vertical">
30
+
31
+ <Button
32
+ android:id="@+id/btn_comfirm"
33
+ android:layout_width="200dp"
34
+ android:layout_height="35dp"
35
+ android:textColor="@color/white"
36
+ android:background="@drawable/update_confirm_btn"
37
+ android:text="立即升级"
38
+ style="?android:attr/borderlessButtonStyle" />
39
+
40
+ <Button
41
+ android:id="@+id/btn_cancel"
42
+ android:layout_width="200dp"
43
+ android:layout_height="35dp"
44
+ android:layout_alignBottom="@id/btn_comfirm"
45
+ android:background="@drawable/update_cancel_btn"
46
+ android:layout_marginTop="10dp"
47
+ android:textColor="#CCCCCC"
48
+ android:text="残忍拒绝"
49
+ style="?android:attr/borderlessButtonStyle" />
50
+ </LinearLayout>
51
+ </RelativeLayout>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <paths xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <root-path name="root" path="/" />
4
+ <files-path name="files" path="/" />
5
+ <cache-path name="cache" path="/" />
6
+ <external-path name="external" path="/" />
7
+ <external-files-path name="external_file_path" path="/" />
8
+ <external-cache-path name="external_cache_path" path="/" />
9
+ <external-files-path
10
+ name="umeng_cache"
11
+ path="umeng_cache/" />
12
+ </paths>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@aks-dev/easyui",
3
- "version": "1.0.26",
4
- "description": "爱科森开发工具包",
3
+ "version": "1.0.27",
4
+ "description": "爱科森开发工具包(react-native)",
5
5
  "main": "./src/index.ts",
6
6
  "typings": "./src/index.d.ts",
7
7
  "scripts": {
@@ -33,7 +33,7 @@
33
33
  "type": "git",
34
34
  "url": "https://gitee.com/the_period_of_the_ten_kingdoms/aks-easyui"
35
35
  },
36
- "author": "",
36
+ "author": "shiguo",
37
37
  "license": "MIT",
38
38
  "peerDependencies": {
39
39
  "@aks-dev/react-native-syan-image-picker": "*",