I´m working on a portability of a human-machine dialogue open source system JVoiceXML from Java to Android. The system is based on the VoiceXML 2.0 standard which uses XML documents to create the interactions between the human and the machine.
The idea is to provide Android with a means to creat apps that interact with the user via voice using the TTS and SpeechRecognizer android engines.
We´re trying to do so without having any visual effect on the screen, just as a system service would work. For now I´ve tried to implement our system as a service, but I´m having trouble with threading and Android killing my service.
The question is, which approach do you think fits best my proyect, an AsyncTask, a service, a Loader? Maybe a service that starts an AsyncTask or a Loader?
The requirements would be:
My VoiceXML Interpreter gets fired up by an app Intent (intent filter is how I´m having it now)
It recieves a document from the app. Also the app can stop my Interpreter , or at least stop the interpreting of that document.
The Interpreter interacts with the TTS and creates a Speech Recognizer engine.
The Interpreter itself is a java thread that has to be started from the service, loader, or asyncTask.
Only one app can make use of my Interpreter (no need for parallel connections)
Please let me know if more info is needed to comprehend the problem.
thanks in advance,
Marcos.
If the bulk of your work is already done within another thread, I don't see a need for an AsyncTask. Just use the interpreter from your Service. You'll need a Service no matter what if you want to provide something without a user interface.
Related
I'm very new to android technologies. I've recently read that android only allows a REST web service invocation from inside an AsyncTask... Is this true?? I'm developing an app for the university, I have to finish it for tomorrow and I would realy like to know if I can just call the REST WS inside an ordinary function, despite the fact that it may not be a good practice...
Thank you in advice!!
José.
The main thing is that you may not call it on the UI-thread (otherwise you will get an exception). Besides this restriction, it does not matter from where you call it.
A benefit of using AsyncTasks is that they are a very easy way of using additional threads in Android, since it comes with many callbacks (which are run on the UI-thread)
Another alternative could be to use an ExecutorService.
I'm a beginner in android development and I'm trying to implement an android udp client, which connects to a java server and sends/receives some packets from it.In this process it collects some data (like round-trip delay etc), which is used to measure the QoS of that particular network. I have tried implementing the connection and sending/receiving data using Java Threads, but the application crashes, and hangs if i try to use more than 2 threads. So I'm looking for alternatives. While going through this site as well as some other links I found that in android multiple threads can be implemented using AsyncTask, Handler etc. Also I found that the Service class also helps to run a background service in an app. Please suggest which approach among these would be the best to achieve my purpose.
Thanks in advance.
You can use AasyncTask to do this and as you mentioned service may be useful too, where u can let your application do whatever it wants in background , if user needs to use application by its interface then AsyncTask must be used to avoid Crashing
There is not one right answer that can be applied as a broad stroke to how to do Android multi-threading. There are a few different ways to approach it based on what your specific needs are.
Any long running, blocking call, in Android will result in the application crashing.
The most common solution is to use an AsyncTask though. For example, when I want to make a call out to a web API endpoint for some XML data within an Activity I would in this case use an AsyncTask and kick off the calls from within doInBackground.
This is not an appropriate solution though if the wait time is longer, or possibly an unknown wait time. Or in a situation where there will always be waiting such as a message queuing service. In this type of situation it may be best to write a separate app based on extending the Service class. Then you can send/receive notifications to/from the service from your primary application in a similar manner to how you would communicate with a web service.
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!
First I'm sorry for my english that is not so good :).
I am facing a problem to develop my app.
That is a general architecture scheme of my solution.
http://i.stack.imgur.com/ooTmE.png
To be quick, the app has to decode code bare but with two possible ways:
using exernal device (The constructor provides a sdk containing an android Service to communicate with the device),
use the camera of the mobile using the library Zxing which is possible to manage it with intent.
The goal of my own service is to manage some business code and make transparent the choice of the tool for the user.
I believed that was a good solution but I wanted to implement it and I had different problems.
My main trouble is that I cannot execute StartActivityForResult inside the service.
Do somebody have any suggestions for my problem whether a change in the architecture or a solution for the main problem?
#Laurent' : You have totaly right my service acts as an API adapter.
I will try to make the expected behaviour more clear.
I have an app that needs to recognize (real) objects which have QR codes on their top. This recognition action will be done several times by the user during the life of the app.
The user chooses to launch the recognition by clicking on a button (or otherwise but he knows that the recogntion will start). So no notification is needed.
The thing is he doesn't choose the way to do the recogniton. It is why, as you said, I implement an adapter.
The adapter chooses between :
Camera mobile or external device. The first is an activity coming from the Zxing library. The second one is a service that manages the external device. This service provides an interface to get back result.
One more thing, I need that my whole implementation (adapter and co) can be re-used by other apps that will also need to do recognition.
So my thought was to implement a service as an adapter to answer my two conditions (make transparent the choice for the user - and make the recognition available for other apps).
I hope you understand my problematic.
Given your architecture, your MyOwnService must act as an API adapter : it should provide a unified scanning API and address each external service specificities transparently.
Your expected behaviour is not clear enough to provide a solution that suits your needs but here are a few remarks that can be of some help.
Passive scanning:
Even if there are some workarounds : no activity should be launched from a service (not directly). Never. Bad. Services are background stuff, the most they will be permitted is to hint users with Notifications (this is point 2 of Justin excellent answer).
As a consequence there's nothing as a 'popup Activities' (and that's good!). If you need to continuously scan for barcodes, even when your activity is not run, then the only way to warn users is by using status bar notification.
Active scanning:
Inside your own activity you can bind to your wrapper service and make it start scanning for codebars. When it finds one it has to message your activity. Your Activity message handler has complete access to the UI to inform the user of your findings.
You selected Active Scanning in your edit, your problem is therefore to find a way for your service to actively notify your main application (the one that started the active scanning) that a new item has been scanned successfully.
You do NOT do this by starting a new activity (remember: this is bad) but you can bind to a service and/or use Messages between the wrapper service and the application.
I advice you take the time to read (and more time to comprehend) this android developer article on BoundServices and especially the part about Messengers.
A full example of Two Way Messaging between a Service and an Activity can be found in the following android examples : Service & Activity
Warning: designing robust, full blown AIDL-based services is a tough job.
Two ways you could solve this problem.
1) Have MyOwnService do a callback into MainActivity telling it to launch your ScanActivity.
- This is a better approach if MyOwnService's task is only going to be running while MainActivity is running and if the user would expect the ScanActivity to come up automatically.
2) Have MyOwnService create a notification that will let the user access the ScanActivity.
- This is a better approach if MyOwnService's task might be running longer than the life span of MainActivity. That way, you can let the user know, unobstrusively, that they might want to access the ScanActivity.
So finally I changed my architecture.
I make the choice to delete myOwnService and to create an intermediate activity that will be my API Adaptater.
This activity will have a dialog.theme to look like a dialog box indicating that a recognition is under execution.
If the recognition uses the external device this activity will stay at the foreground otherwise the camera activity will start (Being managed by the intermediate activity).
Thank to that I can manage my result from the intermediate activity and do not have an android strange architecture, keeping my business code for the recognition outside my main app.
Service was not the good choice.
Thanks a lot for you help and your time.