@aks-dev/easyui 1.0.26 → 1.0.29

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="${applicationId}.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-23 18:21:04
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,306 @@ 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";
50
93
  }
94
+ }
51
95
 
96
+ @ReactMethod
97
+ public void getAppVersion(final Promise promise) {
98
+ promise.resolve(this.getAppVersionName());
52
99
  }
53
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
+
111
+ promise.reject("error_app_upgrade","已是最新版本");
112
+ }
113
+ Activity currentActivity = context.getCurrentActivity();
114
+ int permission = ActivityCompat.checkSelfPermission(context.getApplicationContext(),
115
+ Manifest.permission.WRITE_EXTERNAL_STORAGE);
116
+
117
+ if (permission != PackageManager.PERMISSION_GRANTED) {
118
+ // 请求权限
119
+ ActivityCompat.requestPermissions(currentActivity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
120
+ EXTERNAL_STORAGE_REQ_CODE);
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
+ promise.resolve("发现新版本");
169
+ }
170
+
171
+ /**
172
+ * 版本更新檢查
173
+ *
174
+ * @param remoteVersion
175
+ * @param localVersion
176
+ * @return true 需要更新 false 不需要更新
177
+ */
178
+ public boolean checkUpdate(String remoteVersion, String localVersion) {
179
+
180
+ if (localVersion == null || localVersion.length() == 0 || remoteVersion == null || remoteVersion.length() == 0) {
181
+ return false;
182
+ }
183
+ String[] localVers = localVersion.split("\\.");
184
+ String[] remoteVers = remoteVersion.split("\\.");
185
+ // 对比主版本
186
+ if (compareVersion(localVers, remoteVers, 0) > 0) {
187
+ return false;
188
+ }
189
+ if (compareVersion(localVers, remoteVers, 0) < 0) {
190
+ return true;
191
+ }
192
+ // 对比子版本
193
+ if (compareVersion(localVers, remoteVers, 1) > 0) {
194
+ return false;
195
+ }
196
+ if (compareVersion(localVers, remoteVers, 1) < 0) {
197
+ return true;
198
+ }
199
+ // 对比fix版本
200
+ if (compareVersion(localVers, remoteVers, 2) < 0) {
201
+ return true;
202
+ }
203
+ return false;
204
+ }
205
+
206
+ /**
207
+ * 判断是否需要更新
208
+ *
209
+ * @param localVers 本地版本
210
+ * @param remoteVers 远程版本
211
+ * @param idx 版本索引
212
+ * @return
213
+ */
214
+ public int compareVersion(String[] localVers, String[] remoteVers, int idx) {
215
+ if (remoteVers.length > idx && localVers.length <= idx) {
216
+ return -1;
217
+ }
218
+ if (remoteVers.length <= idx && localVers.length > idx) {
219
+ return 1;
220
+ }
221
+ if (remoteVers.length <= idx && localVers.length <= idx) {
222
+ return 0;
223
+ }
224
+ Integer localVer = Integer.parseInt(localVers[idx]);
225
+ Integer remoteVer = Integer.parseInt(remoteVers[idx]);
226
+ return localVer.compareTo(remoteVer);
227
+ }
228
+
229
+ /**
230
+ * 开始更新
231
+ *
232
+ * @param downloadUrl
233
+ */
234
+ public void start(String downloadUrl) {
235
+ Activity currentActivity = context.getCurrentActivity();
236
+ mProgressDialog = new ProgressDialog(currentActivity);
237
+ mProgressDialog.setCanceledOnTouchOutside(false);
238
+ mProgressDialog.setTitle("升级文件下载中,请稍候...");
239
+ mProgressDialog.setIndeterminate(true);
240
+ mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
241
+ mProgressDialog.setCancelable(false);
242
+ final DownloadTask downloadTask = new DownloadTask(currentActivity);
243
+ downloadTask.execute(downloadUrl);
244
+ }
245
+
246
+ private void updateApk() {
247
+ //安装应用
248
+ Intent intent = new Intent(Intent.ACTION_VIEW);
249
+ //sg
250
+ ContextWrapper cw = new ContextWrapper(getReactApplicationContext());
251
+ File directory = cw.getExternalFilesDir(Environment.DIRECTORY_MUSIC);
252
+ Activity currentActivity = context.getCurrentActivity();
253
+ //判断是否是AndroidN以及更高的版本
254
+ String packageName = context.getPackageName();
255
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
256
+ Uri contentUri = FileProvider.getUriForFile(currentActivity,packageName+".provider", new File(directory, mDownloadFile));
257
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
258
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
259
+ intent.setDataAndType(contentUri,"application/vnd.android.package-archive");
260
+ } else {
261
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
262
+ intent.setDataAndType(Uri.fromFile(new File(directory, mDownloadFile)),
263
+ "application/vnd.android.package-archive");
264
+ }
265
+ currentActivity.startActivity(intent);
266
+ }
267
+
268
+ /**
269
+ * 下载应用
270
+ *
271
+ * @author Administrator
272
+ */
273
+ class DownloadTask extends AsyncTask<String, Integer, String> {
274
+
275
+ private Context context;
276
+ private PowerManager.WakeLock mWakeLock;
277
+
278
+ public DownloadTask(Context context) {
279
+ this.context = context;
280
+ }
281
+
282
+ @Override
283
+ protected String doInBackground(String... sUrl) {
284
+ InputStream input = null;
285
+ OutputStream output = null;
286
+ HttpURLConnection connection = null;
287
+ File file = null;
288
+ try {
289
+ URL url = new URL(sUrl[0]);
290
+ connection = (HttpURLConnection) url.openConnection();
291
+ connection.connect();
292
+ // expect HTTP 200 OK, so we don't mistakenly save error
293
+ // report
294
+ // instead of the file
295
+ if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
296
+ return "Server returned HTTP "
297
+ + connection.getResponseCode() + " "
298
+ + connection.getResponseMessage();
299
+ }
300
+ // this will be useful to display download percentage
301
+ // might be -1: server did not report the length
302
+ int fileLength = connection.getContentLength();
303
+
304
+ mDownloadFile = "app_" + String.valueOf(System.currentTimeMillis()) + ".apk";
305
+ //sg
306
+ ContextWrapper cw = new ContextWrapper(getReactApplicationContext());
307
+ File directory = cw.getExternalFilesDir(Environment.DIRECTORY_MUSIC);
308
+ file = new File(directory, mDownloadFile);
309
+ //
310
+ if (!file.exists()) {
311
+ // 判断父文件夹是否存在
312
+ if (!file.getParentFile().exists()) {
313
+ file.getParentFile().mkdirs();
314
+ }
315
+ }
316
+ input = connection.getInputStream();
317
+ output = new FileOutputStream(file);
318
+ byte data[] = new byte[4096];
319
+ long total = 0;
320
+ int count;
321
+ while ((count = input.read(data)) != -1) {
322
+ // allow canceling with back button
323
+ if (isCancelled()) {
324
+ input.close();
325
+ return null;
326
+ }
327
+ total += count;
328
+ // publishing the progress....
329
+ if (fileLength > 0) // only if total length is known
330
+ publishProgress((int) (total * 100 / fileLength));
331
+ output.write(data, 0, count);
332
+
333
+ }
334
+ } catch (Exception e) {
335
+ System.out.println(e.toString());
336
+ return e.toString();
337
+
338
+ } finally {
339
+ try {
340
+ if (output != null)
341
+ output.close();
342
+ if (input != null)
343
+ input.close();
344
+ } catch (IOException ignored) {
345
+ }
346
+ if (connection != null)
347
+ connection.disconnect();
348
+ }
349
+ return null;
350
+ }
351
+
352
+ @Override
353
+ protected void onPreExecute() {
354
+ super.onPreExecute();
355
+ PowerManager pm = (PowerManager) context
356
+ .getSystemService(Context.POWER_SERVICE);
357
+ mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
358
+ getClass().getName());
359
+ mWakeLock.acquire();
360
+ mProgressDialog.show();
361
+ }
362
+
363
+ @Override
364
+ protected void onProgressUpdate(Integer... progress) {
365
+ super.onProgressUpdate(progress);
366
+ // if we get here, length is known, now set indeterminate to false
367
+ mProgressDialog.setIndeterminate(false);
368
+ mProgressDialog.setMax(100);
369
+ mProgressDialog.setProgress(progress[0]);
370
+ }
371
+
372
+ @Override
373
+ protected void onPostExecute(String result) {
374
+ mWakeLock.release();
375
+ mProgressDialog.dismiss();
376
+ if (result != null) {
377
+ Toast.makeText(context, "您未打开SD卡权限" + result, Toast.LENGTH_LONG).show();
378
+ } else {
379
+ updateApk();
380
+ }
381
+ }
382
+ }
54
383
  }
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <shape xmlns:android="http://schemas.android.com/apk/res/android"
3
+ android:shape="rectangle">
4
+ <!-- 填充的颜色 -->
5
+ <!--<solid android:color="@android:color/transparent" />-->
6
+ <!-- 设置按钮的四个角为弧形 -->
7
+ <!-- android:radius 弧形的半径 -->
8
+ <corners android:radius="4dp" />
9
+ <!--边框的宽度及颜色-->
10
+ <stroke android:width="2px" android:color="#CCCCCC" />
11
+ </shape>
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <shape xmlns:android="http://schemas.android.com/apk/res/android"
3
+ android:shape="rectangle">
4
+ <!-- 填充的颜色 -->
5
+ <solid android:color="#EA6561" />
6
+ <!-- 设置按钮的四个角为弧形 -->
7
+ <!-- android:radius 弧形的半径 -->
8
+ <corners android:radius="4dp" />
9
+ <!--边框的宽度及颜色-->
10
+ <!--<stroke android:width="2px" android:color="#388e3c" />-->
11
+ </shape>
@@ -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="#FFFFFF"
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>
@@ -2,12 +2,16 @@
2
2
  * @Author: shiguo
3
3
  * @Date: 2022-05-05 14:19:39
4
4
  * @LastEditors: shiguo
5
- * @LastEditTime: 2022-05-07 11:41:41
6
- * @FilePath: /@aks/easyui/jsbridge/UpgradeModule.tsx
5
+ * @LastEditTime: 2022-05-23 18:22:39
6
+ * @FilePath: /@aks-dev/easyui/jsbridge/UpgradeModule.tsx
7
7
  */
8
8
  import { NativeModules } from 'react-native';
9
9
 
10
10
  const { UpgradeModule } = NativeModules;
11
11
 
12
+ import type { UpgradeOptions } from '.'
12
13
 
13
- export const getAppVersion = () => UpgradeModule.getAppVersion();
14
+ export const getAppVersion = () => UpgradeModule.getAppVersion();
15
+
16
+
17
+ export const upgrade = (props: UpgradeOptions) => UpgradeModule.upgrade(props)
package/jsbridge/index.ts CHANGED
@@ -2,12 +2,22 @@
2
2
  * @Author: shiguo
3
3
  * @Date: 2022-04-19 10:23:01
4
4
  * @LastEditors: shiguo
5
- * @LastEditTime: 2022-05-05 14:29:15
6
- * @FilePath: /@aks/easyui/jsbridge/index.ts
5
+ * @LastEditTime: 2022-05-23 18:21:50
6
+ * @FilePath: /@aks-dev/easyui/jsbridge/index.ts
7
7
  */
8
8
  /**
9
9
  * @description: 获取App版本号
10
10
  * @param {*}
11
11
  * @return {*}
12
12
  */
13
- export declare const getAppVersion:()=>Promise<string>;
13
+ export declare const getAppVersion: () => Promise<string>;
14
+
15
+
16
+ export declare type UpgradeOptions = {
17
+ version: string;
18
+ downloadUrl: string;
19
+ note: string;
20
+ force: boolean;
21
+ };
22
+
23
+ export declare const upgrade: (props: UpgradeOptions) => Promise<string>;
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.29",
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": "*",