@aigens/aigens-sdk-core 0.0.5 → 0.0.8

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.
@@ -10,7 +10,7 @@ Pod::Spec.new do |s|
10
10
  s.homepage = package['repository']['url']
11
11
  s.author = package['author']
12
12
  s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
- s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
13
+ s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp,xib}'
14
14
  s.ios.deployment_target = '12.0'
15
15
  s.dependency 'Capacitor'
16
16
  s.swift_version = '5.1'
package/README.md CHANGED
@@ -14,10 +14,12 @@ npx cap sync
14
14
  <docgen-index>
15
15
 
16
16
  * [`echo(...)`](#echo)
17
+ * [`dismiss(...)`](#dismiss)
17
18
  * [`finish(...)`](#finish)
18
19
  * [`getMember(...)`](#getmember)
19
20
  * [`openBrowser(...)`](#openbrowser)
20
- * [`scan(...)`](#scan)
21
+ * [`isInstalledApp(...)`](#isinstalledapp)
22
+ * [`openExternalUrl(...)`](#openexternalurl)
21
23
 
22
24
  </docgen-index>
23
25
 
@@ -39,6 +41,21 @@ echo(options: any) => Promise<any>
39
41
  --------------------
40
42
 
41
43
 
44
+ ### dismiss(...)
45
+
46
+ ```typescript
47
+ dismiss(options: any) => Promise<any>
48
+ ```
49
+
50
+ | Param | Type |
51
+ | ------------- | ---------------- |
52
+ | **`options`** | <code>any</code> |
53
+
54
+ **Returns:** <code>Promise&lt;any&gt;</code>
55
+
56
+ --------------------
57
+
58
+
42
59
  ### finish(...)
43
60
 
44
61
  ```typescript
@@ -84,15 +101,30 @@ openBrowser(options: any) => Promise<any>
84
101
  --------------------
85
102
 
86
103
 
87
- ### scan(...)
104
+ ### isInstalledApp(...)
88
105
 
89
106
  ```typescript
90
- scan(options: any) => Promise<any>
107
+ isInstalledApp(options: { key: string; }) => Promise<{ install: boolean; }>
91
108
  ```
92
109
 
93
- | Param | Type |
94
- | ------------- | ---------------- |
95
- | **`options`** | <code>any</code> |
110
+ | Param | Type |
111
+ | ------------- | ----------------------------- |
112
+ | **`options`** | <code>{ key: string; }</code> |
113
+
114
+ **Returns:** <code>Promise&lt;{ install: boolean; }&gt;</code>
115
+
116
+ --------------------
117
+
118
+
119
+ ### openExternalUrl(...)
120
+
121
+ ```typescript
122
+ openExternalUrl(options: { url: string; }) => Promise<any>
123
+ ```
124
+
125
+ | Param | Type |
126
+ | ------------- | ----------------------------- |
127
+ | **`options`** | <code>{ url: string; }</code> |
96
128
 
97
129
  **Returns:** <code>Promise&lt;any&gt;</code>
98
130
 
@@ -53,9 +53,6 @@ dependencies {
53
53
  implementation project(':capacitor-android')
54
54
  implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
55
55
 
56
- implementation('com.journeyapps:zxing-android-embedded:4.3.0') { transitive = false }
57
- implementation 'com.google.zxing:core:3.3.0'
58
-
59
56
  testImplementation "junit:junit:$junitVersion"
60
57
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
61
58
  androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
@@ -1,3 +1,12 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
1
2
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
3
  package="com.aigens.sdk">
4
+ <uses-permission android:name="android.permission.INTERNET" />
5
+ <application android:hardwareAccelerated="true">
6
+ <activity android:name=".WebContainerActivity"
7
+ android:screenOrientation="portrait"
8
+ >
9
+
10
+ </activity>
11
+ </application>
3
12
  </manifest>
@@ -1,11 +1,18 @@
1
1
  package com.aigens.sdk;
2
2
 
3
+ import android.app.Activity;
3
4
  import android.content.Intent;
4
5
  import android.content.res.AssetManager;
5
6
  import android.graphics.Bitmap;
7
+ import android.graphics.Color;
6
8
  import android.net.Uri;
9
+ import android.os.Build;
7
10
  import android.os.Bundle;
11
+ import android.text.TextUtils;
12
+ import android.util.Log;
8
13
  import android.view.View;
14
+ import android.webkit.ServiceWorkerClient;
15
+ import android.webkit.ServiceWorkerController;
9
16
  import android.webkit.WebResourceError;
10
17
  import android.webkit.WebResourceRequest;
11
18
  import android.webkit.WebResourceResponse;
@@ -21,7 +28,6 @@ import com.getcapacitor.CapConfig;
21
28
  import com.getcapacitor.Plugin;
22
29
  import com.getcapacitor.PluginLoadException;
23
30
  import com.getcapacitor.PluginManager;
24
- import com.aigens.sdk.R;
25
31
 
26
32
  import org.json.JSONException;
27
33
  import org.json.JSONObject;
@@ -40,6 +46,16 @@ public class WebContainerActivity extends BridgeActivity {
40
46
  private String url;
41
47
  private boolean navbar = false;
42
48
  private Map member;
49
+ private List<String> externalProtocols = new ArrayList<String>(){{
50
+ add("octopus://");
51
+ add("alipay://");
52
+ add("alipays://");
53
+ add("alipayhk://");
54
+ add("tel:");
55
+ add("mailto:");
56
+ add("payme://");
57
+ add("https://play.google.com");
58
+ }};
43
59
 
44
60
  private void debug(Object... msgs){
45
61
 
@@ -59,7 +75,9 @@ public class WebContainerActivity extends BridgeActivity {
59
75
 
60
76
  super.onCreate(savedInstanceState);
61
77
 
62
- setContentView(R.layout.sdk_layout_main);
78
+ setContentView(com.aigens.sdk.R.layout.sdk_layout_main);
79
+
80
+ disableServiceWorker();
63
81
 
64
82
  Intent intent = getIntent();
65
83
  this.url = intent.getStringExtra("url");
@@ -69,6 +87,13 @@ public class WebContainerActivity extends BridgeActivity {
69
87
 
70
88
  this.member = (Map) intent.getSerializableExtra("member");
71
89
 
90
+ List<String> externalProtocols_ = (List<String>) intent.getSerializableExtra("externalProtocols");
91
+ if (externalProtocols_ != null) {
92
+ for (String s : externalProtocols_) {
93
+ this.externalProtocols.add(s);
94
+ }
95
+ }
96
+
72
97
  if(this.member != null) {
73
98
  CorePlugin.setMember(this.member);
74
99
  }
@@ -119,6 +144,16 @@ public class WebContainerActivity extends BridgeActivity {
119
144
 
120
145
  }
121
146
 
147
+ addExtraPlugins(new String[] {
148
+ "com.aigens.googlepay.GooglePayPlugin",
149
+ "com.aigens.octopus.OctopusPlugin",
150
+ "com.aigens.wechatpay.WechatPayPlugin",
151
+ "com.aigens.alipay.AliPayPlugin",
152
+ "com.aigens.alipayhk.AliPayhkPlugin",
153
+ "com.aigens.payme.PaymePlugin",
154
+ }, plugins);
155
+ addExtraPlugins(intent.getStringArrayExtra("extraClasspaths"), plugins);
156
+
122
157
  debug("App plugins:" + plugins);
123
158
 
124
159
  super.init(savedInstanceState, plugins, cc);
@@ -126,12 +161,38 @@ public class WebContainerActivity extends BridgeActivity {
126
161
  //still have time to override webview client to avoid any intercept
127
162
 
128
163
  BypassWebViewClient wvc = new BypassWebViewClient(this.bridge);
164
+ wvc.activity = this;
165
+ wvc.externalProtocols = this.externalProtocols;
129
166
  this.bridge.getWebView().setWebViewClient(wvc);
130
167
 
131
168
  initView();
132
169
  initLayout(false, true, false);
133
170
  }
134
171
 
172
+ private void addExtraPlugins(String[] extraClasspaths, List<Class<? extends Plugin>> plugins) {
173
+ if (extraClasspaths == null) return;
174
+ for (int i = 0; i < extraClasspaths.length; i++) {
175
+ String classPath = extraClasspaths[i];
176
+ try {
177
+ Class<?> c = Class.forName(classPath);
178
+ Class<? extends Plugin> sub = c.asSubclass(Plugin.class);
179
+ String clsName = sub.getName();
180
+ Boolean add = false;
181
+ for (Class<? extends Plugin> plugin : plugins) {
182
+ if (plugin.getName() == clsName) {
183
+ add = true;
184
+ break;
185
+ }
186
+ }
187
+ if (!add) {
188
+ plugins.add(sub);
189
+ }
190
+ } catch (ClassNotFoundException e) {
191
+ e.printStackTrace();
192
+ }
193
+ }
194
+ }
195
+
135
196
  private void initView(){
136
197
 
137
198
  Button backButton = (Button) findViewById(R.id.back);
@@ -154,6 +215,8 @@ public class WebContainerActivity extends BridgeActivity {
154
215
  }
155
216
  });
156
217
 
218
+ setTheme();
219
+
157
220
  }
158
221
 
159
222
  private void reload(){
@@ -170,6 +233,18 @@ public class WebContainerActivity extends BridgeActivity {
170
233
 
171
234
  }
172
235
 
236
+ private void setTheme() {
237
+ Intent intent = getIntent();
238
+ String themeColor = intent.getStringExtra("themeColor");
239
+ if (!TextUtils.isEmpty(themeColor)) {
240
+ View info = findViewById(R.id.info);
241
+ View error = findViewById(R.id.error);
242
+ info.setBackgroundColor(Color.parseColor(themeColor));
243
+ error.setBackgroundColor(Color.parseColor(themeColor));
244
+ bridge.getWebView().setBackgroundColor(Color.parseColor(themeColor));
245
+ getWindow().setStatusBarColor(Color.parseColor(themeColor));//set statussbar color
246
+ }
247
+ }
173
248
  private void initLayout(boolean showWeb, boolean showInfo, boolean showError){
174
249
 
175
250
  if(showError){
@@ -203,6 +278,25 @@ public class WebContainerActivity extends BridgeActivity {
203
278
  return plugins;
204
279
  }
205
280
 
281
+ private static boolean SW_DISABLED = false;
282
+
283
+ private static void disableServiceWorker(){
284
+
285
+ if(SW_DISABLED) return;
286
+
287
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
288
+ ServiceWorkerController.getInstance().setServiceWorkerClient(new ServiceWorkerClient() {
289
+ @Override
290
+ public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) {
291
+
292
+ return null;
293
+ }
294
+ });
295
+ }
296
+
297
+ SW_DISABLED = true;
298
+
299
+ }
206
300
 
207
301
 
208
302
  private static String readString(InputStream is) throws IOException {
@@ -254,10 +348,78 @@ public class WebContainerActivity extends BridgeActivity {
254
348
  //BridgeWebViewClient
255
349
  class BypassWebViewClient extends BridgeWebViewClient {
256
350
 
351
+ public Activity activity;
352
+ private String TAG = "BypassWebViewClient";
353
+ List<String> externalProtocols;
257
354
  public BypassWebViewClient(Bridge bridge) {
258
355
  super(bridge);
259
356
  }
260
357
 
358
+ public boolean loopExternalProtocols(String url) {
359
+ if (externalProtocols != null) {
360
+ for (String p : externalProtocols) {
361
+ if (url != null && url != "" && url.startsWith(p)) {
362
+ return true;
363
+ }
364
+ }
365
+ }
366
+ return false;
367
+ }
368
+ public boolean shouldOverrideUrl(WebView view, String url) {
369
+ if (url.startsWith(WebView.SCHEME_TEL)) {
370
+ try {
371
+ Intent intent = new Intent(Intent.ACTION_DIAL);
372
+ intent.setData(Uri.parse(url));
373
+ activity.startActivity(intent);
374
+ return true;
375
+ } catch (android.content.ActivityNotFoundException e) {
376
+ Log.e(TAG, "Error dialing " + url + ": " + e.toString());
377
+ }
378
+ } else if (url.startsWith("geo:") || url.startsWith(WebView.SCHEME_MAILTO) || url.startsWith("market:")
379
+ || loopExternalProtocols(url)) {
380
+ try {
381
+ Intent intent = new Intent(Intent.ACTION_VIEW);
382
+ intent.setData(Uri.parse(url));
383
+ activity.startActivity(intent);
384
+ return true;
385
+ } catch (android.content.ActivityNotFoundException e) {
386
+ Log.e(TAG, "Error with " + url + ": " + e.toString());
387
+ }
388
+ }
389
+ // If sms:5551212?body=This is the message
390
+ else if (url.startsWith("sms:")) {
391
+ try {
392
+ Intent intent = new Intent(Intent.ACTION_VIEW);
393
+
394
+ // Get address
395
+ String address = null;
396
+ int parmIndex = url.indexOf('?');
397
+ if (parmIndex == -1) {
398
+ address = url.substring(4);
399
+ } else {
400
+ address = url.substring(4, parmIndex);
401
+
402
+ // If body, then set sms body
403
+ Uri uri = Uri.parse(url);
404
+ String query = uri.getQuery();
405
+ if (query != null) {
406
+ if (query.startsWith("body=")) {
407
+ intent.putExtra("sms_body", query.substring(5));
408
+ }
409
+ }
410
+ }
411
+ intent.setData(Uri.parse("sms:" + address));
412
+ intent.putExtra("address", address);
413
+ intent.setType("vnd.android-dir/mms-sms");
414
+ activity.startActivity(intent);
415
+ return true;
416
+ } catch (android.content.ActivityNotFoundException e) {
417
+ Log.e(TAG, "Error sending sms " + url + ":" + e.toString());
418
+ }
419
+ }
420
+ return false;
421
+ }
422
+
261
423
  //somehow this must call parent, otherwise plugins won't work
262
424
  @Override
263
425
  public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
@@ -267,7 +429,9 @@ public class WebContainerActivity extends BridgeActivity {
267
429
  //debug("shouldInterceptRequest", url);
268
430
 
269
431
 
270
- if(url.indexOf("//scan") > 0){
432
+
433
+ //support redirect from /scan
434
+ if(url.indexOf("/scan?") > 0 || url.indexOf("/qr?") > 0 || url.indexOf("//scan") > 0){
271
435
  return null;
272
436
  }
273
437
 
@@ -281,11 +445,10 @@ public class WebContainerActivity extends BridgeActivity {
281
445
  @Override
282
446
  public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
283
447
  debug("shouldOverrideUrlLoading", request.getUrl());
284
- //Uri url = request.getUrl();
448
+ Uri url = request.getUrl();
285
449
 
286
450
  //return super.shouldOverrideUrlLoading(view, request);
287
-
288
- return false;
451
+ return shouldOverrideUrl(view, url.toString());
289
452
  }
290
453
 
291
454
  @Override
@@ -295,7 +458,7 @@ public class WebContainerActivity extends BridgeActivity {
295
458
 
296
459
  //return super.shouldOverrideUrlLoading(view, url);
297
460
 
298
- return false;
461
+ return shouldOverrideUrl(view, url);
299
462
  }
300
463
 
301
464
  @Override
@@ -2,24 +2,29 @@ package com.aigens.sdk.plugins;
2
2
 
3
3
  import android.app.Activity;
4
4
  import android.content.Intent;
5
+ import android.content.pm.PackageInfo;
6
+ import android.content.pm.PackageManager;
7
+ import android.net.Uri;
8
+ import android.os.Parcelable;
5
9
 
6
10
  import androidx.activity.result.ActivityResultLauncher;
7
11
  import androidx.appcompat.app.AppCompatActivity;
8
12
 
9
13
  import com.aigens.sdk.WebContainerActivity;
14
+ import com.getcapacitor.JSArray;
10
15
  import com.getcapacitor.JSObject;
11
16
  import com.getcapacitor.Plugin;
12
17
  import com.getcapacitor.PluginCall;
13
18
  import com.getcapacitor.PluginMethod;
14
19
  import com.getcapacitor.annotation.CapacitorPlugin;
15
- import com.journeyapps.barcodescanner.ScanContract;
16
- import com.journeyapps.barcodescanner.ScanOptions;
17
20
 
18
21
  import org.json.JSONException;
19
22
 
20
23
  import java.io.Serializable;
21
24
  import java.util.HashMap;
22
25
  import java.util.Iterator;
26
+ import java.util.List;
27
+ import java.util.Locale;
23
28
  import java.util.Map;
24
29
 
25
30
  @CapacitorPlugin(name = "Core")
@@ -29,26 +34,21 @@ public class CorePlugin extends Plugin {
29
34
 
30
35
  private static Map member;
31
36
 
32
- private void debug(Object msg){
37
+ private void debug(Object msg) {
33
38
 
34
- if(DEBUG){
39
+ if (DEBUG) {
35
40
  System.out.println(msg);
36
41
  }
37
42
 
38
43
  }
39
44
 
40
- public static void setMember(Map member){
45
+ public static void setMember(Map member) {
41
46
  CorePlugin.member = member;
42
47
  }
43
48
 
44
49
  @Override
45
- protected void handleOnStart(){
50
+ protected void handleOnStart() {
46
51
 
47
- debug("CorePlugin handleOnStart");
48
-
49
- prepareScan();
50
-
51
- debug("CorePlugin handleOnStart END");
52
52
  }
53
53
 
54
54
  @PluginMethod()
@@ -72,83 +72,6 @@ public class CorePlugin extends Plugin {
72
72
  call.resolve(ret);
73
73
  }
74
74
 
75
- private PluginCall scanCall;
76
-
77
- @PluginMethod()
78
- public void scan(PluginCall call) {
79
-
80
- debug("SCANNING!!");
81
-
82
- this.scanCall = call;
83
- scanRaw();
84
-
85
-
86
- }
87
-
88
- // Register the launcher and result handler
89
-
90
- private ActivityResultLauncher<ScanOptions> barcodeLauncher;
91
-
92
- private void prepareScan(){
93
-
94
- AppCompatActivity act = getActivity();
95
-
96
- barcodeLauncher = act.registerForActivityResult(new ScanContract(),
97
- result -> {
98
-
99
- if(scanCall == null){
100
- debug("Missing scan callback");
101
- return;
102
- }
103
-
104
- if(result.getContents() == null) {
105
- //Toast.makeText(MyActivity.this, "Cancelled", Toast.LENGTH_LONG).show();
106
- debug("scan cancelled");
107
- JSObject ret = new JSObject();
108
- ret.put("hasContent", false);
109
- ret.put("success", false);
110
- scanCall.resolve(ret);
111
- } else {
112
- //Toast.makeText(MyActivity.this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
113
- String val = result.getContents();
114
-
115
- debug("scan result:" + val);
116
-
117
- if(val != null && val.length() > 0){
118
-
119
- JSObject ret = new JSObject();
120
- ret.put("content", val);
121
- ret.put("hasContent", true);
122
- ret.put("success", true);
123
- scanCall.resolve(ret);
124
- }else{
125
-
126
- JSObject ret = new JSObject();
127
- ret.put("hasContent", false);
128
- ret.put("success", false);
129
- scanCall.resolve(ret);
130
- }
131
-
132
-
133
-
134
- }
135
- scanCall = null;
136
- });
137
- }
138
-
139
- private void scanRaw(){
140
-
141
- ScanOptions options = new ScanOptions();
142
- //options.setDesiredBarcodeFormats(ScanOptions.ONE_D_CODE_TYPES);
143
- options.setPrompt("");
144
- //options.setCameraId(0); // Use a specific camera of the device
145
- options.setBeepEnabled(false);
146
- options.setOrientationLocked(false);
147
- options.setBarcodeImageEnabled(true);
148
-
149
- //options.setBarcodeImageEnabled(true);
150
- barcodeLauncher.launch(options);
151
- }
152
75
 
153
76
  // Launch
154
77
  //public void onButtonClick(View view) {
@@ -162,21 +85,28 @@ public class CorePlugin extends Plugin {
162
85
 
163
86
  }
164
87
 
88
+ @PluginMethod()
89
+ public void dismiss(PluginCall call) {
90
+
91
+ getActivity().finish();
92
+
93
+ }
94
+
165
95
  @PluginMethod()
166
96
  public void openBrowser(PluginCall call) {
167
97
 
168
98
  String url = call.getString("url");
169
99
 
170
- if(url == null) return;
100
+ if (url == null) return;
171
101
 
172
102
  JSObject options = call.getObject("options", null);
173
103
  JSObject member = call.getObject("member", null);
174
104
 
175
105
  Map memMap = new HashMap();
176
106
 
177
- if(member != null){
107
+ if (member != null) {
178
108
  Iterator<String> iter = member.keys();
179
- while(iter.hasNext()){
109
+ while (iter.hasNext()) {
180
110
  String k = iter.next();
181
111
  try {
182
112
  Object v = member.get(k);
@@ -192,9 +122,20 @@ public class CorePlugin extends Plugin {
192
122
 
193
123
  Intent intent = new Intent(act, WebContainerActivity.class);
194
124
 
125
+ JSArray externalProtocols = call.getArray("externalProtocols");
126
+ try {
127
+ if (externalProtocols != null) {
128
+ List<String> es = externalProtocols.toList();
129
+ intent.putExtra("externalProtocols", (Serializable) es);
130
+ }
131
+ } catch (JSONException e) {
132
+ e.printStackTrace();
133
+ }
134
+
195
135
  intent.putExtra("url", url);
196
136
  intent.putExtra("member", (Serializable) memMap);
197
137
 
138
+
198
139
  act.startActivity(intent);
199
140
 
200
141
  JSObject ret = new JSObject();
@@ -202,4 +143,52 @@ public class CorePlugin extends Plugin {
202
143
  call.resolve(ret);
203
144
  }
204
145
 
146
+ @PluginMethod
147
+ public void openExternalUrl(PluginCall call) {
148
+ String url = call.getString("url");
149
+ if (url == null) {
150
+ call.reject("missing the url");
151
+ return;
152
+ }
153
+
154
+ final Intent intentExternal = new Intent();
155
+ intentExternal.setAction(Intent.ACTION_VIEW);
156
+ intentExternal.setData(Uri.parse(url));
157
+ Activity act = getActivity();
158
+ act.startActivity(intentExternal);
159
+ JSObject ret = new JSObject();
160
+ ret.put("open", true);
161
+ call.resolve(ret);
162
+ }
163
+
164
+ @PluginMethod
165
+ public void isInstalledApp(PluginCall call) {
166
+ String packname = call.getString("key");
167
+ Activity act = getActivity();
168
+ if (packname == null) {
169
+ call.reject("key is missing or is invaild key");
170
+ return;
171
+ }
172
+
173
+ try {
174
+ JSObject object = new JSObject();
175
+ final PackageManager packageManager = act.getPackageManager();// 获取packagemanager
176
+ List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);// 获取所有已安装程序的包信息
177
+ object.put("install", false);
178
+ if (pinfo != null && packname != null) {
179
+ packname = packname.toLowerCase(Locale.ENGLISH);
180
+ for (int i = 0; i < pinfo.size(); i++) {
181
+ String pn = pinfo.get(i).packageName.toLowerCase(Locale.ENGLISH);
182
+ if (pn.equals(packname)) {
183
+ object.put("install", true);
184
+ }
185
+ }
186
+ }
187
+ call.resolve(object);
188
+ } catch (Exception e) {
189
+ e.printStackTrace();
190
+ call.reject("key is missing or is invaild key");
191
+ }
192
+ }
193
+
205
194
  }