I have three switchpreferences in my app (say, switch1, switch2 and switch3). What I want to achieve is whenever switch1 AND switch2 are set to false, switch3 must also be set to false automatically. If either of switch1 or switch2 is set to true, switch3 should also be true. How can I achieve that??
Implement onCheckChangedListener for switch1 and switch2 and add the below statement in your onCheckChanged() callback method.
switch3.setChecked(switch1.isChecked() || switch2.isChecked())
Follow below steps
1) first create local broadcast receiver
#Override
public void onCreate(Bundle savedInstanceState) {
...
// Register to receive messages.
// We are registering an observer (mMessageReceiver) to receive Intents
// with actions named "custom-event".
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("custom-event"));
}
// Inside handler for received Intents. This will be called whenever an Intent
// with an action named "custom-event" is broadcasted.
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
String message = intent.getStringExtra("message");
Log.e("receiver", "Got message: " + message);
//perform logic here to store data etc..
}
};
#Override
protected void onDestroy() {
// Unregister since the activity is about to be closed.
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onDestroy();
}
2) write any user define method like this :
let say I want to call inside button click event ,
private void sendMessage() {
Log.e("sender", "Broadcasting message");
Intent intent = new Intent("custom-event");
// You can also include extra data.
intent.putExtra("message", "Its me !!");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
//Thats it....
}
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)
I have a service that get data from an other application.
When I get date I send message to broadCast in order to refresh the UI.
The onReceive method is called many times and data displayed multiple times.
this is my code:
DataService.java
if(sizeLat == 1) {
sendMessage("Alerte1;");
}
else {
sendMessage("Alerte2;");
}
private void sendMessage(String message) {
Log.w("","==> send message");
Intent intent = new Intent("my-event");
// add data
intent.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
MainActivity.java
// handler for received Intents for the "my-event" event
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("","Onreceiver");
String message = intent.getStringExtra("message");
if(message.equals("Alerte1")){
parentItems.add(message);
adapter.notifyDataSetChanged();
}}};
#Override
protected void onResume() {
Log.d(TAG, "On Resume");
super.onResume();
// Register mMessageReceiver to receive messages.
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("my-event"));}
How can I resolve the problem ?
Put broadcast register line in onCreate and unregister it in onDestroy() method. The line which you have to move from onResume() to onCreate is:-
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("my-event"));}
Possibly, you have two instances of the activity living at the same time. Make a breakpoint on the message receiver and check the address of the instance of your activity class and see if they are different each time the onReceive is called.
There are a few reasons why you could have two instances living at the same time, but one of the most common is leaking context within the activity.
More on this topic.
I fixed same problem by unregister BroadcastReceiver in onPause method
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver,new IntentFilter("my-event")));
Register it in OnResume Method
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("my-event"));}
I'm looking to make my own debug Activity and then update it from various other classes (not just a single class like the other questions I've seen here) using THE LEAST amount of code in my other classes. So ex:
// activity class
public class DebugActivity extends Activity {
public TextView txtView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView txtView = (TextView)findViewById(R.id.text);
}
public someMethod(String text) {
//Update text view code here.
}
// A class updating the text view
public class Some other class {
someOtherMethod {
DebugActivity.someMethod(updatedTextViewSTring);
}
}
The easiest way that i can think of is by sending the data (text) to your DebugActivity. You need to use this code in each activity that work with DebugActivity:
Intent i = new Intent(this, DebugActivity.class);
i.putExtra("text", "some text");
startActivity(i);
And accept that data(text) in the onCreate of DebugActivity :
Bundle b = getIntent().getExtras();
if(b!=null)
String text = b.getString("text");
Note : Theres no use to change the textview in an Activity in realtime because only one activity is displayed at a time.
Elegant way to do is use EventBus lib https://github.com/greenrobot/EventBus
you need to write code like below in DebugActivity
EventBus.getDefault().register(this);
public void onEventMainThread(TextEvent textEvent)
{
txtView.setText(textEvent.getText());
}
after that you can send textevent from anywhere in App like below
eventBus.post(new TextEvent("my Message"));
Or
Pure Android way is use Broadcast / Handler
Here is how to use broadcast
An activity that watches for notifications for the event named "custom-event-name".
#Override
public void onCreate(Bundle savedInstanceState)
{
// Register to receive messages.
// We are registering an observer (mMessageReceiver) to receive Intents
// with actions named "custom-event-name".
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,new IntentFilter("custom-event-name"));
}
// Our handler for received Intents. This will be called whenever an Intent
// with an action named "custom-event-name" is broadcasted.
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
// Get extra data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
}
};
And here is how you will send message from anywere in app
// Send an Intent with an action named "custom-event-name". The Intent sent should
// be received by the ReceiverActivity.
private void sendMessage()
{
Log.d("sender", "Broadcasting message");
Intent intent = new Intent("custom-event-name");
// You can also include some extra data.
intent.putExtra("message", "This is my message!");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
I am trying to develop a android chat application using asmack api and server is openfire.
I am at the stage of handling incoming messages from users and representing them corresponding user chat screen (i.e. activity).
So for that, I developed 2 activities i.e.
public class ResultActivity extends Activity
public class UserActivity extends Activity
resultactivity is the one which maintains roster presence information like online , away etc. so this would be only one instance.
useractivity is the one which maintain chat list with the corresponding user. This activity starts with onclick event on list in ResultActivity. so this can be more than one based on no of users on Result activity..
So to listen to incoming packets (i.e. incoming messages) I added a listener in the ResultActivity which adds messages into global arraylist.
In Result Activity:
PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
MainActivity.connection.addPacketListener(receive_message, filter);
PacketListener receive_message = new PacketListener() {
public void processPacket(Packet packet) {
message = (Message) packet;
String sender=null,body=null,sender_final=null;
if (message.getBody() !=null) {
Log.d("UA", "message from "+StringUtils.parseBareAddress(message.getFrom()));
Log.d("UA", "message is "+message.getBody());
sender = StringUtils.parseBareAddress(message.getFrom());
sender_final=sender.substring(0, sender.indexOf('#'));
body = message.getBody();
Log.d("UA", "Sender : "+sender_final+" body : "+body);
userMessage = new UserMessage("In", sender_final, body);
userMessage_list.add(userMessage);
userMessage_list.add(userMessage);
}
}
};
After adding the message in the global message list (i.e. userMessage_list) I need to update the user activity with incoming message. userMessage_list is the array list used as array in the getview method of base adapter extended class.
So Now I need the update the userActivity list with notifydatasetchanged method.
In UserActivity :
private class UserActivityThread extends Thread {
#Override
public void run() {
UserActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
userAdapter.notifyDataSetChanged();
}
});
}
}
So how to call the notifydatasetchanged method in the another activity.
I am curious to know how this scenario is handled in whatsapp or any chat applications.
I have solved this problem in my chat app by using a ContentProvider class and a CursorLoaderwhich will be automatically notified everytime certain URI has new records.
In your case I would recommend you launching a broadcast message. Your class which has a ListView with the messages will have registered a BroadcastReceiver and it will be listening to possible updates. Everytime your BroadcastReceiver.onReceive is triggered in your activity, refresh your adapter.
Hope it helps :)
EDIT
How to achieve this:
Create a BroadcastReceiver object in your activity.
BroadcastReceiver mReceiver;
Code your broadcast receiver (on your onCreate for example)
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//extract our message from intent
String extra= intent.getStringExtra("extra");
Log.i("msg received: ", extra);
}
};
Add IntentFilter (in your onResume could be valid)
IntentFilter intentFilter = new IntentFilter("com.myproject.myintentfilter");
4.1 register your receiver
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
registerReceiver(mReceiver,intentFilter);
}
4.2 Unregister your receiver
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
this.unregisterReceiver(mReceiver);
}
Make sure your receiver will receive the message, cheking that your sendBroadcast matches the IntentFilter.
Finally:
Intent i = new Intent("com.myproject.myintentfilter").putExtra("extra", "This is a new value");
this.sendBroadcast(i);
EDIT 2
In the case of receiving a message during your activity rotation (receiver is not registered) I have found 2 solutions which I am not very satisfied with, but they work.
Reload your listview after orientation change, as the activity destroys itself, you can just reload the information of your listview, your new message should appear anyway.
Put a static field in your activity, everytime you receive a message, put such variable to TRUE. If your broadcastReceiver triggers, put that variable to false, and when your onResume / onCreate method is called after a change of orientation, check your static variable and do your reload if the variable was true (put it to false after reloading the ListView).
I have a main activity that launches a service to do a web search in the background and I would like the main activity to get an intent when the search is done.
In my main activity , I defined a BroadcastReceiver and an Intent Filter to listen to the "end of search" intent:
public class AgeRage extends Activity {
// Listener to all results from background processes
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ImageSearchService.SEARCH_RESULT_ACTION)) {
0);
Toast.makeText(context,"Got " + i + "results", Toast.LENGTH_SHORT).show();
}
else Toast.makeText(context,"unknown intent", Toast.LENGTH_SHORT).show();
}
};
IntentFilter receiverFilter = new IntentFilter ();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Register to image search service messages
receiverFilter.addAction(ImageSearchService.SEARCH_RESULT_ACTION);
registerReceiver(receiver,receiverFilter);
...
In the service , I do the search and when it is done , I send an Intent:
public class ImageSearchService extends IntentService {
...
protected void onHandleIntent (Intent intent) {
... doing search ...
Intent i = new Intent (this,AgeRage.class);
i.setAction (SEARCH_RESULT_ACTION);
i.putExtra(SEARCH_STATUS, (searchStatus ==SearchStatus.DONE) ? true:false);
i.putExtra (SEARCH_RESULT_NUM, totalResultNum);
i.putExtra (SEARCH_ID, searchID);
sendBroadcast (i,null);
}
But, the main activity doesn't get the Intent. I know that the sendBroadcast is being called and the the receiver's OnReceive is not (checked with a debugger).
I assume that since I create the filter dynamically , I do not need to define a filter in the manifest file.
Am I doing something wrong ?
Thanks
Isaac
Ok. Well I just checked mine and we are doing it the same way, however ...
ImageSearchService.SEARCH_RESULT_ACTION
Try doing com.yourpackagename.ImageSearchSrvice.SEARCH_RESULT_ACTION
where SEARCH_RESULT_ACTION is a public static string variable. See if that helps.
I think it must be the naming of the ACTION. Also note that you might want to run tru the breakpoints and just check log. do intent.getAction() and print this out rather than checking inside the if statement. Just always print it out and see. Don't need to break inside a broacast receiver it will crash after a while.