I have been searching for an answer for at least a week and I still can't get a straight answer that will fix the issue I have with my code. I'm fairly new to android development so I assume there is some deeper level understanding that I am missing.
I am developing an app that gets data from the internet so i tried to implement safeguards to prevent the app from crashing and ruining the user experience while there is no service.
I did this is using a onSharedPreferenceChanged
. I created an activity that is called when there is no service (I test this using Airplane mode) and other reasons such as wifi connection and user selected preferences for using wifi only to download data.
Now, it worked a few times and stopped working and I can't figure out why.
I looked at Stack OverFLow
for a few days and I ran into a wall.
I was led to this question:
Different approaches to a Listener when I asked my own question. This question is different because that question was asking for a specific answer to why my code doesn't work. I also used the android studio
documentation but it was outdated.
I don't want to keep asking questions about my code because I use the SharedPreferences.OnSharedPreferenceChangeListener
in several activities so I just want to ask, How exactly does it work?
I know that it uses a WeakHashMap which gets garbage collected often, but I thought implementing
it would solve the issue. But it didn't for some reason, the sharedPreferences
values change but the listener
doesn't get called.
Other than researching the question, I wrote a separate app to test just how onSharedPreferenceChanged
works and it worked. This iteration of the code doesn't work though.
public class MainActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener{
static final String TAG = "MainActivity";
public static final String SHARED_PREFS = "sharedPrefs";
public static final String WIFI_CONNECTION = "WiFi";
public static final String CELLULAR_CONNECTION = "Cellular";
public static final String CONNECTION = "Connection";
private NetworkCheck networkCheck;
SharedPreferences sharedPreferences;
boolean wifi;
boolean cellular;
boolean connected;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wifiT = findViewById(R.id.wifi);
cellularT = findViewById(R.id.mobile);
connectedT = findViewById(R.id.connected);
sharedPreferences = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
wifi = sharedPreferences.getBoolean(WIFI_CONNECTION, false);
cellular = sharedPreferences.getBoolean(CELLULAR_CONNECTION, false);
connected = sharedPreferences.getBoolean(CONNECTION, false);
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
switch (key){
case CONNECTION:
connected = sharedPreferences.getBoolean(CONNECTION, false);
Log.i(TAG, "sharedStuff In: connection: " + wifi + " cellular: "
+ cellular + " connected: " + connected);
setStuff();
break;
case WIFI_CONNECTION:
wifi = sharedPreferences.getBoolean(WIFI_CONNECTION, false);
Log.i(TAG, "sharedStuff In: wifi: " + wifi + " cellular: " +
cellular + " connected: " + connected);
setStuff();
break;
case CELLULAR_CONNECTION:
cellular = sharedPreferences.getBoolean(CELLULAR_CONNECTION, false);
Log.i(TAG, "sharedStuff In: cellular: " + wifi + " cellular: " +
cellular + " connected: " + connected);
setStuff();
break;
default:
connected = sharedPreferences.getBoolean(CONNECTION, false);
Log.i(TAG, "sharedStuff In: default: " + wifi + " cellular: " +
cellular + " connected: " + connected);
}
Log.i(TAG, "sharedStuff Out: listener: " + wifi + " cellular: " +
cellular + " connected: " + connected);
}
void setStuff() {
if(wifi)
wifiT.setText("WIfi Is Connected");
else
wifiT.setText("WIfi Is Not Connected");
if(cellular)
cellularT.setText("Cellular Is Connected");
else
cellularT.setText("Cellular Is Not Connected");
if (connected)
connectedT.setText("Network Is Connected");
else
connectedT.setText("Network Is Not Connected");
}
@Override
protected void onStart() {
super.onStart();
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
this.registerReceiver(networkCheck, filter);
PreferenceManager.getDefaultSharedPreferences(this)
.registerOnSharedPreferenceChangeListener(this);
}
@Override
protected void onStop() {
super.onStop();
if (networkCheck != null) {
this.unregisterReceiver(networkCheck);
PreferenceManager.getDefaultSharedPreferences(this)
.unregisterOnSharedPreferenceChangeListener(this);
}
}
The preferences are loaded from another activity that uses `ConnectivityManager'. I've tested it extensively and it works every time so far.
I want my app to "see" that service has changed on the user's phone and act accordingly. For example, i have the app opening, and if there is no service, it will not ask for data from google and facebook until there is service and if there is no wifi service and the user specifically wants to only use wifi, the user will be notified about that their choice is being implemented.
This is why my question is more of a conceptual question than a "why isn't my code working" question. I thought I understood how it worked, but it doesn't work I must be wrong.