I'm new to Android development and I couldn't find this in the Dev Guide.
I would like to create a background service so that any other app could connect to it and get some data from it. I saw android.app.Service, but it seems that it only allows other apps to ping the service, it doesn't allow them to register for some specific events.
I had in mind something like the built in LocationManager and its addProximityAlert or even requestLocationUpdates.
Is anything like this possible with the existing sdk?
maybe this sample could help you: RemoteService.
This is the description from android developer site:
Remote Service Controller and Remove
Service Binding
Demonstrates starting a service in a separate process, by assigning
android:process=":remote" to the
service in the AndroidManifest.xml
file. Shows how those clients can
either start/stop it with {#link
android.content.Context#startService
Context.startService} and {#link
android.content.Context#stopService
Context.stopService}, or bind and call
it with {#link
android.content.Context#bindService
Context.bindService} and {#link
android.content.Context#unbindService
Context.unindService}. Binding is
similar to the local service sample,
but illustrates the additional work
(defining aidl interfaces) needed to
interact with a service in another
process. Also shows how a service can
publish multiple interfaces and
implement callbacks to its clients.
Hi and welcome to android development. I hope you enjoy your stay :D.
About your question:
What you are asking is done with a Service.
If you want apps to register for events what is usually done is the following:
Create the service with all the logic.
Make the service send a Broadcast msg.
All interested apps will have a receiver class to get that msg.
I would like to know what you are trying to do to give you further assistance.
Related
I've written a library starting a service in the background. It runs perfectly in all applications.
In order to reduce the RAM usage, I want to avoid running multiple services for different applications. Actually, it's pretty enough to use only one service to get things done.
Firstly, I've written an AIDL file to make IPC between applications/libraries. Defined the service as exported/enabled with signature permission. Since all applications are the exactly the same service, it's not possible to check if any one is up or down. While binding the service to check the condition of the service, it always creates and destroys the own service because of the nature of BIND_AUTO_CREATE flag. That's why not possible to get any kind of info from the exported service if it's really up and running.
Then, I tried to define a Content Provider to the manifest of the library. My aim is to share the service info through it. It's really good mechanism to communicate between exported service and application main process. But it is not usable for multiple instances. Because applications which gets the content provider info from the library use the same authority and so it's not possible to install the second one. It gives an DUPLICATE_PROVIDER_AUTHORITY error.
What's your suggestion about the issue? Is there any option to create a master/slave mechanism? Is it possible to make the service singleton for the application uses the library project?
P.S: Tried broadcast and shared preferences techniques. But they're not effective to listen the callback from the exported service.
You need to put the Service in an APK of its own. It needs to have its own unique package name (in the manifest) which is different from the package names of any of the applications that use it. This is how you make the Service behave as a singleton. Now you can use AIDL and bind to the Service in order to have two-way communication.
Note that in more recent versions of Android, it has become necessary to start a Service using an explicit Intent (ie: the Component must be explicitly specified, you can't use just an ACTION).
Alternative 1:
If the use case permits I think you should not implement the Service.
Make your client implement a service a call your library code. This
is how MediaPlayer and other default android APIs work.
Alternative 2:
Host the service in a separate app..and download the app when the
first call is made from any client. From here onwards there will be
single service handling all the client request.This is how some APIs like adobe
air/ MDM solutions from Airwatch works.
There is no good way you can control a component which is running in other app,unless using broadcast receivers and all.
I have Google source code and want to write one Android Service in lower layer similar to how Android provides for App and Frameworks layer.
Is it possible?
If yes, I want to access this native service in my app though IMyService.Stub.asInterface.
Obviously my that service should be be running in different process and services to be provided by my native service should expose AIDL or something similar.
Of course you can.
First you must define you own protocol, like the message definitions.
Then you implement your server side, register it with service manager, and waiting for the binder calls.
Your client could get the service handle from the service manager and then send binder call to the server.
You can refer to the media_server and mediaplayer source code in AOSP.
I'm using pubnub as a publish/subscribe channel between an android app and a server.
Currently I'm thinking of how I will implement this.
I'm using the provided library for android (https://github.com/pubnub/pubnub-api/tree/master/android) but I think there will be some problems with the application lifecycle if I use it like it is now. (Correct me if i'm wrong)
I was thinking of implementing it as a service
What I want
The service has to keep on running until an hour (negotiable) after the last app usage. That's because we want to have notifications when a message comes in, but the app is not the currently used app.
How do i stop the service after one hour of non-activity of the app? Probably Android will kill it, but I want some control.
The Service must be able to trigger the app to change it's interface when specific messages come in (I was thinking of sending intents from the service when we receive a pubnub message?), pubnub will send data to the service, so I need a way to pass this data to the application (probably save it in a Bundle in the intent?)
I need to listen to multiple pubnub channels (max 2 at the same time), I think I will have to do this in multiple instances of this service?
I think I will do it like this:
Create a service that's started when the app starts
Let the service listen to a pubnub channel
When a message comes in, send an intent and use the intent filters
implement broadcasthandlers to listen to these internal intents
Is this the right way to do this? any hints?
You have an excellent set of questions an detailed points that I will talk about in this answer. You are using Android and you are interested in the conventions and best practices for PubNub Publish/Subscribe scenarios.
Your use case is very common and the best ways to build apps always vary dependent on application needs. However you definitely have the right idea and have asked all the right questions. You just needed some sample code and a direction to get started on implementing the specifics of your application needs. To define your needs in a list:
Connect/Disconnect Ability.
Always-on Background Service that can Send/Receive data and notify other apps via Android Intents.
Connecting to Multiple PubNub Channels at the Same Time.
So to get started I will provide you direct links to some examples and methods:
Create a Service that is Started when when Android Boots: https://github.com/pubnub/pubnub-api/blob/0dfd8028b803332f5641adc909b1a26f87bd7ff1/android/PubnubAndroid/src/com/aimx/androidpubnub/BootReceiver.java
UnSubscribe/Disconnect Example Code when you want to stop listening on a PubNub Channel: https://github.com/pubnub/pubnub-api/blob/0dfd8028b803332f5641adc909b1a26f87bd7ff1/android/PubnubAndroid/src/com/aimx/androidpubnub/MainActivity.java - Listening to multiple channels is easy by placing the blocking pubnub.Subscribe() method inside a Thread.
Regarding your thoughts - This IS the right way to do it:
Create a service that's started when the app starts
Let the Service listen to a PubNub Channel.
When a message comes in, send an intent and use the intent filters.
Implement BroadcastHandlers to listen to these internal intents.
to understand the AIDL in android, i want one real life example, means the at what scenario of development we need to use AIDL.
by reading the Android Docs ... It puts me in confusion and so many question, so it is hard to read whole doc for me, can anyone help me
is it for communicating with outside the phone.
or to communicating with different apps, (why we need to communicate with other apps)
what kind of service they are talking in docs
AIDL is used for Binder. Binder is a mechanism to do RPC calls on/from an Android Service.
When to use AIDL? When you need a Service. When do you need a Service? If you want to share data and control something in another application, you need a service using AIDL as an interface. (A Content Provider is used when sharing data only).
Services can be used within your application as the model roll in the MVC-pattern.
AIDL is Android Interface Definition Language. This basically allows you to do IPC calls.
Use: There are situations where one process would need to talk to other to obtain certain information.
Example: Process A needs info of Call status to determine whether it needs to change Call Type (for example Audio to Video Call or Vice-versa). You may get call status from certain listeners but to change Call type from Audio to Video, Process A needs a hook to change. This "Hook" or way of changing calls is typically part of Telephony Classes which are part of Telephony Process. So in order to obtain such an information from Telephony process, One may write a telephony service (which runs as a part of android telephony process), which will allow you to query or change call type. Since Process A(Client) here is using this remote Service which communicates with Telephony process to alter call type, it needs to have an interface to talk to service. Since Telephony service is the provider, and Process A (client) is the user, they both need to agree on an interface (protocol) they can understand and adhere to. Such an interface is AIDL, which allows you to talk (via a remote service) to Telephony process and get some work done.
Simply put in laymen terms, AIDL is an "agreement" Client gets, which tells it about how to talk to service. Service itself will have a copy of that agreement(since it published for it's clients). Service will then implement details on how it handles once a request arrives or say when someone is talking to it
So process A requests to change call via Service, Service gets the request, it talks to telephony process(since it's part of it) and changes call to video.
An important point to note is, AIDL is only necessary for multithreading environment. You could do away with Binders if you don't need to deal with multithreaded arch.
Another real world example is Google Play License is using AIDL.
I have the same thinking about an example of AIDL, it's very difficult to find an idea to make an example app which uses AIDL. Then I have an idea about it create a LocalLogServerApp. Maybe it can not become a production app but it still shows some value in using AIDL
The main function of this app is
Receive the local log from other local apps (another app need to implement AIDL to send log)
Save the log to datastore
Display the logs
Maybe do something with the local log (eg: search, delete)
Maybe notify developer when error log happened
The benefit of this app
The local log can use when you have some very strange issues which sometimes happened in a few moments and in some specific device. In this case, common Log won't help, debug won't help, Firebase Log may help but Firebase receive log from multiple device.
Reusable, many apps can use it with less code
Hope you find this idea helpful to find another better AIDL example
https://github.com/PhanVanLinh/AndroidLocalLogServer
https://github.com/PhanVanLinh/AndroidLocalLogClientTest
1 - is it for communicating with outside the phone.
Its communicating with outside the app.
2 - or to communicating with different apps, (why we need to communicate with other apps)
As #GodOnScooter mentioned, when your app communicates with telephony service which is actually an other part.
3 - what kind of service they are talking in docs?
This is a service which runs in different process of a system, To bind to this service you need IPC(inter process communication), AIDL is used to implement this.
In Virgil Dobjanschi talk during Google I/O he mentioned using Services for doing the fetching and then using a callback to notify the Activity when this was completed. He never went into specifics on how to implement this callback and I can't seem to find anything helpful on this topic anywhere.
I think he said that you didn't need to implement binding at all?
Any clues?
Option #1: Service sends a broadcast Intent, which the Activity catches via a BroadcastReceiver registered via registerReceiver().
Option #2: If the Activity is binding to the Service, have the Activity pass a listener to the Service, which the Service invokes when the work is complete.
Option #3: Service doesn't do much, but the ContentProvider calls notifyChange() when the data changes, which can ripple back through to the Activity and/or its Cursor on the data.
Option #4: Singletons, which should be avoided.
...
Option #237: Service sends a letter via FedEx to the Activity. :-)
...
All that being said, once they release the Twitter app as open source, you'll know for certain what the Twitter app does.
Check out the Google I/O 2010 app. It uses the pattern he was referring to. It uses Option #2 from CommonsWare's answer.
i think they're talking ab out using AIDL to communicate between the activity & the service...