I have a unity app that should run on android. I have some native code (inside a plugin) that I need to call in order to process deep-link activation of the app, and I need to call it from my unity script when the app gets reopened by that deep link. Where is the appropriate place to make that call?
Note OnApplicationPause is not a good option, since it mimics onResume, and you MUST NOT process deep links inside onResume on Android because it will cause them to get re-processed over and over every time the app is reopened after the initial click on the deep link.
So basically, I am looking for a lifecycle-equivalent to onCreate, but in unity script (I do not have legal permissions to replace the native unity activity in this case and simply override its onCreate method).
onCreate() is run basically on the initialization of any activity. It's kind of hard to think about it in terms of Unity3D. When you call a level the Start() and Awake() are called, the latter first. You could potentially UnitySendMessage() from your native plugin on the java Android side. I believe the syntax looks like:
UnityPlayer.UnitySendMessage("GameObjectName1", "MethodName1", "Message to send");
And inside your GameObjectName1 construct MethodName1 method with string params passed:
function void MethodName1 (message:String) {}
Not sure if this will suffice for your needs. I've done comparable with iOS, i'm sure there should be an Android equivalent with Unity3D.
Related
Suppose you have a news app like Yahoo.
When a user runs your app and move out of your app (without quitting the app).
After a while (like an hour) he comes back, and you want to refresh the page (if he's seeing the front Yahoo page, it may have new news to show)
Is this a thing that I don't need to worry about because android actually disposes the long lived activity?
Or is this a thing that I have to implement it myself?
If I have to do it myself, should I implement this with saving 'exit time' and comparing it with 'resume time' and so forth or are there android/ios support or github library?
You can get an idea about Android life cycle and activity by browsing this
https://developer.android.com/reference/android/app/Activity
If you create an application using react-native and deploy it to both Android and IOS, you need to use a compatible react-native module for that.
If you only consider an android application. You can override onStart(), onResume(), onStop(), onPause() and onDestroy() methods to do what u want in certain states.
eg: If u want to reload new content when reopening the application, u need to override that refresh criterion in an overridden onResume() method.
Assuming you want to update the content after however long, assuming that your data is coming from a remote source that you are loading within your React Native application - you can hit one of the React Native JS lifecycle events.
For example, you can use componentDidMount():
componentDidMount() is invoked immediately after a component is mounted (inserted into the tree). Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.
This method is a good place to set up any subscriptions. If you do that, don’t forget to unsubscribe in componentWillUnmount().
If youre wanting to create a custom React Native Module, then you'll need to create an Android Service - but assuming you have an API endpoint for your data and the data will only be refreshed when the user is interacting with the app - I don't see why you'd need a custom module. It's all built in already.
You should use facebook.github.io/react-native/docs/appstate to check when the app becomes active, and then you do stuff.
I have developed an Android app for video conference using WebRTC. I used the available Java Library for the same.
I can successfully make a P2P call. However, when i make the same P2P call again one-after-another, I get the following error:
SetRemoteDescription failed: Called with type in wrong state, type: answer state:
STATE_INPROGRESS
However when I restart the app, I can make the call again, it works flawlessly.
Summary: In order to make a second call, I have to restart the application. It might be because of some possible caching of some objects like PC, SDPObserver or PCObserver. I make all of them null and also kill the activity after the first call. Even then second call doesn't work unless I restart my app.
What can be the possible cause?
It sounds like the local resources are not properly disposed even though you are killing the activity.
Make sure you are calling when the video call ends:
peerConnection.dispose();
videoSource.dispose();
peerConnectionFactory.dispose();
You can test that this works on the AppRTCDemo reference app. Here is the reference code.
I have been working on an Android app using Phonegap and now would like to make it so when the app is closed it can still execute the java/js code in the app. So I understand I need to create a service. If I create a service plugin on phonegap can I still execute the javascript code or only the java?
Has anyone does something like this? I found this discussion but did not seem to work: http://groups.google.com/group/phonegap/browse_thread/thread/722b0e796baa7fc6
So that is all I have right now.
Before I turn to developing it native if I can't figure it out thought I would ask if anyone has done this before. I can't seem to find any of the phonegap plugins that do something similar.
EDIT: I have got an app that executes Java code as a service. However when it calls sendjavascript it does not work. So is there a way to have the javascript code running in the background as well when an app is closed with phonegap?
Thanks
No, it is not possible to run Javascript code in the background (at least in my opinion) as a service. Phonegap on Android uses an special activity called Droidgap, which hosts a WebView. This browser control executes the JavaScript. This means that JS execution can only handled inside this activity, regardless if it is visible or not.
The code you linked from Google Groups tries to bind a service developed in Java to the DroidGap activity, so the service is NOT written in JS.
You can have some background activity within your JS code inside your child activity derived from the DroidGap activity. For example have a background thread in your activity, have a JS callback function and let the thread call this callback functionality.
If you really need a service you have to go native.
Update:
JS code can only be executed with the Droidgap activity. An activity can have 3 states (based on the Lifecycle of activites):
visible
invisible but still loaded
not loaded
I provided a sample in which I implemented a Phonegap plugin. The plugin allows the activity to register itself to SMS_RECEIVED. When the activies goes out of scope (event onbeforeunload), it deregisters, so only issue 1 is handled.
When you want all 3 issues handled, you have to forward the incoming SMS intent to the activity. When it is not loaded the system will automatically load and activate the activity. But this is not a background service anymore, your app would become visible whenever a SMS is received.
If you don't want this (if you really want a background service), you have to provide a native implementation.
There is this article on how to create a service on Android with Phonegap which gives some good information on your problem.
It's using a great plugin in order to build a background service with phonegap easily. But you can't use JS though
I didn't find a way to make JS to run in the Background. BUT you can pass parameters from Java to JS and vice versa with the plugin...which is pretty useful.
You would still need to rewrite your JS code in Java though.
Unless you do have a specific reason to only want JS to be run? (But there shouldn't be...)
Hope that could be useful to some people visiting this page.
YES, and it is very simple... just install the plugin backgroundJS:
https://build.phonegap.com/plugins/430
It allows you to run javascript on the background and combined with the local notification plugin, you can even send notifications to the user at any time, just keep in mind that doing this will cause the battery to run out faster, also consider that this might create a problem with the iOS policy. good luck!!!
You can try to add plugin cordova-plugin-background-mode
But as author says:
Infinite background tasks are not official supported on most mobile operation systems and thus not compliant with public store vendors. A successful submssion isn't garanteed.
Use the plugin by your own risk!
I have been working on an Android app using Phonegap and now would like to make it so when the app is closed it can still execute the java/js code in the app. So I understand I need to create a service. If I create a service plugin on phonegap can I still execute the javascript code or only the java?
Has anyone does something like this? I found this discussion but did not seem to work: http://groups.google.com/group/phonegap/browse_thread/thread/722b0e796baa7fc6
So that is all I have right now.
Before I turn to developing it native if I can't figure it out thought I would ask if anyone has done this before. I can't seem to find any of the phonegap plugins that do something similar.
EDIT: I have got an app that executes Java code as a service. However when it calls sendjavascript it does not work. So is there a way to have the javascript code running in the background as well when an app is closed with phonegap?
Thanks
No, it is not possible to run Javascript code in the background (at least in my opinion) as a service. Phonegap on Android uses an special activity called Droidgap, which hosts a WebView. This browser control executes the JavaScript. This means that JS execution can only handled inside this activity, regardless if it is visible or not.
The code you linked from Google Groups tries to bind a service developed in Java to the DroidGap activity, so the service is NOT written in JS.
You can have some background activity within your JS code inside your child activity derived from the DroidGap activity. For example have a background thread in your activity, have a JS callback function and let the thread call this callback functionality.
If you really need a service you have to go native.
Update:
JS code can only be executed with the Droidgap activity. An activity can have 3 states (based on the Lifecycle of activites):
visible
invisible but still loaded
not loaded
I provided a sample in which I implemented a Phonegap plugin. The plugin allows the activity to register itself to SMS_RECEIVED. When the activies goes out of scope (event onbeforeunload), it deregisters, so only issue 1 is handled.
When you want all 3 issues handled, you have to forward the incoming SMS intent to the activity. When it is not loaded the system will automatically load and activate the activity. But this is not a background service anymore, your app would become visible whenever a SMS is received.
If you don't want this (if you really want a background service), you have to provide a native implementation.
There is this article on how to create a service on Android with Phonegap which gives some good information on your problem.
It's using a great plugin in order to build a background service with phonegap easily. But you can't use JS though
I didn't find a way to make JS to run in the Background. BUT you can pass parameters from Java to JS and vice versa with the plugin...which is pretty useful.
You would still need to rewrite your JS code in Java though.
Unless you do have a specific reason to only want JS to be run? (But there shouldn't be...)
Hope that could be useful to some people visiting this page.
YES, and it is very simple... just install the plugin backgroundJS:
https://build.phonegap.com/plugins/430
It allows you to run javascript on the background and combined with the local notification plugin, you can even send notifications to the user at any time, just keep in mind that doing this will cause the battery to run out faster, also consider that this might create a problem with the iOS policy. good luck!!!
You can try to add plugin cordova-plugin-background-mode
But as author says:
Infinite background tasks are not official supported on most mobile operation systems and thus not compliant with public store vendors. A successful submssion isn't garanteed.
Use the plugin by your own risk!
I've seen this in a few tutorials now... but how in the world can Android source code not have a main method and still run.
For example (from http://developer.android.com/guide/tutorials/hello-world.html):
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
That runs but there is no main!!!
I've also thought that using things like onCreate (or formLoad, etc.) was bad becuase a constructor should do that work and such built-in methods can be smelly sometimes. But onCreate is an entry point? Even without a main?
What if there is more than one activity... is there a hierarchy to these built in event handlers? OnCreate trumps everything else? Otherwise, how would the app know what to run or where to enter the program?
Thanks!
Each application will be having it's own Virtual Machine. To run an app, within it's space (VM), must have a main method.
Activities are not the actual classes to be invoked for start of application. There is a class called Application, which will be the root class for an application to be launched.
If there is no main method, how can a VM recognize how to start an app?
Framework has classes called Process, VMRuntime which are responsible for starting an application. Which indeed deal with main method.
For better understanding, study the Zygote service of Android. deals with Applicationmanager Service, ActivityStack Activity Threadds etc.
That runs but there is no main!!!
Of course. Many things that you might think of as a Java "application" do not have their own main() method. For example, IIRC, servlets, WARs, and the like do not have main() methods -- the main() method, if there is one, is in the container.
But onCreate is an entry point?
onCreate() is a method.
What if there is more than one activity... is there a hierarchy to these built in event handlers?
Not really.
OnCreate trumps everything else?
Not really.
Otherwise, how would the app know what to run or where to enter the program?
An app does not "know what to run or where to enter the program".
An Android application is a basket of components. Some components may be tied to icons in a home screen launcher. Some components may be tied to scheduled timers, like cron jobs or Windows scheduled tasks. Some components may be tied to system events, such as when the device is placed into or removed from a car dock. Those components will be automatically created and used when appropriate (e.g., when a user taps the icon in the home screen launcher). Yet other components are only created and used when your code specifically asks for them.
Thinking of an Android application as if it were a monolithic console-mode Java program will cause you no end of trouble.
You tell it which one to run on startup in the manifest file. There isn't a main() because there doesn't have to be, main may be a convention used for "regular" java apps, but it isn't for things like browser applets. The system creates the activity object and calls methods within it, which may or may not be called main. In this case, it's not.
onCreate is different from a main, and from a constructor, in that it can be called twice on a single activity, such as if the process is killed and the user navigates back to the activity. See http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
Actually, this type of pattern is not peculiar of Android, but happens whenever you have some framework in the middle. Some basic examples are java Applets and Servlets. Some of the answers already provide give the correct response, but I will try to elaborate a bit.
When you launch a Java app, you start a JVM and then you need to load something into it: so you need a static method (the main) because there are no objects (yet) living in the JVM that you can refer to.
If you have some sort of framework in the middle, it is the framework that will start the JVM and will start populating it with its own service objects: writing your code then means writing your own objects (which will be subclasses of given "template"). Your objects can then be injected (loaded) by the framework. The framework service objects manage the lifecycle of the injected objects by calling the lifecycle methods defined in the "template" superclass.
So for instance when you provide an applet to a browser, you do not launch a static main method: you rather only provide a subclass of java.applet.Applet that implements some instance methods which act as callback to manage the lifecycle (init, paint, stop...). It is the browser that will launch the JVM, instantiate what's needed for the launching an applet, load your applet and call it.
Similarly, with servlets you subclass the javax.servlet.http.HttpServlet class and implement some instance (non static) methods (doGet, doPost...). The Web container (e.g. Tomcat) will be in charge to launch the JVM, instantiate what's needed for launching a servlet, load your servlet and call it.
The pattern in Android is pretty much the same: what do you do is to create a subclass of android.app.Activity. When you launch an app, the system looks in the manifest to find out which activity should be started, then the "framework" loads it and calls its instance methods (onCreate, onPause, onResume...).
In Java programs we need a main() method, because while executing the byte code the JVM will search for the main() method in the class and start executing there.
In Android, the Dalvik Virtual Machine is designed to find a class which is a subclass of Activity and which is set to start the execution of the application from its onCreate() method, so there is no need of a main() method.
The order in which Dalvik Virtual Machine calls methods is based on order of priorities called android life cycle for more information on android life cycle check the link below
Android Life Cycle: https://developer.android.com/guide/components/activities/activity-lifecycle.html
While there is no specific main entry point, intent filters describe which activity is started when the application is launched.
They are controlled in AndroidManifest.xml as described here:
http://developer.android.com/guide/topics/intents/intents-filters.html
where a note pad application example is described:
This filter declares the main entry point into the Note Pad application. The standard MAIN action is an entry point that does not require any other information in the Intent (no data specification, for example), and the LAUNCHER category says that this entry point should be listed in the application launcher.
An android programmer should learn this like the back of their hands it simply explains everything and would help in the future when creating activities.
http://developer.android.com/reference/android/app/Activity.html
There is a main of sorts, it just happens to be out of your hands. After all, there's nothing special about a main function in any language. It's just the entry point where your code starts executing. The Android operating system expects applications to have a certain structure and it calls your code based on the conventions you follow.
I found this particularly useful...
http://developer.android.com/guide/topics/fundamentals.html#appcomp
Applets don't have main() methods either. It just depends on how your code is packaged.
The Android UI frame encapsulate some Java common details, you can study the source code of the android UI framework
I think that Jonathon's answer is going in the right direction. He says the OS expects a certain structure. There's a name for that structure which is a "state machine". In this case Android calls it the "activity lifecycle". Rob gives a link to the documentation which contains an important diagram of that state machine though the text is a bit dry. A quick search also found me the following link that explains it fairly clearly: http://www.android-app-market.com/android-activity-lifecycle.html
In Java, there is a main even if it isn't listed as main(). The page you get after the icon click, whatever its name, is the main().