This isn't a very advanced question, I just don't understand how exactly to receive intents in Android. I want to update a clock app (only when it's in the foreground) every minute. I guess I have to create a class that extends BroadcastReceiver, and implement the method onReceive(Context context, Intent intent), and add an intent filter in my AdroidManifest.xml? How do I add that filter? Is that the only thing that makes the intent received ACTION_TIME_TICK?
As Android SDK reference states, you have to explicitly register for this intent with:
Context.registerReceiver().
Related
I am developing an android application. This application architecture is divided into 5 modules with 2 modules having multiple features. To develop this app, I am creating 2 process with multiple threads in them as required and 3 other threads. I have a some questions regarding this implementation:
Is this a good model? If not, why not? Right now I am considering only modularity.
I need to send a message from broadcast receiver in process1 to Service thread in process2, what is the best way to do it?
what is the best IPC mechanism in android? I tried to use this link, http://androidapps.org.ua/androidintro_ipc_intent.html which suggests startActivity and startActivityForResult, but these options are not available in broadcast receiver and service does not have startActivityForResult option.
Thank you.
Use Custom BroadcastReceiver
Write this in ActivityA.java
Intent intent = new Intent();
intent.putExtra("message","hi");
intent.setAction("com.android.activity.SEND_DATA");
sendBroadcast(intent);
Write this in ServiceA.java
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Extract data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
}
};
Now register Receiver
LocalBroadcastManager.getInstance(mContext).registerReceiver(mMessageReceiver,
new IntentFilter("com.android.activity.SEND_DATA"));
Just create an Intent in the BroadcastReceiver, add your data as extras, can call startService() with the Intent:
Intent intent = new Intent(context, MyService.class);
intent.putExtra("message", "whatever data you need to pass to the service");
context.startService(intent);
The method onStartCommand() will be called in your service with the passed Intent.
To answer your other question "what is the best IPC method", the answer (as always) is "that depends". Using Intents is the easiest method, as it is supported for all components out-of-the-box. If you need more complicated interaction between components you can look at using AIDL which will allow you to do remote method calls in a Service. If that still isn't enough, then just implement your own socket protocol between the 2 components.
First of all, trying to understand your terminologies. By process, I presume you mean activity and "service thread", I presume you mean a service.
If you want to send a message from onReceive() broadcast receiver, running in context of Activity 1, to a service which is already active, you can try one of the below:
1) Create a new intent (service class name as the class) and call startService() with the intent. Add the additional parameters you need as intent extras. It does not matter if your service is already active, the onStartCommand() is still called, you can have special parameters as intent extras to differentiate a onStartCommand() from onReceive.
2) If your scenario allows this, consider registering to same broadcast event in both your activity and service and act appropriately (then no need to pass messages)
3) Write another broadcast receiver in your service and call sendBroadcast() from the Activity's broadcast receiver
I have some Service class, which registers multiple alarms.
In my BroadcastReceiver class, I want the onReceive() method to call some method of the Service class.
However, I don't see how I can bind them together. I tried to make the BroadcastReceiver an inner class, but then I got more errors and couldn't fire the alarm at all.
Thanks
Look at http://developer.android.com/reference/android/content/BroadcastReceiver.html life cycle. BroadcastReceiver is created only for handling a message. It means that it's life is very short, ant it is also stateless. So you cannot bind anything to it.
Anyway you can try to start a service form onReceive(Context context, Intent intent) method of BroadcastReceiver,
like this:
public void onReceive(Context context, Intent intent) {
Intent intent2 = new Intent(context, GCMService.class);
intent2.putExtras(intent);
context.startService(intent2);
}
Then a=the service should handle a broadcast message.
From the http://developer.android.com/guide/components/bound-services.html
Note: Only activities, services, and content providers can bind to a service - you cannot bind to a service from a broadcast receiver.
I saw in few android ad networks sdks that they are declaring BroadcastReceiver with no intent filters. Something like this:
<receiver android:name="com.example.SampleReceiver" />
My guess is that such receiver would capture all possible events. So I've tried doing it myself and created a SampleReceiver:
public class SampleReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
System.out.println("Event captured: " + intent.getAction());
}
}
I've launched the app, tried to fire some events by doing various action on my phone and noticed that onReceive() wasn't called even once.
So the question is - how does such BroadcastReceiver without intent filters work? Maybe it require the intent filters to be created via code? If so, how? If not, then why isn't it receiving any events? What's going on here?
If you do not have some intent filters, the only way to receive something is to call the receiver explicitly.
This would look like this:
context.sendBroadcast(new Intent(context, MyBroadcastReceiverClass.class));
Another guy already answered this question in the following post:
https://stackoverflow.com/questions/10051256/broadcast-receiver-not-receiving
I think that the following question/answer should give you some clues:
Create an IntentFilter in android that matches ALL intents
I have a question regarding AppWidget intent handling. I have a widget which is clickable, and on click I want to send an intent to the AppWidgetProvider itself for further processing.
The problem: I receive the intents initially in onReceive(), but after a while (not sure what causes it), onReceive() is no longer called.
I have the following code, all in MyWidgetProvider extends AppWidgetProvider.
a) register for receiving broadcasts:
in onEnabled(...):
context.getApplicationContext().registerReceiver(this, new IntentFilter(MY_ACTION));
b) set intent to be fired on click:
in onUpdate(...)
Intent intent= new Intent(MY_ACTION);
PendingIntent pendingIntent= PendingIntent.getBroadcast(context, 0/*notusedanyway*/, intent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.widget_root, pendingIntent);
c) react to event and do something:
in onReceive(...)
if (MY_ACTION.equals(intent.getAction())
doSomething();
When I deploy + add a widget, it works fine. However, after a while - not sure what exactly causes the problem, but a phone call, for example, seems to affect it - I no longer get any notifications in onReceive().
I am completely stumped why this is the case. Can someone point out to me the correct way of doing this?
Thanks!
Tom
You should use a BroadcastReceiver registered in your AndroidManifest.xml file. When you register it in onEnable it is tied to the process. Whenever Android kills your process (for example, when a phone call is received) then your receiver no longer exists and (as you observed) no longer works.
I want to know whether an app can be a BroadcastReceiver and sender? Please expain with an example.
Application can't be a BroadcastReceiver. BroadcastReceiver is an application component. But answer to your question is yes: you can send broadcasts from one component and receive it in another.
For ex. in activity:
Intent intent = new Intent(...);
sendBroadcast(intent);
In receiver:
#Override
public void onReceive(Context context, Intent intent) {
// here is your intent
}
Yes, it can. An example can be found here.
If by app you mean activity, so yes you can but you will have to embed your BroadcastReceiver in your activity and register/unregister it yourself. That way, you just need to add your activity as Activity in the Manifest and you activity will be able to receive a broadcast and send broadcast as well.
I m not too sure how it behaves in term of life cycle though. You will need to look it up if it s what you want.