I am currently working on an architecture to pass traffic messages (“stationary traffic on A9 between Como-Monte Olimpino and Brogeda”) between applications.
Sources of these messages are dedicated apps: one picks up messages via TMC, others might pull them from various services on the Internet.
Consumers are navigation apps in the typical use case, though other use cases are possible as well.
Multiple sources and consumers can be active at the same time.
When a source receives a new message, it sends a broadcast Intent with the message as an extra. Consumers register a BroadcastReceiver to pick up these messages. (Payload for a message typically being a few hundred bytes.)
When a consumer starts up, I need to provide a way for it to poll every source for messages which the source might have in its cache (while bearing in mind that the consumer has no way of knowing which sources are available).
My initial idea was to do that via broadcasts as well: on startup, the consumer would send an implicit broadcast and each source would respond with a broadcast feed of its currently active messages.
Some sources might not be running at the time a consumer starts up, but may still have messages in their cache that need to be delivered to the consumer. As a context-registered BroadcastReceiver would not be able to catch the poll broadcast if the app is not running, it would seem logical to declare te receiver in the manifest.
However, as of Android 8.0, manifest-declared receivers can no longer be used to receive implicit broadcasts. Furthermore, this comment suggests that even on earlier versions and with some flavors of Android, waking up an app via an implicit broadcast does not work as expected (and the device on which I am developing sems to have that restriction as well).
What would be a good mechanism to let a consumer retrieve all currently active messages from all sources, even if they are not running? Implementing a content provider looks a bit like overkill, so what other options are available?
Your consumer app will need to know:
What sources are installed
What subset of those sources the user wants the consumer app to use (as the user might not want all of them)
Possible ways to know what sources are installed include:
Iterating over a list of known possible source application IDs and using PackageManager to see which are installed
Using some application ID naming convention (if you will be the developer of all source apps) and using PackageManager to see which installed apps adhere to that convention
Using PackageManager and queryBroadcastReceivers() to see which apps implement a receiver for some known action string
Using PackageManager to iterate over all installed apps and see which have a certain <meta-data> entry
You can use SharedPreference and a MultiSelectListPreference, or some similar UI, to allow the user to uncheck particular sources that they do not want the consumer app to use.
Given that you are planning on the sources sending broadcasts to consumers, you will also need the same basic flow in the source apps, to see:
What consumers are installed
What subset of those consumers the user wants the source app to work with
Given that the sources know the eligible consumers, and vice versa, you have a variety of IPC options.
It feels like that most of the communications is source -> consumer. In that case, having sources use broadcasts is reasonable. Bear in mind that those will need to be explicit broadcasts:
Create an Intent with the desired action string
Iterate over the application IDs of the eligible consumers
Use setPackage() on a copy of the Intent to associate it with a particular consumer
Send the "broadcast" of that copy
If I am correct that most of the communications is source -> consumer, then using a broadcast from consumer -> source to "wake up" the sources and get cached data is reasonable, if this will simplify the implementation of the sources. It may be that a regular update broadcast is very similar to the "send the cached events" broadcast.
If there will be substantial differences between those two broadcasts, such that not a lot of code would be shared either on the source or the consumer, you might eliminate the asynchronous nature of that approach and use a ContentProvider, where the source has a provider that the consumer can query.
IMHO, your #1 problem with all of this is privacy and security. N-party communications like this gets tricky to make sure that it is not accidentally N+1-party communications, where the +1 is a piece of spyware.
Related
I read that it is possible to use the Web SDK to build a sender app that would run on Chrome in iOS or Android. Is it possible to make that same app being also the receiver to cast to a web enabled TV? So instead of having multiple apps, I'd only have one PWA?
Same codebase? Yes. Same app? No.
The sender and receiver do very different jobs. It's not a bad idea to write your sender and receiver as part of the same project, or to serve them from the same server, but if make your own receiver app then your receiver needs its own URL. (To publish a receiver app, you tell Google your receiver URL, and then Chromecast devices load that url whenever you cast to them.)
Your sender app is complicated. It's responsible for giving the user controls they can click on and sending those messages to the receiver, but it can have a variety of other responsibilities depending on your application. It might do search and browsing, real-time updates, or notifications, and it might let your users write messages or play games or draw beautiful digital art - anything you want your app to accomplish.
The receiver's job is much simpler: play an audio or video file when the sender tells it to. The receiver also needs to respond to play/pause/stop commands and display basic status info, but this functionality is built in to the Cast receiver library, so you don't have to write any of it yourself. You can add bells and whistles like pop-up notifications or custom css styling, but all user interaction happens through the sender app (or from the Google Home app, which acts as a simple remote control). This limitation means that a lot of your features belong only in your sender app, not in the receiver.
Your receiver app is also limited because it has to run on a tiny Chromecast dongle with limited processing and cooling power. Putting unnecessary code into your receiver app could result in the Chromecast overheating and shutting down.
To keep your code as simple as possible, consider using the default Chromecast receiver. This way, you don't have to write or maintain any receiver code. If you need more control over the receiver's styling or behavior, then build your own, but it doesn't have to be complex. The basic Cast Receiver app is thirteen lines of HTML - that's it. Depending on your requirements, you might add css styling, custom message or event handling, or an autoplay queue, but even with all of these features the sample CastReceiver project is only 636 lines of code. Your receiver definitely doesn't need to be as complex as a Slack or Steam desktop web app.
Take advantage of the project-management wins from sharing a codebase with your sender app, but you must keep your receiver small and lightweight. Use the full js/html/css stack if you need to, but consider writing your receiver as a short HTML document, or even using the default receiver. When you keep your receiver functionality to a minimum, you give your users a reliable and responsive Chromecast experience, while still allowing rich interactive features through the sender app.
Hi I'm want to collect user health data. In iOS we have HKObserverQuery to observe.So when ever there is a change in health data for example, change in step count it will wake our app. Is there any thing similar in android for live updates. So I can setup monitoring for any changes.
I been scratching my head for few days. Thank you.
Broadcasts
Android apps can send or receive broadcast messages from the Android system and other Android apps, similar to the publish-subscribe design pattern. These broadcasts are sent when an event of interest occurs. For example, the Android system sends broadcasts when various system events occur, such as when the system boots up or the device starts charging. Apps can also send custom broadcasts, for example, to notify other apps of something that they might be interested in (for example, some new data has been downloaded).
You Could Use LocalBroadcastManager for your App when data changed it will called from your code
Then Register Reciever in manifest
send Broadcast locally fron your app to Broadcast Reciever when data changed in store Like HKObserverQuery
https://developer.android.com/guide/components/broadcasts.html
Yes, there is a CompletableFuture class in java to do so. You can read about it in Java's documentation
Suppose I want to develop an application that extends in some way (let me say "cooperate with") a very popular application I obviously don't have control over. Let us also suppose, for sake of simplicity, that the very famous application author won't release an update to block my application.
I studied the application's functionality and identified that it widely uses BroadcastReceivers. I also know, from manifest, the com.famousvendor.intent.INTENT_NAME constants I might use.
The question is straightforward: if I create an application, namely org.zighinetto.tinyapp with a broadcast receiver set for intent com.famousvendor.intent.INTENT_NAME will the tiny app catch the broadcast? Or can those broadcast be received only by the process that fires them?
will the tiny app catch the broadcast? Or can those broadcast be received only by the process that fires them?
There are a number of things that control this.
If the broadcast is secured with a permission, you will not be able to receive that broadcast unless you also hold that permission. It may not be possible for you to hold that permission, depending on the type of permission that it is.
Also, if the broadcast is an ordered broadcast, higher priority apps will receive that broadcast and can abort it (consuming the event, so lower-priority receivers do not get the broadcast). The priority is set via the <intent-filter> (or IntentFilter), and it may not be possible for you to have one that is higher priority than is their own app, depending upon the priority value the original developer held.
There are also other local-only scenarios (e.g., LocalBroadcastManager), though you would not see those in the manifest, and so we can assume that they are not what is being used here... today.
Let us also suppose, for sake of simplicity, that the very famous application author won't release an update to block my application.
They do not need to specifically block your application. They just need to decide whether or not they really want to have the API you are trying to exploit, and they may choose to lock it down if this was more of an accidental API. They might do so in response to a blog post by a balding guy, for example.
I'm trying to read audio meta data that is broadcast by other apps. There is no standard for broadcasting meta data, but a common way is to send one with an action that ends with .metachanged and extras that list artist, album, etc.
How can I determine what broadcasts are coming from various other apps? If I could just filter all broadcasts, then I could read through them and be able to tell which apps are broadcasting their meta data, and how it's formatted.
How can I determine what broadcasts are coming from various other apps?
You ask the developers of those apps what broadcasts they send out that they support. If you are expecting to be able to discover this programmatically, that is not possible, sorry.
Now, if they happen to listen to their own broadcasts, you may see that in the apps' manifests (if they are not using registerReceiver(). As a developer, you can examine this via apps like AppXplore.
But if this is not part of some documented and supported API by those music apps, then when those music apps change their broadcasts, your app will break.
In a certain situation, I'd like my app to be able to "fake" an incoming SMS on the user's device, as a sort of notification. This would save me money when I'd normally use Twilio to send a text to my users but I know they already have my app. Is there any way to do this? I imagine it would have something to do with Intents and Content Providers but I don't really know where to start.
To clarify:
I'm not new to Android and I do respect all of the normal Notification methods. However, my app will have an opt-in for text messages and I'd like to be able to trigger them for free rather than paying for it. This is for SMS-specific uses and not as a substitute for a normal Notification.
Yes (although I really don't support doing this) it is, in theory possible by creating and broadcasting the proper intent. Specifically, they android.provider.Telephony.SMS_RECEIVED intent will be received by anybody who is listening for SMS messages, including the default SMS application. This will in turn cause the notification to be displayed.
All of that said, I've only ever done this in a custom version of Android from within the system process. I'm really not sure if a generic application can do this (in fact, I kinda doubt it). The other caveat is that you will need to formulate your data into PDU's which represent the binary data format of an SMS message. You can look this up, but it's nontrivial.
A far better approach would be to simply have your application display a notification in the tray, the way well behaved applications are supposed to notify the users of events. Take a look at the Notification class.
If you install the apk named ApiDemos-debug.apk that usually comes installed with your choosen platform for the SDK, you will find an example in
<Api Demos> > App > Notification > IncomingMessage
the complete source for this package is usually under
<SDK root>/samples/android-xx/ApiDemos