Skip to content

Commit d4078a1

Browse files
authored
Merge pull request #5 from mfdeveloper/android-exception-catch
[Android] Return exception details + Promise support
2 parents edd8f59 + b723b63 commit d4078a1

File tree

9 files changed

+231
-60
lines changed

9 files changed

+231
-60
lines changed

README.md

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@ Until here, this plugin is not registered on cloud. In future, this plugin will
6161

6262
* Or create a `.jar` or a `.aar` that contains this class, and import like a [Android module dependency](https://developer.android.com/studio/projects/android-library.html#AddDependency)
6363

64+
* Verify if the code snippet below is present in your `AndroidManifest.xml`. This is required to open a specific Activity from a [Intent](https://developer.android.com/reference/android/content/Intent.html) (using **[package + activityName]**)
65+
66+
```xml
67+
<activity android:name=".MyActivity" >
68+
<intent-filter>
69+
<action android:name="com.mypackage.MyActivity" />
70+
<category android:name="android.intent.category.DEFAULT" />
71+
</intent-filter>
72+
</activity>
73+
```
74+
> If this filter not exists in `AndroidManifest.xml`, you will get this error: [No Activity found to handle Intent splash screen](https://stackoverflow.com/questions/15614561/android-content-activitynotfoundexception-no-activity-found-to-handle-intent-sp)
75+
6476
* Build/Run your android project!
6577

6678
## Supported Platforms
@@ -79,8 +91,25 @@ Shows a native view.
7991

8092
```js
8193

82-
// pass a package name and a activity by params
83-
window.NativeView.show('com.mycompany', 'MyActivity');
94+
document.addEventListener("deviceready", function() {
95+
// pass a package name and a activity by params
96+
cordova.plugins.NativeView.show('com.mycompany', 'MyActivity')
97+
.then(function() {
98+
99+
/**
100+
* Do something when open the activity.
101+
* This code here will be executed in paralell,
102+
* not after open.
103+
*/
104+
}).catch(function(error) {
105+
106+
/**
107+
* error.success => Will be "false"
108+
* error.name => Exception type from the captured error
109+
* error.message => A exception message
110+
*/
111+
});
112+
}, false);
84113

85114
```
86115
**IOS**
@@ -91,15 +120,43 @@ window.NativeView.show('com.mycompany', 'MyActivity');
91120
* Optionally, pass a storyboard name that contains
92121
* an UIViewController
93122
*/
94-
window.NativeView.show('MyStoryboard', 'MyUIViewController');
95-
96-
/*
97-
* Or, pass only the UIViewController name, if you don't
98-
* use storyboards in your project.
99-
*/
100-
window.NativeView.show('MyUIViewController');
123+
document.addEventListener("deviceready", function() {
124+
cordova.plugins.NativeView.show('MyStoryboard', 'MyUIViewController')
125+
.then(function() {
126+
127+
/**
128+
* Do something when open the activity.
129+
* This code here will be executed in paralell,
130+
* not after open.
131+
*/
132+
});
133+
134+
/*
135+
* Or, pass only the UIViewController name, if you don't
136+
* use storyboards in your project.
137+
*/
138+
cordova.plugins.NativeView.show('MyUIViewController');
139+
140+
/*
141+
* Or just call the "show()" method without params.
142+
* This plugin will check whether exists a *"NavigationController"
143+
* in your project, and execute
144+
* "[popViewControllerAnimated: Yes]" method. Else, will be throw a
145+
* exception
146+
*
147+
*/
148+
cordova.plugins.NativeView.show();
149+
150+
}, false);
101151
```
102152

153+
**IONIC**
154+
155+
Replace `document.addEventListener` event to `this.platform.ready().then(...)` service method. See [IONIC Platform documentation](https://ionicframework.com/docs/api/platform/Platform/)
103156
## License
104157

105158
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details
159+
160+
## TODO
161+
162+
- Better catch IOS exception from JS

cordova-plugin-nativeview.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,6 @@ Pod::Spec.new do |s|
135135

136136
# s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
137137
# s.dependency "JSONKit", "~> 1.4"
138-
s.dependency "Cordova", "~> 4.4.0"
138+
s.dependency "Cordova", ">= 4.4.0"
139139

140140
end

jsconfig.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
/* Basic Options */
44
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
55
"module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
6-
// "lib": [], /* Specify library files to be included in the compilation: */
6+
"lib": [ /* Specify library files to be included in the compilation: */
7+
"dom",
8+
"es2015"
9+
],
710
// "allowJs": true, /* Allow javascript files to be compiled. */
811
// "checkJs": true, /* Report errors in .js files. */
912
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
@@ -19,7 +22,7 @@
1922
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
2023

2124
/* Strict Type-Checking Options */
22-
"strict": true /* Enable all strict type-checking options. */
25+
"strict": true, /* Enable all strict type-checking options. */
2326
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
2427
// "strictNullChecks": true, /* Enable strict null checks. */
2528
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
@@ -37,7 +40,7 @@
3740
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
3841
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
3942
// "typeRoots": [], /* List of folders to include type definitions from. */
40-
// "types": [], /* Type declaration files to be included in compilation. */
43+
// "types": [] /* Type declaration files to be included in compilation. */
4144
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
4245

4346
/* Source Map Options */

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cordova-plugin-nativeview",
3-
"version": "0.0.2",
3+
"version": "0.0.3",
44
"types": "./types/index.d.ts",
55
"description": "Start or Back to a native screen/page",
66
"author": {
@@ -14,6 +14,9 @@
1414
"ios"
1515
]
1616
},
17+
"engines": {
18+
"cordova": ">=3.0.0"
19+
},
1720
"repository": {
1821
"type": "git",
1922
"url": "https://github.com/mfdeveloper/cordova-plugin-nativeview"

plugin.xml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,15 @@
1313
<repo>https://github.com/mfdeveloper/cordova-plugin-nativeview.git</repo>
1414
<issue>https://github.com/mfdeveloper/cordova-plugin-nativeview/issues</issue>
1515

16-
<js-module src="www/plugin.js" name="NativeView">
16+
<dependency id="es6-promise-plugin" version="4.2.2"></dependency>
17+
18+
<engines>
19+
<engine name="cordova" version=">=3.0.0" />
20+
</engines>
21+
22+
<js-module src="www/plugin.nativeview.js" name="NativeView">
1723
<!-- This is the window variable name you want, like window.MyCordovaPlugin -->
18-
<clobbers target="window.NativeView" />
24+
<clobbers target="cordova.plugins.NativeView" />
1925
</js-module>
2026

2127
<!-- android -->

src/android/NativeView.java

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,28 @@
99
import org.apache.cordova.CordovaWebView;
1010
import org.json.JSONArray;
1111
import org.json.JSONException;
12+
import org.json.JSONObject;
1213

1314
import java.lang.reflect.InvocationTargetException;
1415
import java.lang.reflect.Method;
16+
import java.util.HashMap;
17+
import java.util.Iterator;
1518

1619
/**
17-
* Created by @mfdeveloper on 28/08/17.
20+
* Start a native Activity. This plugin
21+
* use Java Reflection to decide which method
22+
* execute
23+
*
24+
* @author @mfdeveloper on 28/08/17
1825
*/
19-
2026
public class NativeView extends CordovaPlugin {
2127

2228
private static final String TAG = "NativeViewPlugin";
2329

2430
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
2531
super.initialize(cordova, webView);
2632

27-
Log.d(TAG, "Initializing NativeViewPlugin");
33+
Log.d(TAG, "Initializing " + TAG);
2834
}
2935

3036
public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
@@ -40,12 +46,21 @@ public boolean execute(String action, JSONArray args, final CallbackContext call
4046
return true;
4147

4248
} catch (IllegalAccessException e) {
49+
JSONObject error = errorResult(e);
50+
callbackContext.error(error);
51+
4352
e.printStackTrace();
4453

4554
} catch (IllegalArgumentException e) {
55+
JSONObject error = errorResult(e);
56+
callbackContext.error(error);
57+
4658
e.printStackTrace();
4759

4860
}catch (InvocationTargetException e) {
61+
JSONObject error = errorResult(e);
62+
callbackContext.error(error);
63+
4964
e.printStackTrace();
5065
}
5166
}catch (NoSuchMethodException e) {
@@ -54,6 +69,12 @@ public boolean execute(String action, JSONArray args, final CallbackContext call
5469

5570
Log.d(TAG, message);
5671

72+
HashMap<String, Object> data = new HashMap<String, Object>();
73+
data.put("message", message);
74+
75+
JSONObject error = errorResult(e, data);
76+
callbackContext.error(error);
77+
5778
e.printStackTrace();
5879

5980
}
@@ -64,16 +85,68 @@ public boolean execute(String action, JSONArray args, final CallbackContext call
6485
public void show(JSONArray params, final CallbackContext callbackContext) throws JSONException {
6586
String packageName = params.getString(0);
6687
String className = params.getString(1);
88+
String extraParams;
89+
90+
if (className.startsWith("{")) {
91+
extraParams = className;
92+
} else {
93+
94+
extraParams = params.length() >= 3 ? params.getString(2) : null;
95+
}
6796

6897
final Intent intent = new Intent(packageName.toLowerCase() + "." + className);
6998

99+
if (extraParams != null) {
100+
101+
JSONObject jsonExtra = new JSONObject(extraParams);
102+
Iterator<?> keys = jsonExtra.keys();
103+
104+
while (keys.hasNext()) {
105+
String key = (String) keys.next();
106+
intent.putExtra(key, jsonExtra.getString(key));
107+
}
108+
}
109+
70110
cordova.getActivity().runOnUiThread(new Runnable() {
71111
@Override
72112
public void run() {
73-
cordova.getActivity().startActivity(intent);
74113

75-
callbackContext.success("started");
114+
try {
115+
cordova.getActivity().startActivity(intent);
116+
JSONObject success = new JSONObject();
117+
success.put("success", true);
118+
119+
callbackContext.success(success);
120+
} catch (Exception e) {
121+
122+
JSONObject error = errorResult(e);
123+
callbackContext.error(error);
124+
e.printStackTrace();
125+
}
126+
76127
}
77128
});
78129
}
130+
131+
protected JSONObject errorResult(Exception e) {
132+
HashMap<String, Object> data = new HashMap<String, Object>();
133+
data.put("success", false);
134+
data.put("name", e.getClass().getName());
135+
data.put("message", e.getMessage());
136+
137+
JSONObject error = new JSONObject(data);
138+
return error;
139+
}
140+
141+
protected JSONObject errorResult(Exception e, HashMap<String, Object> extraData) {
142+
HashMap<String, Object> data = new HashMap<String, Object>();
143+
data.put("success", false);
144+
data.put("name", e.getClass().getName());
145+
data.put("message", e.getMessage());
146+
147+
data.putAll(extraData);
148+
149+
JSONObject error = new JSONObject(data);
150+
return error;
151+
}
79152
}

types/index.d.ts

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,48 @@
11
// Type definitions for NativeView
22
// Project: https://github.com/mfdeveloper/cordova-plugin-nativeview
33
// Definitions by: Michel Felipe <https://github.com/mfdeveloper>
4-
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
4+
interface CordovaPlugins {
5+
NativeView: NativeView
6+
}
57

8+
interface ResultView {
9+
success: boolean;
10+
name?: string;
11+
message?: string;
12+
}
613
interface NativeView {
7-
8-
/**
9-
* Shows the native view.
10-
*
11-
* Define the `packageOrClass` param to a package (Android) or a
12-
* storyboard/classname (IOS)
13-
*
14-
* ```ts
15-
*
16-
* //Android
17-
* NativeView.show('com.mycompany', 'MyActivity')
18-
*
19-
* //IOS
20-
* NativeView.show('MyStoryboard', 'MyUIViewController');
21-
* ```
22-
*
23-
* @param packageOrClass
24-
* @param className
25-
* @param success
26-
* @param error
27-
*/
28-
show(packageOrClass?: string, className?: string, success?: Function, error?: Function): void;
29-
}
30-
31-
declare var NativeView: NativeView;
14+
15+
/**
16+
* Shows the native view.
17+
*
18+
* Define the `packageOrClass` param to a package (Android) or a
19+
* storyboard/classname (IOS)
20+
*
21+
* ```ts
22+
*
23+
* //Android
24+
* cordova.plugins.NativeView.show('com.mycompany', 'MyActivity')
25+
* .then(() => {
26+
* // Do something
27+
* });
28+
*
29+
* //IOS
30+
* cordova.plugins.NativeView.show('MyStoryboard', 'MyUIViewController')
31+
* .then(() => {
32+
* // Do something
33+
* });
34+
*
35+
* //OR Back to previous View (IOS only)
36+
* cordova.plugins.NativeView.show().then(() => {
37+
* // Do something
38+
* });
39+
*
40+
* ```
41+
*
42+
* @param packageOrClass Package or class name of view to open
43+
* @param className Class name of view to open
44+
* @param success [Optional] Callback when success, if you don't want use promise "then()"
45+
* @param error [Optional] Callback when error happens, if you don't want use promise "catch()"
46+
*/
47+
show(packageOrClass?: string, className?: string, success?: Function, error?: Function): Promise<ResultView | void>;
48+
}

0 commit comments

Comments
 (0)