Acessing Application Lifecycle Interface with AppMethod - android

I am using the new Embarcadero AppMethod 1.14 to do some development for Android Devices (in C++), but I cannot for the life of me figure out how to gain access to the lifecycle events (doPAuse, doResume, etc). If anyone has any how-to's links, tips or code they can share on this subject?

Here is the code I finally came up with:
TGUID guid = StringToGUID("{F3AAF11A-1678-4CC6-A5BF-721A24A676FD}"); // GUID for ApplicationEventService interface
IInterface *AEventSvc;
if (TPlatformServices::Current->SupportsPlatformService(guid)) {
AEventSvc = TPlatformServices::Current->GetPlatformService(guid);
IFMXApplicationEventService *EventSvc;
AEventSvc->QueryInterface(guid,(void**)(&EventSvc));
EventSvc->SetApplicationEventHandler(SysEventHandler);
EventSvc->Release();
}
Kudos out to Pawel Glowaki whose blog gave me the key details to getting this answer: http://blogs.embarcadero.com/pawelglowacki/2013/09/30/40067/

Related

Kotlin Mutliplatform : Maping Swift/Objc code to Kotlin in iOSMain module?

I am learning KMM. I am now designing a common Location fetching in iOSMain and Android main
My problem is , I don't know to map Swift to Kotlin in iOSMain
For example,
The Swift code for , getting location is
var locationManager = CLLocationManager()
locationManager.requestWhenInUseAuthorization()
var currentLoc: CLLocation!
if(CLLocationManager.authorizationStatus() == .authorizedWhenInUse ||
CLLocationManager.authorizationStatus() == .authorizedAlways) {
currentLoc = locationManager.location
print(currentLoc.coordinate.latitude)
print(currentLoc.coordinate.longitude)
}
Kotlin side implementation:
In the above code:
How to use the Swift's .authorizedWhenInUse and .authorizedAlways in Kotlin Code ?
And the in currentLoc.coordinate.longitude , the longitude and latitude is not resolving . Why ?
Please help me
Mapping Swift (Objective-C) to Kotlin
How to use the Swift's .authorizedWhenInUse and .authorizedAlways in Kotlin Code ?
According to Kotlin's documentation on interoperability, Kotlin/Native provides bidirectional interoperability with Objective-C, not Swift, so my first recommendation would be to reference Apple's Objective-C documentation over the Swift documentation.
If you pull up the Swift documentation for .authorizedWhenInUse, you'll see you can switch the language to Objective-C:
Switch this to the Objective-C documentation to see how to reference this in Objective-C:
Given this, you should be able to use kCLAuthorizationStatusAuthorizedWhenInUse in your Kotlin code.
Referencing iOS Frameworks
Since you already have some reference code, you could also simply Command+Click (or Command+B) one of the objects (for example, CLLocationManager) which should open up the compiled Kotlin code.
Manually you can also access all iOS frameworks from the "Project" View of Android Studio → "External Libraries" and then search for the iOS framework that you are searching for.
Here, you can dig through the frameworks to find what you're looking for. Not knowing the equivalent Objective-C API, you could just search for "authorizedWhenInUse" and can find it:
Dealing with C-structs
currentLoc.coordinate.longitude , the longitude and latitude is not resolving
This is more complicated...
The location property is of type CLLocationCoordinate2D and (the important part!) is that it is contained within a CValue:
#kotlinx.cinterop.ExternalObjCClass public open class CLLocation : platform.darwin.NSObject, platform.Foundation.NSCopyingProtocol, platform.Foundation.NSSecureCodingProtocol {
...
public final val coordinate: kotlinx.cinterop.CValue<platform.CoreLocation.CLLocationCoordinate2D> /* compiled code */
Note that in Objective-C, CLLocationCoordinate2D is a C struct:
typedef struct CLLocationCoordinate2D {
...
} CLLocationCoordinate2D;
The Kotlin documentation here is thin, but it shows the methods available for CValue includes the .useContents() method.
Therefore, your code could be written as follows (compiled and confirmed that this runs and generates a location on a physical device):
val locationManager = CLLocationManager()
val currentLoc: CLLocation?
if (locationManager.authorizationStatus == kCLAuthorizationStatusAuthorizedWhenInUse ||
locationManager.authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) {
currentLoc = locationManager.location
currentLoc?.coordinate?.useContents {
println("latitude = ${latitude}")
println("longitude = ${longitude}")
}
}
[Update September 2022]
If you want to dig deeper, I also published a blog post on writing iOS-platform-dependent code using Kotlin with KMM's expect/actual: artandscienceofcoding.com/science/avoid-this-kmm-technique

How can i embed an NativeScript Angular app in iOS / Android and navigate to certain routes from the existing app

We are looking to integrate NativeScript Angular into existing iOS and Android apps. We would like to have existing menus in our app be able to route to sections of the NS Angular app. /home /contact for example. One of our concerns with embedding an NS Angular app is the large overhead for frameworks / vendor files / etc and having to duplicate these sections over and over for multiple embedded apps. We would rather have one NS Angular app that contains various views and be able to navigate to those views as the starting view based on the initial link tapped in the previous Native app that hosts the embed.
Has anyone achieved this already and can share some examples or any info that would help? Would sending a variable from the native app to the embedded NS Angular app that routes be on option?
in https://github.com/NativeScript/sample-ios-embedded/blob/master/HOWTO.md
there is mention of _runScript
- (void)activateNativeScript:(id)sender {
NSString *source = #"var application = require('application');"
"application.start({ moduleName: 'main-page' });";
[self _runScript: source];
}
Would we be able to send routes through _runScript or possibly initialize various sections but still maintain the same vendor bundle.js ?
thanks!
I don't think you could access Angular from outside Angular context. A workaround could be, store the RouterExtensions reference on global variable while your appcomponent.ts is initiated,
export class AppComponent {
constructor(private routerExtensions: RouterExtensions) {
(<any>global)._routerExtensions = routerExtensions;
}
}
You may do this with _runScript then
NSString *source = #"global._routerExtensions.navigate([...])";
But make sure you access _routerExtensions once it's initialised. Also the code to start Angular app is slightly different, you will find it in the same docs if you go down a little further.
- (void)activateNativeScript:(id)sender {
NSString *source = #"var platform = require('nativescript-angular/platform');"
"var AppModule = require('./app.module' });"
"platform.platformNativeScriptDynamic().bootstrapModule(AppModule);";
[self _runScript: source];
}

Titanium Hyperloop access to android.os.SystemProperties

I have been trying a ( i hope) simple bit of Android hyperloop code directly within a titanium project (using SDK 7.0.1.GA and hyperloop 3).
var sysProp = require('android.os.SystemProperties');
var serialNumber = sysProp.get("sys.serialnumber", "none");
But when the app is run it reports
Requested module not found:android.os.SystemProperties
I think this maybe due to the fact that when compiling the app (using the cli) it reports
hyperloop:generateSources: Skipping Hyperloop wrapper generation, no usage found ...
I have similar code in a jar and if I use this then it does work, so I am wondering why the hyperloop generation is not being triggered, as I assume that is the issue.
Sorry should have explained better.
This is the jar source that I use, the extraction of the serial number was just an example (I need access to other info manufacturer specific data as well), I wanted to see if I could replicate the JAR functionality using just hyperloop rather that including the JAR file. Guess if it's not broke don't fix it, but was curious to see if it could be done.
So with the feedback from #miga and a bit of trial and error, I have come up with a solution that works really well and will do the method reflection that is required. My new Hyperloop function is
function getData(data){
var result = false;
var Class = require("java.lang.Class");
var String = require("java.lang.String");
var c = Class.forName("android.os.SystemProperties");
var get = c.getMethod("get", String.class, String.class);
result = get.invoke(c, data, "Error");
return result;
}
Where data is a string of the system property I want.
I am using it to extract and match a serial number from a Samsung device that is a System Property call "ril.serialnumber" or "sys.serialnumber". Now I can use the above function to do what I was using the JAR file for. Just thought I'd share in case anyone else needed something similar.
It is because android.os.SystemProperties is not class you can import. Check the android documentation at https://developer.android.com/reference/android/os/package-summary.html
You could use
var build = require('android.os.Build');
console.log(build.SERIAL);
to access the serial number.

Using PeerConnection.createDataChannel() in Android

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.

getEntity call results in crash (using odata4j on a WCF service)

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());
}
}

Categories

Resources