Reputation: 38940
Here's my onResume
call in the MainActivity
:
@Override
public void onResume() {
super.onResume();
SharedPreferences settings = context.getSharedPreferences(INSTALL_PREFERENCE, 0);
String referrerString = settings.getString(REFERRAL_KEY, null);
Map<String, String> params = new HashMap<~>();
if (referrerString != null){
params.put("referrer", referrerString);
}
}
Here's my onResume
in the class that extends BroadcastReceiver
:
@Override
public void onReceive(Context context, Intent intent){
try{
String referrerString = intent.getStringExtra("referrer");
if(null != referrerString){
String referrer = URLEncoder.encode(referrerString, "UTF-8");
context.getSharedPreferences(INSTALL_PREFERENCE, Context.MODE_PRIVATE).edit().putString(REFERRAL_KEY, referrer).commit();
}
}
catch (Exception e){
//don't handle exceptions for now
}
}
The issue is that when I call the MainActivity
by opening the app, my app will not return the referrer
on the first open. Is there a reason the SharedPreferences
will not store my referrer
on the first application open? I want to pass back the referrer
on the first open and not the second.
Upvotes: 2
Views: 854
Reputation: 7516
The referrer broadcast is sent slightly after the main component of your app is started. Therefore, you must notify your activity once the broadcast is received.
One simple solution would be to use LocalBroadcastManager between the Receiver and the Activity:
/* BroadcastReceiver */
@Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
String referrer = (String) extras.get(KEY_REFERRER);
// save String to SharedPrefrences
Intent intent = new Intent(ACTION_UPDATE);
intent.putExtra(KEY_REFERRER, referrer);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
/*****/
/* Activity*/
private final BroadcastReceiver mUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String referrer = intent.getStringExtra(KEY_REFERRER);
}
};
@Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mUpdateReceiver);
super.onPause();
}
@Override
protected void onResume() {
LocalBroadcastManager.getInstance(this).registerReceiver(mUpdateReceiver, new IntentFilter(ReferrerReceiver.ACTION_UPDATE));
super.onResume();
}
If you need a fully fonctional sample code/app, check out my OpenSource project on GitHub.
Upvotes: 0
Reputation: 43322
Here is one way you could fix it. Make your Activity implement the OnSharedPreferenceChangeListener interface, which will call the onSharedPreferenceChanged()
callback when any value in the SharedPreference file registered changes.
If the timing is right and you get a value in onResume()
, just carry on as you do in your current code.
If you don't have a value yet, then show a ProgressDialog, and wait for the BroadcastReceiver to populate the value.
Once the value is modified by the BroadcastReceiver, capture the value in onSharedPreferenceChanged()
, and then use it as needed.
Here is the general structure of the solution:
public class MainActivity extends Activity
implements SharedPreferences.OnSharedPreferenceChangeListener {
SharedPreferences settings;
ProgressDialog dialog;
Map<String, String> params;
String INSTALL_PREFERENCE = "installpref";
String REFERRAL_KEY = "referral";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dialog = new ProgressDialog(this);
params = new HashMap<String, String>();
settings = this.getSharedPreferences(INSTALL_PREFERENCE, 0);
settings.registerOnSharedPreferenceChangeListener(this); //added
}
@Override
public void onResume() {
super.onResume();
String referrerString = settings.getString(REFERRAL_KEY, null);
if (referrerString != null){
params.put("referrer", referrerString);
//call whatever methods need params to have a value
//.......
}
else{
//Show progress dialog and wait for BroadcastReceiver to populate referrer
dialog.setMessage("loading");
dialog.show();
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPrefs, String key) {
if (key.equals(REFERRAL_KEY)){
//dismiss dialog if it's showing
if (dialog.isShowing()){
dialog.dismiss();
}
String referrerString = sharedPrefs.getString(REFERRAL_KEY, null);
if (referrerString != null){
params.put("referrer", referrerString);
//call whatever methods need params to have a value
//.......
}
}
}
}
Upvotes: 1
Reputation: 1858
on resume() will be executed before the broadcast receiver and hence for the first time you might be receiving null or default value for the referrer and at later pont of time if you reopen the activity you might be getting correct value because onReceive() would have executed by this time.
If your application has any settings preference screen which actually initialises the settings only after opening it so you may have to initialises all the preferences with default values before using it. It could be the reason that sometimes if you open the application you are getting correct values because you might have opened the setting screen.
Upvotes: 1