Where I start an async task in activity A, and immediately start activity B. On completion of background task in activity A, I want to update UI of activity B. Here is the prototype of the code:
public class ActivityA extends Activity{
public void onCreate() {
// Starting asynctask here
BackgroundAsyncTask mBackgroundObject=new BacgroundAsyncTask(getActivity.getApplicationContext());
mBackgroundObject.execute();
// Start Activity B
}
public class BackGroundAsyncTask extends AsyncTask< ... > {
Context context;
public BackGroundAsyncTask(Context mCOntext){
context = mContext;
}
doInBackground(){
// Background Task
}
onPostExecute(){
ActivityB.UpdateUI(context);
}
}
}
public class ActivityB extends Activity {
public void onCreate(){}
public static void UpdateUI(Context mContext) {
// **Here I want to update the UI of Activity B , but it is not happening, looks like it is because context is of activity A**
}
}
Any help in implementation of call back listeners or any other implementation would be of really great help. The issue I'm facing is that I don't get any exception but the UI of activity B doesn't get updated.
create callback from async task
after get result from async task send updated data from activity A to Activity B vai broadcast intent
Register local BroadcastReceiver in Activity B
in onReceive() method of broadcast listener you can get all upadated data vai intent the update your UI
or
Directly send broadcast from onPostExecute() method
I put a small demo here, it's same as the above.
public class TestA extends Activity{
private final String ACTION_NAME = "bc";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
new Thread(){
#Override
public void run() {
// TODO Auto-generated method stub
super.run();
try {
sleep(5000);
Intent mIntent = new Intent(ACTION_NAME);
mIntent.putExtra("yaner", "发送广播,相当于在这里传送数据");
//发送广播
sendBroadcast(mIntent);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
startActivity(new Intent(this, TestB.class));
}
}
public class TestB extends Activity{
private final String ACTION_NAME = "bc";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//注册广播
registerBoradcastReceiver();
}
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals(ACTION_NAME)){
Log.d("aaa", "TestB onReceive:"+intent.getStringExtra("yaner"));
}
}
};
public void registerBoradcastReceiver(){
IntentFilter myIntentFilter = new IntentFilter();
myIntentFilter.addAction(ACTION_NAME);
//注册广播
registerReceiver(mBroadcastReceiver, myIntentFilter);
}
}
Related
I want to update an Activity which is not the MainActivity.
So I start a second Activity via a onClick method in MainActivity.
Now the Activty "SecondActivity" is at front.
When I started a Thread in the "MainActivity" how can I reference to the "SecondActivity" to update their TextViews and so on?
PseudoCode
public class activity_MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ThreadSome threadSome= new ThreadSome();
threadSome.start()
}
onClick(View View){
Intent intent = new Intent(this, activity_Second.class);
startActivity(intent);
}
}
Inside Thread
public class ThreadSome extends Thread {
#Override
public void run() {
//This is what I don't know, so I just write what I want to do.
// I know the following Code is wrong and not working.
activity_Second.someTextView.setText("Hi");
}
}
Is a WeakReference the best way to do this, or better work with static TextView objects? How would you solve this problem?
Based on your description, I think you want to do something where there will be some ui change in activity stack based on some event performed in the forground activity. There is a good way to use onActivityResult() via startActivityForResult() but if this is not fullfilling your requirement directly then you can try something like below:
/**
UpdateActivity is the activity where some ui update or action will be taken based on event in EventActivity.
**/
public class UpdateActivity extends Activity {
private BroadcastReceiver mReceiver;
public static final String ACTION_UPDATE = "com.my.internal.activity.action";
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update);
......
//Prepared Intent for broadcast receiver
IntentFilter intentFilter = new IntentFilter(ACTION_UPDATE);
//registering our receiver
this.registerReceiver(mReceiver, intentFilter);
.....
}
//This is the receiver section where you need to do the ui update
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//extract our message from intent
String some_msg = intent.getStringExtra("msg_1"); //parameter received if passed in intent when broadcast called.
//log our message value
Log.i("Message", some_msg);
updateActivityUi();
}
};
private void updateActivityUi() {
// you need to write the code for the update which you want to do after an event done in other activity.
}
#Override
protected void onDestroy() {
super.onDestroy();
//unregister our receiver
this.unregisterReceiver(this.mReceiver);
}
}
public class EventActivity extends Activity {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event);
......
//Sending BroadcastReceiver against the action ACTION_UPDATE and it will be received by UpdateActivity.
if(condition_for_event) {
Intent i = new Intent(UpdateActivity.ACTION_UPDATE).putExtra("msg_1", "Hey! an event performed here.");
this.sendBroadcast(i);
}
.....
}
....
}
Let me know if it solved your issue.
I Have three activities
On activity A i register the broadcast receiver ,then i go to activity B from there i go to activity C.
and finally onBackPressed of activity c ,i send the broadcast
but onReceive is not called
My first Activity
private MyBroadCastReceiver myRecevier = new MyBroadCastReceiver();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Submit.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent frag=new Intent(MainActivity.this,Activity2.class);
//frag.putExtra("Limit", foo);
startActivity(frag);
// }
}
});
}
#Override
protected void onResume() {
super.onResume();
//Register the activity to the broadcast receiver
registerReceiver(myRecevier, new IntentFilter(MyBroadCastReceiver.ACTION));
}
#Override
protected void onPause() {
super.onPause();
//Unregister the activity from the broadcast receiver. Good practice ;)
unregisterReceiver(myRecevier);
}
public class MyBroadCastReceiver extends BroadcastReceiver{
public static final String ACTION = "com.uberrueco.mybroadcastreceiver.receivers";
#Override
public void onReceive(Context context, Intent intent) {
Log.d("MyBroadCastReceiver", "received");
Toast.makeText(context,"Received "+intent.getStringExtra("editText"), Toast.LENGTH_LONG).show();
}
}
}
Second activity has nothing but an intent to activity 3
Third Activity
public class Activity3 extends Activity {
EditText etReceivedBroadcast;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity3);
etReceivedBroadcast = (EditText) findViewById(R.id.etReceivedBroadcast);
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
Intent intent = new Intent(this, MyIntentService.class);
intent.putExtra("editText", etReceivedBroadcast.getText().toString());
startService(intent);
}
}
and finally my IntentService class
public class MyIntentService extends IntentService{
public MyIntentService(){
super("MyIntentService");
}
public MyIntentService(String name) {
super(name);
}
#Override
protected void onHandleIntent(Intent intent) {
Log.d("MyIntentService", "handling intent...");
//Intent created for broadcasting
Intent intentBroadCast = new Intent();
//Filter the broadcast to the action desired
intentBroadCast.setAction(MyBroadCastReceiver.ACTION);
intentBroadCast.putExtra("editText", intent.getStringExtra("editText"));
//Send the broadcast :D
sendBroadcast(intentBroadCast);
}
}
You are calling unregisterReceiver in onPause of MainActivity . So you are not recieving the broadcast.
Move register to onCreate and unregister to onDestroy of your MainActivity.
if your onHandleIntent() was called then you should try like.
Intent intentBroadCast = new Intent(MyBroadCastReceiver.ACTION);
intentBroadCast.putExtra("editText", intent.getStringExtra("editText"));
//Send the broadcast :D
sendBroadcast(intentBroadCast);
make changes like below code
private MyBroadCastReceiver myRecevier = new MyBroadCastReceiver();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Register the activity to the broadcast receiver
this.registerReceiver(myRecevier, new IntentFilter(MyBroadCastReceiver.ACTION));
Submit.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent frag=new Intent(MainActivity.this,Activity2.class);
//frag.putExtra("Limit", foo);
startActivity(frag);
// }
}
});
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onDestroy() {
super.onDestroy();
//Unregister the activity from the broadcast receiver. Good practice ;)
this.unregisterReceiver(myRecevier);
}
#Override
protected void onPause() {
super.onPause();
//Unregister the activity from the broadcast receiver. Good practice ;)
unregisterReceiver(myRecevier);
}
public class MyBroadCastReceiver extends BroadcastReceiver{
public static final String ACTION = "com.uberrueco.mybroadcastreceiver.receivers";
#Override
public void onReceive(Context context, Intent intent) {
Log.d("MyBroadCastReceiver", "received");
Toast.makeText(context,"Received "+intent.getStringExtra("editText"), Toast.LENGTH_LONG).show();
}
}
}
u need to use like this this.unregisterReceiver() and this.registerReceiver()
I need to use Context object in the function killCall, but I don't know how to pass the Context object to KillCall, could you help me? Thanks!
public class ReceiverCall extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent msgIntent = new Intent(context, InternetServerCall.class);
context.startService(msgIntent);
}
}
public class InternetServerCall extends IntentService{
public InternetServerCall(String name) {
super("InternetServerCall");
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
HandleCall.killCall(context); //Need context
}
}
public class HandleCall {
public static boolean killCall(Context context) {
try {
....
Toast.makeText(context, "PhoneStateReceiver kill incoming call Ok",Toast.LENGTH_SHORT).show();
} catch (Exception ex) { // Many things can go wrong with reflection calls
return false;
}
return true;
}
}
You can get Context into InternetServerCall by doing InternetServerCall.this. And this is because all Android Components overrides Context class, on of them is IntentService.
You can also use getApplicationContext() into IntentService to get context. You can read my another similar answer Pass a Context an IntentService.
But you can not display Toast from IntentService directly, because it needs UI thread but IntentService runs into background thread. You need to use Handler to show Toast, like below example
public class TestService extends IntentService {
private Handler handler;
public TestService(String name) {
super(name);
// TODO Auto-generated constructor stub
}
public TestService () {
super("TestService");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler = new Handler();
return super.onStartCommand(intent, flags, startId);
}
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Handling Intent..", Toast.LENGTH_LONG).show();
}
});
}
}
An IntentService is subclass of Context so you can pass in this:
#Override
protected void onHandleIntent(Intent intent) {
HandleCall.killCall(this);
}
i'm trying to wait for the wifi scan to finish in the broadcast receiver!.
I have 1 Activty (ChooseActivity extends Activity) and 1 class (Scan).
In my Activity i call Scan class to scan wifi and return boolean (true) when finish, here is the code.
My purpose is to separate the scan of my activity because i call scan class in several places.
public class ChooseActivity extends Activity implements OnClickListener{
private int idMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_choose);
idMap = this.getIntent().getExtras().getInt("ID_MAP");
((Button)this.findViewById(R.id.scan_button)).setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.scan_button:
Scan scan = new Scan();
Toast.makeText(getApplicationContext(), " "+scan.scanHotspots(idMap), Toast.LENGTH_SHORT).show();
break;
}
}
}
And here is my Scan class
public boolean scanHotspots(int idMap){
wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
wifiManager.startScan();
receiver = new Receiver();
IntentFilter intentFilter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
context.registerReceiver(receiver, intentFilter);
//HERE I WANT STOP EXECUTION TO WAIT test VAIRABLE CHANGE STATUS
return test;
}
public class Receiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))
{
test=true;
}
}
}
}
Thank you in advance.
I my app I'm calling a Broadcast Receiver to read incoming Text Messages and say it aloud. My Broadcast Receiver gets called properly, it reads the text message properly but when it comes to the speak() method, it just crashes. Here's my code:
This is the BroadcastReceiver:
public class DrivingModeSpeaker extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
// TODO Auto-generated method stub
int n;
Bundle bundle=intent.getExtras();
Object messages[]=(Object[])bundle.get("pdus");
SmsMessage smsMessage[]=new SmsMessage[messages.length];
for(n=0;n<messages.length;n++)
{
smsMessage[n]=SmsMessage.createFromPdu((byte[])messages[n]);
}
//show first message
String sms1=smsMessage[0].getMessageBody();
String from=smsMessage[0].getOriginatingAddress();
Toast toast=Toast.makeText(context,"In DrivingModeSpeaker BR",1);
toast.show();
DrivingMode.speakSMS(sms1);
}
}
And this is DrivingMode.java which contains the speak() method:
public class DrivingMode extends Activity {
private static TextToSpeech myTts;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.message_m);
myTts = new TextToSpeech(this,ttsInitListener);
}
private TextToSpeech.OnInitListener ttsInitListener=new TextToSpeech.OnInitListener() {
#Override
public void onInit(int version) {
// myTts.speak(""+o, 0 ,null);
}
};
public static void speakSMS(String sms)
{
myTts.speak(sms,0,null);
}
}
I have tried out this code in a separate project, it works. But in my main project, it doesn't - could it be because of two broadcast receivers clashing or something? I dunno, I'm new to Android, please help!
Currently you are trying to call Activity method by Creating an instance of Activity which through NullPointerException if Activity is not running. so instead of calling Activity's method start Activity from BroadcastReceiver and send sms data using Intent.putExtra as :
For Example :
public void onReceive(Context context, Intent intent)
{
// Your code here....
Toast toast=Toast.makeText(context,"In DrivingModeSpeaker BR",1);
toast.show();
// start Activity here
Intent intent = new Intent(context,
DrivingMode.class);
intent.putExtra("sms", sms); //<<< put sms text
context.startActivity(intent);
}
and in DrivingMode onCreate method get sms data and call speakSMS method as :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.message_m);
Bundle extras = getIntent().getExtras();
myTts = new TextToSpeech(this,ttsInitListener);
DrivingMode.speakSMS(extras.getString("sms"));
}
also use TextToSpeech.setOnUtteranceCompletedListener for finishing Activity at the end of Speak