I am trying to establish a communication between the native part (android) with javascript part(react-native).Here is the following code from Java side:-
WritableMap params = Arguments.createMap();
params.putString("arg1","valueToJS");
getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("showResult",params);
And the Respective Javascript file to receive the event :-
DeviceEventEmitter.addListener('showResult', function (e: Event) {
// hadle the event triggered from java side
});
Now in addListner where do we add the params(Argument) in order to get the "valueToJS",Since i am not able find proper documentation about DeviceEventEmitter i am finding difficult to get the value of argument arg1.Any help is highly appreciated.
Related
I have added flutter to a native iOS code. I have UIButton and on pressing this button, I am presenting a FlutterViewController. I have been following this.
Here's my code for presenting the FlutterViewController:
#objc
#IBAction func openProfile() {
print("open profile")
lazy var flutterEngine = FlutterEngine(name: "patient_profile_engine")
flutterEngine.run(withEntrypoint: "", libraryURI: "");
let profileVC =
FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
present(profileVC, animated: true, completion: nil)
}
This code is working fine and the flutter view is opening and since I haven't specified and entry point yet so it using the main.dart.
The problem is that I need to pass some information to the Flutter dart code. e.g. a dictionary ["patient_id": "123456"] during the initialization.
I will have to do the same in Android native Java code as well.
Is there any easy way?
You will probably want to write a platform channel to communicate between the native code and the flutter engine.
An alternative, for this purpose, would be to use runWithEntrypoint:initialRoute: method to start the engine, encode the data into the initial route, and parse it on the flutter side.
I am including react native to my existing android application. I have one activity(say A) that is starting activity B. A activity sends some data in Bundle(consider some Custom Objects POJO) that B needs to render its view.
Now I want my Activity B to contain React Native View. How will the objects(POJO) come from Activity A be sent to React Native code**(JavaScipt Code)**?
I know some time has passed, but maybe someone is still looking for an answer.
If you want to send object from JavaScript to ReactNative (let's say as an method argument), which is unfortunately not mentioned in documentation:
let map = {
name: 'message1',
surname: 'message2',
}
NativeModules.BluetoothModule.sendObject(map);
And get it in android:
#ReactMethod
public void sendObject(ReadableMap readableMap){
Log.i(TAG, readableMap.toString());
//you can decode it here like:
String name = readableMap.getString("name");
//or just parse it as json
}
Now for the other way (from Java to Javascript) you can use either Callbacs, Promises or Events. This part is described in documentation here
From Java (Native Thread) to JavaScript (UI Thread):
#ReactMethod
public void sendObjectFromNative(Promise promise){
WritableMap map = Arguments.createMap();
map.putString("name", name);
map.putDouble("rotationDegrees", rotationDegrees);
map.putBoolean("isLandscape", isLandscape);
promise.resolve(map);
}
In JavaScript(UI Thread):
import { NativeModules } from 'react-native';
NativeModules.AwesomeModule.sendObjectFromNative().then(result=>console.log(result));
Above described how to do it vice versa
In Angular 1.x , we can use angular.element(appElement).scope() to get $scope, and then use the $apply(), so that the native javascript can directly call angular functions or two-way binding. While with Angular 4, how could we call angular functions or two-way binding by native javascript or the android native.
For example :
The web is developed by angular 4, and it will be used in the android webview, so it needs an interaction with android, how can i handle the interaction?
I can think of many ways, but have never read anything in the manuals which clarifies as to the most Angular way.
Zones
You have to keep in mind that Angular uses zones and a change detection tree at the core of it's engine. So any outside access needs to happen in that context.
You have to run external code in the Angular zone:
zone.run(() => {
// do work here
});
If you make changes to any data that will directly or indirectly effect a template expression you run the risk of a change detection error. So a component needs to inject ChangeDetectorRef and call markForCheck.
So if you code runs inside a component but from outside of Angular. You need to do this:
zone.run(() => {
// do work here.
this.ChangeDetectorRef.markForCheck();
});
Still, that raises the question. How do I get to the component?
Accessing Angular
You have to bootstrap your Angular application so that it can be accessed.
When you bootstrap your Angular application the browser service returns a promise to the main module. That main module contains the injector and from there you can access any exported services.
platformBrowserDynamic()
.bootstrapModule(AppModule)
.then((modRef: NgModuleRef<AppModule>) => {
window.myGlobalService = modRef.injector.get(MyServiceClass);
});
That would place a service class as a global variable. You would have to create an API that forwards to Angular's zones.
#Injectable()
export class MyServiceClass {
public dataEmitter: Subject<any> = new Subject();
public constructor(private zone: NgZone) {}
public fooBar(data: any): any {
return this.zone.run(()=>{
// do work here
this.dataEmitter.next(data);
return "My response";
});
}
}
You can return a result from zone.run out of the service. The key is that Angular code is run in the correct zone.
Easy Component One-Way Binding
The easiest solution for one-way data binding is to just use the Event module for the DOM.
#Component({....})
export class MyComponent {
#HostListener('example',['$event'])
public onExample(event: Event) {
console.log(event.fooBar);
}
}
// else where in external JavaScript
var elem; // the DOM element with the component
var event = new Event('example', {fooBar: 'Hello from JS!'});
elem.dispatchEvent(elem);
I prefer this approach since Angular handles the event listener as it would any other kind of event (i.e. click events)
You can also do this the other way around. Have the component emit DOM events on it's ElementRef for external JavaScript to listen for. This makes the whole two-way communications more DOM standard.
I have built webrtc for android and have included the jar file in my project. I want to attach data channel to my PeerConnection object. On web, we do following in javascript :
sendChannel = pc.createDataChannel("sendDataChannel", {reliable: true});
or
sendChannel = pc.createDataChannel("sendDataChannel", {reliable: false});
where pc is the PeerConnection.
I want to do same in Java on Android using native webrtc code. I have little confusion. By looking at Jar file on eclipse, I could see that createDataChannel method of PeerConnection takes two arguments of type String and Init.
PeerConnection.createDataChannel(String, Init)
I could not understand what should I put in the second argument. WebRTC documentation, I found, is for web applications. I have seen the following WebRTC draft document but could not understand clearly.
http://www.w3.org/TR/webrtc/#methods-2
It would be helpful if someone can provide a small example of how it should be used.
Currently, I am trying to do this:
DataChannel dc = this.pc.createDataChannel("sendDataChannel", new DataChannel.Init());
You'd create the Init instance and manipulate the public properties before passing it to createDataChannel:
https://code.google.com/p/webrtc/source/browse/trunk/talk/app/webrtc/java/src/org/webrtc/DataChannel.java#35
If you did not find "reliable" there, that is because this does not work anymore. See maxRetransmits and maxRetransmitTimeMs.
Try to make a new Init and assign it a id if you want otherwise just pass new Init() in second argument it will work.
I am trying out odata4j in my android app to retrieve data from a DB that can be accessed from a WCF service.
ODataConsumer co = ODataConsumer.create("http://xxx.xx.xx.xxx:xxxx/Users");
for(OEntity user : co.getEntities("Users").execute())
{
// do stuff
}
However this crashes at the call to getEntities. I have tried a variety of other calls as well, such as
Enumerable<OEntity> eo = co.getEntities("Users").execute();
OEntity users = eo.elementAt(0);
However this also crashes at eo.elementAt(0).
The logcat doesn't tell me anything, and the callstack seems to be Suspended at ActivityThread.performLaunchActivity.
Entering "http://localhost:xxxx/Users" in my web browser on the other hand works as expected and returns the users in my DB in xml format.
Any ideas on how I can debug this?
To log all http requests/responses:
ODataConsumer.dump.all(true);
The uri passed to the consumer .create call should be the service root. e.g. .create("http://xxx.xx.xx.xxx:xxxx/"); Otherwise your code looks fine.
Note the Enumerable behaves like the .net type - enumeration is deferred until access. If you plan on indexing multiple times into the results, I'd suggest you call .toList() first.
Let me know what you find out.
Hope that helps,
- john
I guess the call should be:
ODataConsumer co = ODataConsumer.create("http://xxx.xx.xx.xxx:xxxx");
for(OEntity user : co.getEntities("Users").execute())
{
// do stuff
}
create defines service you want to connect but Users is the resource you want to query.
Can you try this way.
OEntity oEntity;
OQueryRequest<OEntity> oQueryRequest= oDataJerseyConsumer.getEntities(entityName);
List<OEntity> list= oQueryRequest.execute().toList();
for (OEntity o : list) {
List<OProperty<?>> props = o.getProperties();
for (OProperty<?> prop : props) {
System.out.println(prop.getValue().toString());
}
}