I am trying to communicate/update UI from Service to activity. The broadcast I receive is not what I had sent. Any ideas why?
Service code:
#Override
//binder returns NULL
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Intent i = new Intent();
i.putExtra("lol", "haha");
i.setAction(MYACTION);
sendBroadcast(i);
Activity code:
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
IntentFilter intentFilter = new IntentFilter(MYACTION);
registerReceiver(recv, intentFilter);
}
BroadcastReceiver recv = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent getintent = getIntent();
String action = getintent.getAction();
//ACTION RECEIVED IS DIFFERENT FROM MYACTION. IT IS ACTION.MAIN
// VALUE RECEIVED IS NULL
String val = getintent.getStringExtra("lol");
}
I have not registered the receiver in manifest. Is it necessary?
As mentioned in comments: I do not receive the same action in broadcast receiver and the value from intent is NULL.
What am I doing wrong?
Thanks for your help.
You dont need to use getIntent, because it translates to Activity's intent, not received broadcast's intent. So in your case, you need to use intent only which refers to broadcasted intent. And make sure you do make a check before reading the desired value from bundle, because there might be a possibility that you are getting another broadcast first which doesn't contain lol in its bundle.
So in your broadcast receiver, do it like this:
....
String val = getintent.getStringExtra("lol");
if(val.equals("your_action_string"){
String val = intent.getStringExtra("lol"); //getIntent() replaced by intent
}
....
P.S. no, you dont need to register any broadcast receiver because it is created and being used programmatically
If you are making web requests or extended tasks I'd check out the async task. It makes it way easier to update the UI. Just make sure you call onPreExecute() and onPostExecute() to do this. I don't like services and receivers.
http://developer.android.com/reference/android/os/AsyncTask.html
Related
I am building a game where I want the user to go through many activities in 20 seconds. Once the 20 seconds is over, I want to send the user to the GameOver screen. To run the timer in the background, I used a service. The issue is, the service doesn't seem to be running?
The weird thing is, that even the toast isn't showing. Here is the place where I call the service:
Here is the manifest:
Please let me know as to why the service or the timer aren't running. Thank you so much for all of your help, I really appreciate it! If you need any more code, just let me know and I will show you. Thanks!
:-)
{Rich}
Services can't interact with UI, which is what Toast does. If you want to do that, try using runOnUIThread along with getApplicationContext or the fancy way with binding/callbacks. Also, take a look at AlarmManager, might be a simpler solution instead of running a service.
BroadcastReciever should be a solution to get and to show the toasts. Just send the message from service and catch it in activity. Then use it wherever you want.
//Service class
final static String ACTION = "ACTION";
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
intent = new Intent();
intent.setAction(ACTION);
intent.putExtra("StartToast", "Started!");
sendBroadcast(intent);
return START_STICKY;
}
//Activity class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent(MainActivity.this, ServiceClass.class);
myReceiver = new MyReceiver();
intentFilter = new IntentFilter();
intentFilter.addAction(ServiceClass.ACTION);
registerReceiver(myReceiver, intentFilter);
}
private class MyReceiver extends BroadcastReceiver {
public String startToast;
#Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
startToast = arg1.getStringExtra("StartedToast");
Toast.makeText(MainActivity.this, startToast, Toast.LENGTH_SHORT).show();
}
Once you register this receiver, you get the message and create a toast automatically when you send data with intent.putExtra(....); .
I'm trying to send a broadcast from IntentService to Activity, but it doesn't work, even the Service did send the broadcast ( I check by debugger tool ).
The strange thing is that I have few other service that broadcast but only this particular one doesn't work.
Here is my code:
IntentService:
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
Intent myItent = new Intent ("test");
sendBroadcast(intent);
}
BroadcastReceiver in MainActivity:
private BroadcastReceiver testbcreceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(getApplicationContext(), "succeed",
Toast.LENGTH_SHORT).show();
System.out.println("success");
}
};
onResume, where I register the BroadcastReceiver. Note that I have 4 service here, 2 out of 4 work fine.
protected void onResume() {
super.onResume();
mds.open();
registerReceiver(testbcreceiver, new IntentFilter("test"));
registerReceiver(downloadServiceReceiver, new IntentFilter(
DownloadChapterService.NOTIFICATION));
registerReceiver(parsingMangaReceiver, new IntentFilter(
ParsingMangaLinkService.NOTIFICATION));
registerReceiver(parsingMangaChapterReceiver, new IntentFilter(
ParsingChapterMangaService.NOTIFICATION));
}
And in AndroidManifest.xml:
<service android:name="anvu.bk.service.ToastService">
</service>
Thank you for looking at my question.
Change it
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
Intent myItent = new Intent ("test");
sendBroadcast(intent);
System.out.println("wait");
}
To
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
Intent myItent = new Intent ();
myItent .setAction(DownloadChapterService.NOTIFICATION); // Define intent-filter
sendBroadcast(myItent );
System.out.println("wait");
}
When creating your intent to be broadcast, prefix your action with your package name and set it like this:
public static final String TEST_ACTION = "anvu.bk.service.TEST_ACTION";
protected void onHandleIntent(Intent intent) {
Intent myItent = new Intent ();
myIntent.setAction(TEST_ACTION);
sendBroadcast(intent);
}
Then, in your onResume(), register your receiver:
IntentFilter filter = new IntentFilter();
//basically, we need the same string as when we were preparing intent for broadcast
//so set action this way, or use string "anvu.bk.service.TEST_ACTION" instead
//of course, use the class name where you declared TEST_ACTION :)
filter.addAction(IntentService.TEST_ACTION);
registerReceiver(testbreceiver, filter);
Then remember to unregister your receiver in onDestroy() with:
unregisterReceiver(testbreceiver);
As a side note, don't use System.out.println() - use Android's Log.d() to log things. Here's why:
System.out.println() (or printf() for native code) should never be used. System.out and System.err get redirected to /dev/null, so your print statements will have no visible effects. However, all the string building that happens for these calls still gets executed.
What’s the difference between an intent used for startActivity() and an intent used for the sendBroadcast() method? In a tutorial, I found an way for dynamically registering a broadcast receiver. For this purpose, I had to provide a string as my intent name. How to choose an intent name in this case and use for sendBroadcast() or registerReceiver()?
Should I add something to my android_manifest.xml file? according to the tutorial, I have currently declared an intent name like this:
private static final String SEARCH_ACTION = "com.example.usingwebservices.rest.SEARCH";
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
unregisterReceiver(receiver);
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
registerReceiver(receiver, new IntentFilter(SEARCH_ACTION));
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(progress!=null){
progress.dismiss();
}
String response = intent.getStringExtra(RestTask.HTTP_RESPONSE);
result.setText(response);
}
};
I think you do right thing. there are two methods to register receiver, following enter link description here:
You can either dynamically register an instance of this class with Context.registerReceiver() or statically publish an implementation through the <receiver> tag in your AndroidManifest.xml.
and the message to queue in service maybe like :
Intent i = new Intent("com.example.usingwebservices.rest.SEARCH");
i.putExtra(RestTask.HTTP_RESPONSE, "msgdetails");
context.sendBroadcast(i);
the intent's contruction ,the parameter is an action name:
Intent(String action)
and when used startActivity, the contruction I used:
Intent(Context packageContext, Class<?> cls)
you can see reference of Intent following here:
and I think Google want package the most msg format .
I am using a Service to listen for a broadcast after boot completed. But the BroadcastReceiver is not registering when boot completed. If instead of a Service I use a BroadcastReceiver to listen for boot completed it works. It doesn't when I register it with a Service. What am I doing wrong? Code is given below.
private BroadcastReceiver sim_change;
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction(action);
sim_change = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "Boradcast Receiver registered successfully", Toast.LENGTH_LONG).show();
}
};
registerReceiver(sim_change, filter);
}#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unregisterReceiver(sim_change);
Toast.makeText(getApplicationContext(), "Boradcast Receiver unregistered successfully", Toast.LENGTH_LONG).show();
}
You have to register for BOOT_COMPLETED in your Manifest. It doesn't make sense to register for it from a Service, because the Service won't be running at boot in order to register for it.
You can't register for BOOT_COMPLETED from within a Service because the reboot removes that registration.
You must do it from your BroadcastReceiver.
There are many ways to handle the enable/disable feature - either using the suggested setComponentEnabledSetting(), or just by storing a value in the app's shared preferences, which you can check when your service starts.
Good day, I have an activity which i navigate to from an icon on an appwidget using pending Intents. Everything is being done in a service class. Now, the activity has a refresh button which when pressed, it sends an intent that calls the onStart() method on the service to update itself and perform some web operations. How do i go about reflecting the changes that could have occurred from the service in the activity without temporarily existing the activity.
Service to Activity:
if(intent.getExtras()!= null){
appWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
//if i get this action from my detailedinfo class add a boolean to it
if(intent.getAction() == refresh_action){
// boolean variable to hold condition
my_action = true;
}
Intent forecast = new Intent(this,detailedInfo.class );
forecast.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
forecast.putExtra("cityname", city);
PendingIntent forecastIntent = PendingIntent.getActivity(this, 0, forecast, 0);
/*onclick to go to detailedInfo class*/
remoteView.setOnClickPendingIntent(R.id.city_image_id, forecastIntent);
if(my_action == true){
//Log.d(TAG, "my_action is true, performing pending intent");
try {
forecastIntent.send(this, 0, forecast);
} catch (CanceledException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
And in the Activity class:
Intent service = new Intent(this, cityService.class);
service.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
service.setAction(refresh_action);
Uri data = Uri.withAppendedPath(Uri.parse(CityWidgetProvider.URI_SCHEME + "://widget/id/"), String.valueOf(appWidgetId));
service.setData(data);
startService(service);
I tried adding a setAction() method to the intent that calls the service and then use the same pendingIntent(even though i think is a long shot) but they seems to be ignored. Please how do i go about this and what could i have been doing wrong.? As usual any help is highly appreciated. Thank you.
I'm not 100% clear on what you're trying to do, but the easiest thing to do would be to register a BroadcastReceiver in your Activity onResume (remove it in onPause). When the service is done with whatever it needs to do, broadcast that info.
In the Activity
public static final String ACTION_STRING = "THE_BIG_ACTION";
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Do whatever you want here
Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT);
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(receiver, new IntentFilter(ACTION_STRING));
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
In the service, when you're done, just call...
sendBroadcast(new Intent(YourActivityClass.ACTION_STRING));
If you want to include some data, just put it in the intent like you would when starting an Activity.
If your Activity is off screen when the service completes, and the user goes back to it, you'll have missed the notification. That's a different issue to resolve.