I have a class called FlashlightFragment that allows the user to control the flashlight.
The problem is that the user can turn the flashlight on or off from a number of places. Since all changes to the flashlight pass through a class called FlashlightHelper I want to broadcast a message from it that can be received anywhere on my app. I remember there was a way to do this but I cannot remember the name of the feature.
Basically I want to send a message like: "FLASH_ON" from FlashlightHelper and then set listeners on different fragments and activities on my app that can receive this message.
How is this done?
I won't specialize to the specific situation that you face but instead answer the question in general: How to send a message from one class to another (or to many others).
BroadcastReceiver
Intents and Intent filters
... These are the main methods that will probably be enough for you. Then there are software engineering patterns such as The singleton pattern that will do the trick, but I ll stick to the first to If I were you.
Related
I would like to describe how the communication in my app works in the hopes that someone can tell me if it's good/bad/just okay design.
My app is single Activity multiple Fragments. The Activity has several generic functions such as show/hide a Progressbar animation on the screen or showing a Snackbar. This is functionality that should only be implemented in one place.
My Fragments send broadcasts whenever they need functionality that is not in the Fragment. For example, if the Fragment wanted to show a Snackbar message, I would send a broadcast like this:
localBroadcastManager.sendBroadcast(new SnackBarIntent("Show this text"));
The Activity receives this broadcast, and shows the Snackbar message. Of course, this is a one way message. My Fragment doesn't know if the broadcast was received. But all in all, it works. I can send broadcasts from anywhere, a Service, an Adapter, etc. I can also send Broadcasts between Fragments if I wanted.
I understand there are alternatives to this. There is an EventBus. Or I could pass a reference of the Activity into the Fragment, Adapter, etc. To me this sounds like a terrible idea that could prevent proper garbage collection.
Then there is RxJava where I guess my fragment subscribes to an Observable that I get from the Activity.
But the question remains, is it bad to use BroadcastReceiver in this way? And if so, why?
Is it wrong? No, they were meant for things like this. I'd make sure I was using a local broadcast and not a global one, for efficiency. Some of the alternatives may provide a nicer API or more features, but they all do more or less the same thing.
I would say that unless the part of the code that broadcasts is really buried that you're better off with interfaces and method calls than broadcasts. The problem with any kind of event broadcast is that it decouples the sender and receiver. That can have advantages when you'd otherwise need to pass objects through multiple levels or to places that shouldn't know about that part of the system. But it has drawbacks in maintenance, especially if multiple places can put similar messages on the same bus.
Server sends some discount information, or some video, or other data, and all users who are using the application
will display that message or video in an alert dialog of any activity.
There is a library called Insert.io , that do the job, but my question is that, is there any
way that android provides by which we can achieve this, without using any 3rd party library.
I google this, and according to my understanding we can use broadcast receiver to achieve this, but i am still
unsure that is this the only way, or will it work with server, and trigger itself whenever server send some data to
Client.
Kindly guide me about this
I think we can.
Create a abstract Activity. this Activity register broadcast receiver listen server.
Other Activity extends from this Activity.
sorry. I have not enough reputation to comment :)
You are right, easiest way is to use PushNotifications and receive them in your implemented BroadcastReceiver.
Then, in my opinion, the safest and easiest option would be to use one main Activity with the different fragments you need for your app.
Declare your custom AlertDialog and BroadcastReceiver in your main Activity and you will be able to show the dialog independently the fragment you are showing in that moment.
Hope it helps :)
I'm messing around with one of the Android Samples Bluetooth chat, im relatively new to Android so I'm here to get users opinions, In the main activity class and instance of the class "BluetoothChatService mChatService" is created this does all the controlling of the bluetooth connectivity,
Now I have created a new Activity that launches a page of buttons, these buttons will send certain hardcoded messages depending on which one is pressed, aseen as "mChatService" has been initiated and is handling the connection I would like to make this class instance available in my newly created Activity so I can send messages straight away,
What is the best practices to make this available?, I have read about Serializing the class (which wont work in this instance) so I can pass it in with the Intent, and also singletons?
Can anyone advice what way this SHOULD be done?
Thanks!
If you can't make your class Serializable you could use Parcelable and do intent.putExtra() when sending and intent.getExtras().getParelable() on the receiving end.
Passing a reference to a Bluetooth class might get tricky. You would probably be better handling the message sending back in the original activity.
I am developing an application which has around 8 Activities, and a class which is used to connect/receive data to/from an embedded Bluetooth chip. When I started, a Bluetooth object was initialized in my initial Activity, where there was a Handler which received messages from the Bluetooth object.
After poking around on the internet for a while, it seems like the best idea for me is to turn my class into an Application subclass. However, doing this removes the need for me to initialize an object in the MainMenu, which removes my ability to pass it the Handler used.
Does anyone know of a way to eliminate the need for a Handler, so that every time the Bluetooth Application changes it state or receives data, the current Activity can access it?
My main problem with this approach is that the Activity doesn't know when the Bluetooth Application will be sending it messages, the Application waits and listens, and then notifies the Activity when it happens.
OR
Is it bad practice for me to write the Handler into the MainMenu, have it handle messages for ALL the different activities, and then pass the Handler from Activity to Activity?
I'm going to assume that you're trying to achieve the following as it's a little unclear from your question your ultimate aim (sorry!):
Your application has several activities but only one Activity receives the data from the bluetooth device.
The other activities in in your application require the data from the bluetooth device but are not receiving it directly from the bluetooth device. Currently you're providing the data via the one activity mentioned above.
You want to NOT use a Handler to achieve this.
If my above assumptions are correct then you are going along the correct lines but you probably do not want to use a Handler.
You are quite correct in having one Activity handle all the interactions with the Bluetooth device. It simplifies things and provides a much better, cleaner way of handling the Bluetooth device. However you need to get the data from this one Activity to all the others and to achieve this you would probably want to use Broadcasts, BroadcastReceivers and Intents. See here for an overview.
However if you can you might want to take a look at using LocalBroadcastManager as this keeps any broadcasts within your own app's space. Broadcasts are global and should be avoided if you do not need to pass the data outside of your own app due to security implications.
Finally, have you considered using Fragments for your other Activities? Another disadvantage with Broadcasts is there is extra overhead associated with them. If you're keeping data within your app then you can create an interface to be implemented by each of your Fragments and your main activity just calls that interface on the Fragment that is currently selected.
You can use BroadcastReceiver class to send broadcast messages to your activities. see here http://developer.android.com/reference/android/content/BroadcastReceiver.html
When you get the data you need into the application class, you can send it to the activity you want.. just make sure that the activity has registered to receive that broadcast message..
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.