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.
Related
I am trying to implement an Async task that gets a string from a url inside a service.
I am using a startedService which calls the Async task get the correct string, update a public DB class content and return to the main activity, the problem is that the list adapter which i need to notify of the change in the DB is at the main activity and i don't have access to it from the Service , I am a a noobie so I am not familiar with what better to use , started or bind service for that job, any sugestions ?
thank you
You can use BroadcastReceiver :
In your Activity:
#Override
public void onResume() {
super.onResume();
// Register mMessageReceiver to receive messages.
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("mybroadcast"));
}
// handler for received Intents for the "my-event" event
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);
}
};
#Override
protected void onPause() {
// Unregister since the activity is not visible
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onPause();
}
And to Broadcast from service use:
Intent intent = new Intent();
intent.setAction("mybroadcast");
sendBroadcast(intent)
In my App, there is a condition which check every day and if it gets true then I want my App get close in between the run like a crash and stack also gets clear .
I have try and tested many solutions but didn't find the one that works the way i wanted .
My BroadcastReceiver:
public void onReceive(Context context, Intent intent) {
PreferenceForApp prefs = new PreferenceForApp(context);
Bundle bundle = intent.getExtras();
if (bundle!=null){
if(bundle.containsKey("exception")) {
// String e = bundle.getString("exception")
if(bundle.get("exception").toString().equalsIgnoreCase("http request failed with error_msg No Match Found")) {
prefs.setIsDeviceValidated(false);
prefs.setIsLogIn(false);
Log.i("Time", "Exception Occur");
Intent CSPIntent=new Intent(context,CSPLoginActivity.class);
CSPIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP);
CSPIntent.putExtra("close_activity", true);
Log.i("Time", "IntentExit");
context.startActivity(CSPIntent);
}
}
}
}
}
And code to finish in an Activity I am calling from broadcastReceiver:
if (getIntent().getBooleanExtra("close_activity",false)) {
Log.i("Time", "ExitCSPLogin");
this.finish();
}
This code is not closing App in between the run.
You need to register BroadcastReceiver in your activity and send broadcast to BroadcastReceiver when you want to close application.
In your Activity try this:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.package.ACTION_CLOSE");;
BroadcastReceiver Receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
};
registerReceiver(Receiver, intentFilter);
in onDestroy() method of you Activity unregister BroadcastReceiver:
#Override
protected void onDestroy() {
unregisterReceiver(Receiver);
super.onDestroy();
}
Now when you want close application send broadcast to BroadcastReceiver:
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.package.ACTION_CLOSE");
sendBroadcast(broadcastIntent);
Hope this helps!
you have to check below condition in your app's mainActivity's onCreate method every time when user enter in your app. or in onResume if you want to to close your app immediately
if (!prefs.getIsDeviceValidated()) {
Log.i("Time", "ExitCSPLogin");
this.finish();
}
i assume you have more then one activity in your app, so insted of check above flag in every activity we 'll put it in main activity. allow user to use your app until he/she come at mainActivity
Note: create Broadcast Receiver for your App(add in manifest), not for specific activity
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'm stuck here at my previous struggle >> Prev. Struggle!
Raanan there helped! me a lot but then he I think went away as timing zone is different , now I'm stuck with my service code that I'm using to call my BroadcastReceiver() that is in the activity! and also I'm not getting with what parameter I should load the filter.addAction(action); in place of action??
Kinldy guide me!
CODE in the Server:
Toast.makeText(Server.this, hr +" , " +min, Toast.LENGTH_LONG).show();
Intent intent = new Intent(this, andRHOME.class);
//intent.putExtra("sendMessage","1");
sendBroadcast(intent);
and CODE IN THE ACITIVITY(Broadcast Receiver)
private BroadcastReceiver ReceivefrmSERVICE = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "IN DA BroadCASTER",
Toast.LENGTH_LONG).show();
sendMessage("1");
}
};
IntentFilter filter = new IntentFilter();
You need to add these line to regiester your receiver for some action for example define a Global variable like this:
public static String NOTIFCATION_BROADCAST_ACTION = "com.your_packagename.UPDATE_NOTIFICATION_INTENT";
then register the action like this in your activity onCreate() Method.
IntentFilter filter = new IntentFilter();
filter.addAction(Global.NOTIFCATION_BROADCAST_ACTION);
registerReceiver(ReceivefrmSERVICE, filter);
Then send the broadcast from your service like this
Intent broadcast = new Intent();
broadcast.setAction(Global.NOTIFCATION_BROADCAST_ACTION);
sendBroadcast(broadcast);
Then in your broadcast Receiver filter this action like this
private BroadcastReceiver ReceivefrmSERVICE = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Global.NOTIFCATION_BROADCAST_ACTION)) {
//Do your stuff here :)
}
}
};
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