BroadcastReceiver object only uses initial values, why? - java

Hi I'm trying to run a code which has one activity and a BroadcastReceiver which runs when new message comes and yes it's run clearly but I have a problem with BroadcastReceiver object !
It's part of MainActivity CLASS :
public class MainActivity extends FragmentActivity {
private IncomingSms checkAndDo; //=> OBJECT
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkAndDo= new IncomingSms();
checkAndDo.setProgramState(210); // program state is a variable
checkAndDo.getProgramState(this); // Toast output : " >>>210 "
....
But problem starts when a new message comes and onReceived() called ! IncommingSms class :
public class IncomingSms extends BroadcastReceiver {
private int programState=110; // Which state we are ? 110=> white / 111=> off / 210=>black ...
public void onReceive(Context context, Intent intent) {
final Bundle bundle = intent.getExtras();
this.getProgramState(context);
// This method called again but toast output is : ">>>110"
// which is initial value !?
AND ....
}
public void setProgramState(int status) {
this.programState=status;
}
public void getProgramState( Context context) {
Toast.makeText(context, ">>>"+this.programState , Toast.LENGTH_LONG).show();
}
question : I'm not sure why it happens but onReceive() uses only the initial value which is so bad . ANY Idea?

this.getProgramState(context);
// This method called again but toast output is : ">>>110"
// which is initial value !?
You met that problem because you registered your BroadcastReceiver in the manifest. So Android will create a new BroadcastReceiver and pass the sms broadcast to it.
If you would like to get the state you set in your program, you must register your BroadcastReceiver in your Activity.
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(checkAndDo, filter);

using Intent data instead bundle
Intent(ContextHolder.applicationContext!!, NotificationDeleteReceiver::class.java).setData(conversation.conversationId.toUri())

Related

Calling activity class method from FirebaseMessagingService class

How to call activity class method from fcm service.
I already tried this way Calling activity class method from Service class
but in fcm service onBind method is final so we can not overwrite, so any other way to call activity class method from fcm service.
for reference some code how to implement fcm.
public class FCMListenerService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage message) {
}
}
When my activity is running and fcm notification came then i want to update code? is there any way to handle this requirement ?
I think you have to try with BroadcastReceiver. This is how you send a message from your FCMListenerService:
public class FCMListenerService extends FirebaseMessagingService {
public static final String INTENT_FILTER = "INTENT_FILTER";
#Override
public void onMessageReceived(RemoteMessage message) {
Intent intent = new Intent(INTENT_FILTER);
sendBroadcast(intent);
}
}
And then you can try to catch it this way, using broadcast receiver in your activity:
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateUi();
}
};
Do not forgot to register / unregister your receiver in onCreate() / onDestroy() method from your activity.
onCreate()
registerReceiver(myReceiver, new IntentFilter(FCMListenerService.INTENT_FILTER));
onDestroy()
unregisterReceiver(myReceiver);
Try this Suppose you want to call method of MainActivity;
Make static variable Context context and initialise in onCreate() of MainActivity.
and make the method static which you want to call in MainActivity say
public static void updateUi()
{
// code to update Ui
}
then call from service like this:-
((MainActivity)MainActivity.context).updateUi();
Update:
if you want to perform in multiple activities then you can this method and handle the logic in this updateUi() method

How to get a variable's value from a registerReceiver inner class

Hi I am writing an application for Android. I use Android Studio 2.1 and Android 4.0.3. My application uses Wi-Fi data and I can not get a variable's content from outer class. I am using registerReceiver and I try to get a variable in that register receiver inner class. I'm sorry for my poor English. When I debug, I see that activityString is null. Please help. My code is here:
public class MyActivity extends Activity {
public String activityString; // Here static or not no difference. This is null
public static WifiManager wifi;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.locationscreen);
wifiScanResults();
String[] dataArray = activityString.split("\\.");
// Here I got Null Referance exception. When I debug, activityString is null
}
public void wifiScanResults()
{
wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent intent) {
activityString = "Go";
}
}, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
wifi.startScan();
}
It is a private inner class. I think you can not fetch anything from it. Instead, you should do whatever you will do inside it. For example you can write your code in it.

Sending data without having to start a new Activity

So basically my question is just explained in the title. How can I send data between activities without having to start that activity which receive the data. Here's my code: This is the main activity sending the data :
public class MainActivity extends Activity {
private EditText mainedit1;
private TextView maintext1;
private Button mainadd1;
private Button maindone1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
maindone1=(Button) findViewById(R.id.maindone);
mainedit1=(EditText)findViewById(R.id.mainedit1);
maintext1=(TextView)findViewById(R.id.maintext1);
mainadd1=(Button)findViewById(R.id.mainadd);
mainadd1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String test1= mainedit1.getText().toString();
Intent intent = new Intent(MainActivity.this,test.class);
intent.putExtra("word",test1);
startActivity(intent);
}
});
And this is the activity receiving the data :
public class test extends Activity {
TextView testtext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fortest);
testtext=(TextView)findViewById(R.id.testtext);
Intent intent = getIntent();
String Word = intent.getStringExtra("word");
testtext.setText(Word);
}
So what I did in here is to send the data but also starting the activity, and this is not what I want to share. Please show me how do I fix my code?
It seems you're just looking to save a string for later use. In your MainActivity, just do the following to save the string:
getSharedPreferences("my_prefs", Context.MODE_PRIVATE).edit().putString("word", test1).commit();
Then when you're ready to retrieve it in your test activity, just do so like this:
String Word = getSharedPreferences("my_prefs", Context.MODE_PRIVATE).getString("word", null);
testtext.setText(Word);
You can use sharedprefrence of android following code you can implement
In your MainActivity, just do the following to save the string:
getSharedPreferences("my_prefs", Context.MODE_PRIVATE).edit().putString("word", test1).commit();
Then when you're ready to retrieve it in your test activity, just do so like this:
String Word = getSharedPreferences("my_prefs", Context.MODE_PRIVATE).getString("word", null);
testtext.setText(Word);
OR
Sending data without having to start a new Acitivity, by create static variable
ex.
public class First_Activity extends Activity {
public static String USER_FORMATED_NUMBER = null;
USER_FORMATED_NUMBER="Data you want to pass";
}
public class Second_Activity extends Activity {
String data=First_Activity.USER_FORMATED_NUMBER;
}

How to update Activity from thread started in another activity?

I have a Main activity and after click on button I start thread (but the thread is hidden in library and I have only callback in Main activity.
Now I want to start another activity (call A) where I want to put results from the thread.
Below is simplified code:
public class Main extends Activity {
XManager.ResultsCallback xResultsCallback = new XManager.ResultsCallback() {
// the method is called every 10 sec.
#Override
public void onResult(ArrayList<String> texts) {
}
};
XManager xManager = new xManager(xResultsCallback);
View.OnClickListener onClick = new View.OnClickListener() {
#Override
public void onClick(View arg0) {
XManager.start();
Intent i = new Intent(Main.this, A.class);
startActivity(i);
}
};
}
I want to update the content of A activity each time when onResult() method is called. How to do that?
Use LocalBroadcastManager,
In your Main Activity create function :
private void sendResult() {
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 result!");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
and add BroadcastReceiver in your A Activity
private BroadcastReceiver onResult= new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("jazzy","onReceive called");
}
};
add on OnCreate
#Override
public void onCreate(Bundle savedInstanceState) {
// Register to receive messages.
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("custom-event-name"));
}
add onDestroy
#Override
protected void onDestroy() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onDestroy();
}
I have a suggestion that you should do as follows:
Start Your Activity A on button click
Inside Activity A declare your XManager instance with a callback present in A itself
Then start your XManager as XManager.start(); that way you would be getting all the callbacks in your desired activity.
Have a great day!
I think if you want to decouple the logic, beside you can use the Android BroadcastReceiver, the another flexible choice is to use the Bus
And you can integrate it with gradle easily
dependencies {
compile 'com.squareup:otto:+'
}

Android: Reference to Activity object in another class becomes NULL

What i am trying to do is to pass a reference to the mainactivity to another class and use it.
when i first pass the reference it is not null. but later when i use it in an event handler it becomes null.
here is the code:
public class MainActivity extends MapActivity implements SmsReceivedListener {
SmsReceiver smsreceiver = new SmsReceiver();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
smsreceiver.setSmsReceivedListener(this);
}
public void drawme() {
// do smth
}
#Override
public void onSmsReceived(String id, String lon, String lat) {
Toast.makeText(this, "SMS delivered", Toast.LENGTH_LONG).show();
}
}
The other class where I obtain the reference:
public class SmsReceiver extends BroadcastReceiver {
private SmsReceivedListener listener;
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
#SuppressLint("NewApi")
#Override
public void onReceive(final Context context, final Intent intent) {
// Here it is NULL
if(listener!=null)
listener().onSmsReceived(carNumber, lon,lat);
}
public void setSmsReceivedListener(SmsReceivedListener mainActivity) {
//It is no null when I first set the object here
listener = (mainActivity);
}
}
It will only "become" null if you
set it to null
use it in a way which is not thread safe and you are reading in a different thread to setting
you are using the same field, but in a different object.
You are not registering the SmsReceiver, therefor i guess the following :
The SmsReceiver is registered in the Manifest. Therefore, an instance of the receiver is created by the system when the broadcast is detected, and it is not the same instance as the one you create.
Suggestion : register the receiver in the activity, not in the manifest.

Categories

Resources