ResultReceiver from Service to Activity - android

I have a service running in background which is started from an activity and does its work without the activity. With a ResultReceiver I can communicate to the activity, but just as long as the activity is alive. Once destroid and started again there is no communication back to the activity. What did I wrong?
// Activity
public void onReceiveResult(int resultCode, Bundle resultData) {
String test = resultData.getString("Event");
}
public MyResultReceiver mReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mReceiver = new MyResultReceiver(new Handler());
mReceiver.setReceiver(this);
Intent i=new Intent(this, AppService.class);
i.putExtra(AppService.TIME, spinner_time.getSelectedItemPosition());
startService(i);
// Service
public class AppService extends Service {
public static final String TIME="TIME";
int time_loud;
Notification note;
Intent i;
private boolean flag_silencemode = false;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
time_loud = intent.getIntExtra(TIME, 0);
resultReceiver = intent.getParcelableExtra(RESULT_RECEIVER);
resultData = new Bundle();
resultData.putString("Event", "ysfgsdfgsdfg");
resultReceiver.send(55, resultData);
play(time_loud);
return(START_NOT_STICKY);
}
#SuppressLint("ParcelCreator")
public class MyResultReceiver extends ResultReceiver {
private Receiver mReceiver;
public MyResultReceiver(Handler handler) {
super(handler);
}
public void setReceiver(Receiver receiver) {
mReceiver = receiver;
}
public interface Receiver {
void onReceiveResult(int resultCode, Bundle resultData);
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
if (mReceiver != null) {
mReceiver.onReceiveResult(resultCode, resultData);
}
}
}

for simplicity use a local broadcast manager, and register and unregister it in your activity onResume , onPause lifecycles

Related

Cannot using BroadcastReceiver with LocalBroadcastManager

I have 1 activity and 1 service. The service will be started when the activity comes into background and will be stopped when the activity comes into foreground. When the service stops, I want to send an object from it to the activity by intent. Here is my code
MyActivity.java
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_WITH_RLM)) {
//I will get the object received by service here
}
}
};
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_record_lesson_ins);
localBroadcastManager = LocalBroadcastManager.getInstance(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_WITH_RLM);
localBroadcastManager.registerReceiver(broadcastReceiver, intentFilter);
}
#Override
protected void onResume() {
super.onResume();
if (intent != null) {
stopService(intent);
}
}
#Override
protected void onPause() {
super.onPause();
if (intent != null) {
startService(intent);
}
}
#Override
protected void onStop() {
super.onStop();
localBroadcastManager.unregisterReceiver(broadcastReceiver);
}
MyService.java
private RecordLessonModel recordLessonModel;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//I code sth for handle recordLessonModel object
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Intent intent = new Intent(MyActivity.ACTION_WITH_RLM);
intent.putExtra(MyActivity.RECORD_MODEL_NAME, Parcels.wrap(recordLessonModel));
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
The problem here is my broadcastReceiver in MyActivity cannot receive intent from service when my activity comes to foreground. I don't know why.
Thanks.
You should consider unregistering your broadcastReceiver into onDestory() instead of onStop()
because your brodcastReceiver is getting unregistered when activity goes background.
For more look at HERE

BroadcastReceiver is receiving like 1 of 10 intents

On button click I am opening activity(ActionListActivity) and sending intent to IntentService (later this service sends broadCast intent to ActionListActivity). But I am usually receiving only the first intent after launch. Is it real that intent is sent before the receiver is registred?
I want to get data providet by the intentService, and update my UI using it.
Scheme Activity->IntentService->BroadCastReceiver inside ActionListActivity
Activity:
private void selectDrawerItem(MenuItem menuItem)
{
switch (menuItem.getItemId()) {
case R.id.actions:{
Intent myIntent = new Intent(this, ActionListActivity.class);
this.startActivity(myIntent);
ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.show();
Intent dataIntent = new Intent(this, DatabaseWorkIntentService.class);
dataIntent.putExtra(Utils.INTENT_SERVICE_INVOKE, Utils.READ_ACTIONS_DATA);
startService(dataIntent);
progressDialog.dismiss();
}
}
}
IntentService:
private void readActionData(){
Log.e("read actions data","data");
List<Action> actionList;
actionList = Action.listAll(Action.class);
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(Utils.READ_ACTIONS_DATA);
broadcastIntent.putParcelableArrayListExtra(Utils.READ_ACTIONS_DATA, (ArrayList<? extends Parcelable>) actionList);
sendBroadcast(broadcastIntent);
}
ActionListActivity:
public class ActionListActivity extends BaseActivity {
boolean mIsReceiverRegistered = false;
DataBroadcastReceiver receiver;
TextView someTv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.action_list_activity);
this.initToolbarAndDrawerWithReadableName(getString(R.string.our_actions));
someTv = (TextView)findViewById(R.id.someTv);
}
public void someTvTest(Action action){
someTv.append(action.getName());
Log.e("data",action.getName());
}
#Override
protected void onPause() {
super.onPause();
if (mIsReceiverRegistered) {
unregisterReceiver(receiver);
receiver = null;
mIsReceiverRegistered = false;
}
}
#Override
protected void onResume() {
super.onResume();
if (!mIsReceiverRegistered) {
if (receiver == null)
receiver = new DataBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Utils.READ_ACTIONS_DATA);
receiver.setMainActivityHandler(this);
registerReceiver(receiver, filter);
mIsReceiverRegistered = true;
}
}
}
class DataBroadcastReceiver extends BroadcastReceiver{
ActionListActivity activity = null;
ArrayList<Action> list;
public void setMainActivityHandler(ActionListActivity main){
activity = main;
}
#Override
public void onReceive(Context context, Intent intent) {
Log.e("reciever","reciev");
list = intent.getParcelableArrayListExtra(Utils.READ_ACTIONS_DATA);
for (Action action:list){
if(activity!=null) {
activity.someTvTest(action);
}
}
}
}
You start activity and service async.
You need to start service inside ActionListActivity and wait for response.

LocalBroadcastManager not working as expected

In my Application I have to notify my Activity from IntentService class .
For that purpose I am using LocalBroadcastManager. But I am not receiving anything in the onReceive of my Broadcast Receiver. Here is what I have written.
In my BaseActivity I have registered my receiver.
public class BaseActivity extends FragmentActivity implements App {
#Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
}
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(
mMessageReceiver, new IntentFilter(custom-event-name));
}
#Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(
mMessageReceiver);
}
// Our handler for received Intents. This will be called whenever an Intent
// with an action named "custom-event-name" is broadcasted.
BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
System.out.println("Overlay Message" +bundle.getString("message"));
}
};
}
I am sending a local broadcast from my RegisterAlarmIntentService class.
public class RegisterAlramIntentService extends WakefulIntentService implements
APIConstants {
public RegisterAlramIntentService() {
super("AlarmService");
}
#Override
public String getTag() {
return "AlarmService";
}
#Override
protected void onHandleIntent(Intent intent) {
System.out.println("Working till here fine In RegisterAlarm");
Bundle bundle = intent.getExtras();
Intent localIntent = new Intent(custom-event-name);
localIntent.putExtras(bundle );
LocalBroadcastManager.getInstance(this).sendBroadcast(
localIntent);
}
}
onHandleIntent() method is called. But nothing is received in onReceive() of my receiver.
Please Help. Thanks in advance!!
Try
public class RegisterAlramIntentService extends WakefulIntentService implements
APIConstants {
Intent localIntent;
public RegisterAlramIntentService() {
super("AlarmService");
localIntent = new Intent(custom-event-name);
}
#Override
public String getTag() {
return "AlarmService";
}
#Override
protected void onHandleIntent(Intent intent) {
System.out.println("Working till here fine In RegisterAlarm");
Bundle bundle = intent.getExtras();
Thread.sleep(5000); // For Testing only because it is in whole new thread (which may not wait for your reciever to setup)
localIntent.putExtras(bundle );
LocalBroadcastManager.getInstance(this).sendBroadcast(
localIntent);
}
}
Also in manifest :
<service android:name="com.commonsware.android.localcast.RegisterAlramIntentService"/>
See this

IntentService responding to dead ResultReceiver

An activity instantiates a ResultReceiver and overrides onReceiveResult. The activity then sends an Intent to an IntentService and includes the ResultReceiver as an extra. Once the IntentService is finished processing it sends a message back to the ResultReceiver and processes it in onReceiveResult.
The issue is if the user navigates away from the Activity then the result is still sent back to the ResultReceiver which causes all types of issues. Is there not a way to stop this behavior? I've tried stopping the IntentService in the activity's onDestroy() but the result is still sent back.
Here is a sample Activity
public class Foo extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent i = new Intent(this, SampleIntentService.class);
i.putExtra("receiver", mReceiver);
startService(i);
}
#Override
public void onDestroy() {
stopService(new Intent(this, SampleIntentService.class));
mReceiver = null;
super.onDestroy();
}
ResultReceiver mReceiver = new ResultReceiver(new Handler()) {
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
// Handle response from IntentService here
}
};
}
Here is a sample IntentService
public class SampleIntentService extends IntentService {
public SampleIntentService() {
super(SampleIntentService.class.getName());
}
#Override
protected void onHandleIntent(Intent intent) {
ResultReceiver rec = intent.getParcelableExtra("receiver");
if (rec != null) {
rec.send(200, null);
}
}
}
I solved this issue by creating a custom ResultReceiver as follows.
public class SampleResultReceiver extends ResultReceiver {
private Receiver mReceiver;
public SampleResultReceiver(Handler handler) {
super(handler);
}
public void setReceiver(Receiver receiver) {
mReceiver = receiver;
}
public interface Receiver {
void onReceiveResult(int resultCode, Bundle resultData);
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
if (mReceiver != null) {
mReceiver.onReceiveResult(resultCode, resultData);
}
}
}
Then in my Activity I do the following:
public class Foo extends Activity implements Receiver {
private SampleResultReceiver mReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReceiver = new SampleResultReceiver(new Handler());
mReceiver.setReceiver(this);
Intent i = new Intent(this, SampleIntentService.class);
i.putExtra("receiver", mReceiver);
startService(i);
}
#Override
public void onDestroy() {
if (mReceiver != null) {
mReceiver.setReceiver(null);
}
super.onDestroy();
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
// Handle response from IntentService here
}
}
This will cause any messages sent to your custom ResultReceiver to end up nowhere after the Activity has been destroyed :)

Using ResultReceiver in Android

Fundamentally, I would like to establish a callback to an Activity from an IntentService. My question is very similar to the one answered here:
Restful API service
However, in the answer code, the activity code is seen as implementing a ResultReceiver. Unless I'm missing something, ResultReceiver is actually a class, so it cannot perform this implementation.
So essentially, I'm asking what would be the correct way to wire up a ResultReceiver to that service. I get confused with Handler and ResultReceiver concepts with respect to this. Any working sample code would be appreciated.
You need to make custom resultreceiver class extended from
ResultReceiver
then implements the resultreceiver interface in your activity
Pass custom resultreceiver object to intentService and in
intentservice just fetch the receiver object and call
receiver.send() function to send anything to the calling activity in
Bundle object.
here is customResultReceiver class :
public class MyResultReceiver extends ResultReceiver {
private Receiver mReceiver;
public MyResultReceiver(Handler handler) {
super(handler);
// TODO Auto-generated constructor stub
}
public interface Receiver {
public void onReceiveResult(int resultCode, Bundle resultData);
}
public void setReceiver(Receiver receiver) {
mReceiver = receiver;
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
if (mReceiver != null) {
mReceiver.onReceiveResult(resultCode, resultData);
}
}
}
implements the Myresultreceiver.receiver interface in you activity, create a class variable
Public MyResultReceiver mReceiver;
initialize this variable in onCreate:
mReceiver = new MyResultReceiver(new Handler());
mReceiver.setReceiver(this);
Pass this mReceiver to the intentService via:
intent.putExtra("receiverTag", mReceiver);
and fetch in IntentService like:
ResultReceiver rec = intent.getParcelableExtra("receiverTag");
and send anything to activity using rec as:
Bundle b=new Bundle();
rec.send(0, b);
this will be received in onReceiveResult of the activity. You can view complete code at:IntentService: Providing data back to Activity
Edit: You should call setReceiver(this) in onResume and setReceiver(null) in onPause() to avoid leaks.
You override a method by subclassing. It doesn't have to be an interface to do that.
For example:
intent.putExtra(StockService.REQUEST_RECEIVER_EXTRA, new ResultReceiver(null) {
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
if (resultCode == StockService.RESULT_ID_QUOTE) {
...
}
}
});
I have created a simple example that demonstrates how to use ResultReceiver.
MainActivity:
public class MainActivity extends AppCompatActivity {
private final static String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent serviceIntent = new Intent(this, MyService.class);
serviceIntent.putExtra("logName", "MAIN_ACTIVITY");
serviceIntent.putExtra(MyService.BUNDLED_LISTENER, new ResultReceiver(new Handler()) {
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
if (resultCode == Activity.RESULT_OK) {
String val = resultData.getString("value");
Log.i(TAG, "++++++++++++RESULT_OK+++++++++++ [" + val + "]");
} else {
Log.i(TAG, "+++++++++++++RESULT_NOT_OK++++++++++++");
}
}
});
startService(serviceIntent);
}
}
MyService:
public class MyService extends Service {
private final static String TAG = MyService.class.getSimpleName();
public final static String BUNDLED_LISTENER = "listener";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String logName = intent.getStringExtra("logName");
ResultReceiver receiver = intent.getParcelableExtra(MyService.BUNDLED_LISTENER);
Bundle bundle = new Bundle();
bundle.putString("value", "30");
receiver.send(Activity.RESULT_OK, bundle);
return Service.START_NOT_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
for use Resulteceiver in android
Create SomeResultReceiver extends from resultReceiver
Create interface someReceiver with on method for example onReceivResult(int resultCode,Bundle resultData);
3.use someReceiver in someResultreceiver
create someService extends IntentService and use someresultReceiver.send() method for send result from service to someOne class (ex: MyActivity)
Implement somereceiver on Activity
6.instantiation someResultReceiver in MyActivity class and setreceiver
startService with Intent and putExtra someResultreceiver instanse
for more details ResultReceiver Class see enter link description here

Categories

Resources