I'm writing an app, that has a somewhat modular system. It has a core app, and some apps, that consist of a single Service, that implements the desired interface. I followed the guide to create the IPC communication. But now I need to get all the services, installed on the system, that my core app can wotk with. How do I do this? I mean, is there any way to mark my Service apps with some kind of a tag, and then filter results, presented by the PackageManager#getInstalledPackages() based on that tag value? What's the common practice of doing so?
Create a custom Intent to which your activities will respond. You can then use PackageManager.queryIntentServices to get your list of matching services. You can get the package info, etc. from the information embedded in the ResolveInfos.
Ideally you'd actually use these intents for invoking the services, but you could always just use them as identification tags and fall back on the binding mechanism you were using before.
Related
I found three ways to share data across applications.
1.Content Provider
2.SharedUserId-When you declare the same shared user id for more than one application, they can reach each other's resources (data fields, views, etc.). provided applications are signed with same certificate.
3.Global Process-Put a component of one application in separate process by using android:process attribute and naming process starting with lowercase letter and another component of another appication in separate process with same name as the separate process of first application.Now these components can share data.
I am confused what to use when or which is more efficient?
I found three ways to share data across applications.
#2 and #3 are the same, insofar as #3 (shared process) requires #2 (sharedUserId).
You also missed all other forms of standard Android IPC, including:
starting activities
starting services
binding to services
sending broadcasts
I am confused what to use when
Ordinary app developers should use #1 (ContentProvider) or one of the other standard Android IPC mechanisms that I outlined above. You have no control over when users update apps, and using formal IPC enforces a clear separation between the apps, forcing you to think through things like API contracts, API versioning, and related concerns.
sharedUserId and shared processes are really there for device manufacturers, where apps are pre-installed and then updated in unison via a firmware update. Personally, I recommend to device manufacturers that they too use standard IPC, for most scenarios. For example, if App A modifies App B's files directly, how does App B find out? What if App B then overwrites App A's changes, because App B did not know about those changes? In many other areas of computer programming, we have gotten away from having multiple processes from multiple apps work with each others files directly.
which is more efficient?
Efficiency should not be an issue in this case, as you should be using any of these techniques infrequently. If you have two apps that need to communicate with each other frequently, then you really have one app, and you should implement it that way.
Before i ask my question i will first explain some background information.
Our company is developing an app for iOS and Android. Our customers can decide to use our app (branded) or integrate our functionality into their app. As our app has some complex algorithms and communication protocols on-board. For this reason we want to provide a kind of SDK for our costumers who wants to integrate instead of using our app.
As we use BLE, NFC and GPS, we decided to make our own apps native. The issue is that many of our customers already have an app which will be a hybrid app in the most cases. So "just" making an SDK for all platforms is almost impossible, not only to build but even more to maintain.
Another important thing to keep in mind is that we want avoid that our customers need to understand our complete communication process, even stronger we won't give our algorithms or communication protocols to others because this is what makes our app/product unique at this moment.
So now the concrete question. Is it possible to provide our functionality as a kind of API so other apps can use the functionality of our app like a kind of API? This means that our app needs to be installed also on the end users smartphone but they don't need to use it individually. The idea is that the app of our customer communicates with our app like an API, our app does the communication with our hardware and gives back the result to the app of our customer. Note that user of the app should not see our app in foreground. (I have the idea from some games who requires "Play Games")
I know there is a way to exchange data between apps (Inter-App Communication) but can this also be used like kind of API?
Obviously this answer relates to Android only. (You may want to ask a separate question for IOS)
At its most basic, a Content Provider is used to exchange data. However, nothing prevents code being run in the provider host to extract that data.
For example, You can host a Content Provider in your app which when called with specific parameters, performs a number of your complex functions and returns a simple table of data (MatrixCursor) or even just a simple True/False response within that cursor.
You could further simplify the usage of this by creating an Android Library that your customers could import into their own project to make it more friendly and API like by adding methods and functions to the library that then delegated their calls to the Content Provider or even to a Broadcast receiver in your main app which could then respond with its own broadcast.
You could even make use of invisible Activities. i.e Call an activity in your app that has no UI.
Even more preferable would be to create your callable code as a self contained library that your customers could use which would negate the need to talk to separate apps completely.
In my understanding, you need other apps to invoke a particular functionality, say call a web API or open an activity and write something or open a popup dialog and do something.
In android: Yeh, it is possible by BroadcastReciever. you only have to listen to the particular action and perform the functionality.
So the task is, you only have to supply the action.
The separation of app and service is just frustratingly disgusting.
The app and service do not have access to each other's variables and data can only be made available to each other through the Messenger. This results in duplication and makes the conversion of PC to Android code an absolute, absolute pain.
Is there an API or some trick to make them share data totally transparently, or do I just have to settle for this cumbersome rubbish implementation (which is the answer that I am expecting)?
You should read the Services developer guide, if you haven't already.
There are a variety of ways for Activity and Service to communicate with each other. If you bind the Service to the Activity, you can share data.
You can also create a custom Application object, which would let you share information across app components. A custom Application acts like a singleton.
Are there any drawbacks to using intents as a form of message passing between two apps that I control?
I have two apks which will always exist on the device together. And, I'd like to use explicit intents to pass messages back and forth as opposed to creating and managing two separate services. Using explicit intents just seems like an easier to manage approach than services.
Communication between applications can expose certain rich, but if you really need to do this way, you can only customizing permissions that your applications will have knowledge. Then you can use BroadcasrReceiver to exchange messages securely using custom permissions.
Defining their permission:
<permission android:name="com.yourapp.PERMISSION"
android:protectionLevel="signature"
android:label="#string/permission_label"
android:description="#string/permission_desc">
</permission>
By setting
<receiver android:name=".MyReceiver"
android:permission="com.yourapp.PERMISSION">
<intent-filter>
<action android:name="com.yourapp.ACTION" />
</intent-filter>
</receiver>
In addition to these permissions you can also set them their purchases Activities, Services, ContentProvider.
Edited
Integration between existing processes in Android (Inter-Process Communication), the AIDL (Android Interface Definition Language).
AIDL is particularly useful when different applications need to
communicate among themselves to exchange information through a
well-defined interface with support for multithreading. Unlike the use
of Messenger with Bound Services with AIDL you are required to create
a file. AIDL containing the declaration of the integration interface,
which helps the client applications to know which operations are
available as well as their respective arguments and returns.
You can use intents to pass data between two apps..however I see once drawback(not too big)-you need to take care that those intents dont get exposed to others.Some malicious app can use the same intents to send bad data something similar to Denial-of-service attacks.
Just to add-if the interactions are in background you can use broadcast receivers too.
Also if the apps are always going to be together why are you not packing them as single app.If you are using parcelables, your flow might break if there are two different incompatible versions of the parcelable.(if you add a field to a object in new version of an app,the other app is still not updated,the app might crash).
Although the discussion here seems really good, at #André.C.S's suggestion, I will add my 2 cents.
Intents are a simple and effective way of passing messages between processes. One of Android's key features, the ability to call another application as a function (Activity.startActivityForResult), depends on it.
As everyone here has already pointed out, intents, whether fired at BroadcastReceivers, Services or Activities, have security issues. If you decide to use them, you will need to protect them. Andre's description of how to use permissions to do that is spot on. You must treat the method that catches the intent as if it were a web service and verify parameters, etc. accordingly.
Finally, Intents, while simple, are really not appropriate for high-bandwidth IPC. If you will be exchanging messages with the other app at a rate measured in milli-seconds, you will want to look into AIDL and a bound service. By my measurements, they are between 1 and 2 orders of magnitude faster.
Incidentally, you might consider running both applications in the same process. There are manifest application attributes that allow that. If you did that, using explicit intents would be easy and your apps would be much safer.
Edited to point out extremely embarrassing error
So, taking my own advice, I tried it. To my horror, as several people have tried to point out, explicit intents can be used across processes.
I am eating a large helping of crow, with humble pie for dessert.
An explicit intent contains a ComponentName object, not an explicit reference to a class object, as I claimed. A ComponentName contains a package name and a class name. The former is, typically, derived from the current context and thus is local to the current process. It is possible, however, to construct an intent with a package name that is an arbitrary string.
I stand corrected.
I've been working with Android for well over a year now, but I still have trouble determining when different types of messaging/communication between processes/threads should be used. I'm mainly talking about broadcasting Intents, using AIDL for services, using Handlers to send messages and socket communication.
Many of these tools can be used to accomplish similar tasks, but which is better suited to particular situations?
This is a pretty open ended question, but let me take a shot at describing how I see the intra/inter application communication working best.
One of the key aspects of Android messaging is the concept of all application components being loosely bound. Because all applications run in a separate process, and one 'app' may actually consist of several applications (responsible for providing different Activities or Services), the messaging techniques are all based around the idea of marshaling messages across process boundaries.
Intents
The preferred technique for messaging, always try to use an Intent whenever possible. It is the most 'native' way to transfer messages within Android.
Advantages
Using Intents for messaging maintains the loose binding of application components, letting you transfer messages seamlessly between several applications. Intents are used heavily within the core system to start Activities and Services, and to broadcast and receive system events.
Using extras Bundles you can include key/value pairs of primitives as payload data within Intents to easily pass information from one application component to another - even if those components are running in different processes.
Disadvantages
Because Intents are designed to go between processes, the extras payload only supports primitive types. If you need to send an object using an Intent you'll need to deconstruct it into primitives at one end and reconstruct it at the other.
Application Class
If you only want to communicate within a single application running in a single process this is a handy solution.
Advantages
By extending the Application class (and implementing it as a Singleton) you get an object that will exist whenever any of your application components exist, providing a centralized place to store and transfer complex object data between application components.
Disadvantages
This technique limits your messaging to components within a single application.
Service Binding, IPC, and AIDL
Binding to a service lets you access its methods and exchange objects with it. AIDL is a way of defining how to serialize an object into OS primitives so that it can be marshalled across process boundaries if the Service you're binding to is running in a separate application.
Advantages
When you bind to a Service you have access to it as though it was an object within the calling class. That means you can execute methods on the Service and exchange rich objects with it.
Note that if you're binding to a Service in a different application process you'll need to create the AIDL definitions that tell Android how to seralize / deserialize any objects you want to pass between applications.
Disadvantages
Creating the AIDL classes for IPC is a bit of extra work, and binding creates additional dependencies between Services and Activities which can make it harder for the kernel to clean up resources when other applications are being starved.
Marshelling messages across process boundaries is expensive though. So if you're not executing methods on a Service, using binding and IPC is probably overkill - see if you can achieve the same thing using Intents.
Sockets
If you're resorting to sockets to communicate within or between applications running on a single device, it's either because there's no other way or you've missed a trick somewhere. If your messages are leaving the device then sockets are a good, fast, alternative. If you're staying on the device chances are Intents or IPC is going to be a better option.
It all depends on the use case and kind of your application. If the application is running all the time better to go with AIDL approach as it is most secure way to communicate. If application need not run all the time, then you can go with either broadcast intent or pending intent approach to communicate between applications.
My 2 cents
I have not used local sockets.
Seems like overkill since you have to
generate and parse the data.
Intents are for either things that
other apps might want to do (launch
me in a compose window or to pick
something out)
AIDL/Parcels/Handlers for having a
GUI talk to a headless process that
is running constantly. Depending on
the app a lot of the actual data
transfer might happen using a content
provider but I tend to have some data
that needs to be transferred outside
of that channel.
This is a good article I found helpful in trying to find a substitute for Cocoa's NSUserDefaults class:
http://developer.android.com/guide/appendix/faq/framework.html