简体   繁体   中英

SharedPreferences gives default values on some devices

I am using this code to save key-value pair in shared preferences and its working fine on my device but on emulators and other real devices, it always returns the default values.

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

public static final String USER_PREFS = "com.aamir.friendlocator.friendlocator.USER_PREFERENCE_FILE_KEY";
SharedPreferences sharedPreferences;

private static String userKey="";

GoogleApiClient mGoogleApiClient;
Location mLastLocation;

static final int PERMISSION_ACCESS_FINE_LOCATION = 1;
boolean FINE_LOCATION_PERMISSION_GRANTED = false;



TextView textViewLocationData;
TextView textViewKeyDisplay;
Button buttonRefresh;
Button btnCopyKey;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);

    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            goToActivityFriends();
        }
    });
    fab.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_people_white_48dp));
    textViewLocationData = (TextView) findViewById(R.id.textViewLocationData);
     textViewKeyDisplay =(TextView) findViewById(R.id.tvKeyDisplay);
    buttonRefresh = (Button) findViewById(R.id.buttonRefresh);
    btnCopyKey = (Button) findViewById(R.id.btnCopyKey);
    sharedPreferences = getApplicationContext().getSharedPreferences(USER_PREFS, Context.MODE_PRIVATE);
    String key = sharedPreferences.getString("key", "");
    if(!key.equals("")) {
        textViewKeyDisplay.setText(key);
    }
    // Create an instance of GoogleAPIClient.
    buildGoogleApiClient();

    //user_sp = getSharedPreferences(USER_PREFS, 0);

    buttonRefresh.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            displayLocation();
        }
    });

    btnCopyKey.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
            ClipData clip = ClipData.newPlainText("userKey", textViewKeyDisplay.getText().toString());
            clipboard.setPrimaryClip(clip);
            Toast.makeText(getBaseContext(), "Key copied !", Toast.LENGTH_SHORT).show();
        }
    });
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
protected void onStart() {
    super.onStart();
    if (mGoogleApiClient != null) mGoogleApiClient.connect();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

protected synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API).build();
}

private void displayLocation() {

    int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
    if ( permissionCheck != PackageManager.PERMISSION_GRANTED)
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},PERMISSION_ACCESS_FINE_LOCATION);

    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

    if (mLastLocation != null) {
        double latitude = mLastLocation.getLatitude();
        double longitude = mLastLocation.getLongitude();

        textViewLocationData.setText(latitude + ", " + longitude);
        sharedPreferences = getApplicationContext().getSharedPreferences(USER_PREFS, Context.MODE_PRIVATE);
        String key = sharedPreferences.getString("key", "");
        Log.d("User Key",key);
        updateServers(latitude, longitude,key);

    } else {
        textViewLocationData
                .setText("Couldn't get the location. Make sure location is enabled on the device");
    }
}
@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_ACCESS_FINE_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                FINE_LOCATION_PERMISSION_GRANTED = true;
                //displayLocation();
            } else {
                FINE_LOCATION_PERMISSION_GRANTED = false;
            }
            return;
        }
    }
}

@Override
public void onConnectionFailed(ConnectionResult result) {
    Log.i("", "Connection failed: ConnectionResult.getErrorCode() = "
            + result.getErrorCode());
}

@Override
public void onConnected(Bundle arg0) {

    // Once connected with google api, get the location
    //displayLocation();
}

@Override
public void onConnectionSuspended(int arg0) {
    mGoogleApiClient.connect();
}

public void goToActivityFriends () {
    Intent intent = new Intent(this, com.aamir.friendlocator.friendlocator.Friends.class);
    startActivity(intent);
}

public void updateServers(Double lat,Double lon,String Key) {
    if (Key.equals("")) {
        Retrofit.Builder builder = new Retrofit.Builder()
                .baseUrl("")
                .addConverterFactory(GsonConverterFactory.create());
        Retrofit retrofit = builder.build();
        SendLocation cleint = retrofit.create(SendLocation.class);

        Call<com.aamir.friendlocator.friendlocator.Models.SendLocation> call = cleint.registerUser(String.valueOf(lat), String.valueOf(lon), Key);

        call.enqueue(new Callback<com.aamir.friendlocator.friendlocator.Models.SendLocation>() {
            @Override
            public void onResponse(Call<com.aamir.friendlocator.friendlocator.Models.SendLocation> call, Response<com.aamir.friendlocator.friendlocator.Models.SendLocation> response) {
                Log.d("Response", response.body().getUserKey());
                if (!response.body().getUserKey().isEmpty()) {

                    String key_user = response.body().getUserKey();
                    textViewKeyDisplay.setText(key_user);

                    // Writing data to SharedPreferences
                    SharedPreferences.Editor editor = sharedPreferences.edit();
                    editor.putString("key", userKey);
                    if(editor.commit()){
                        Log.d("saved","saved");
                    }



                }

            }

            @Override
            public void onFailure(Call<com.aamir.friendlocator.friendlocator.Models.SendLocation> call, Throwable t) {
                Log.e("Response", t.toString());
            }
        });


    }
    else {
        Retrofit.Builder builder = new Retrofit.Builder()
                .baseUrl("http://demoanalysis.com/pro03/FriendLocator/")
                .addConverterFactory(GsonConverterFactory.create());
        Retrofit retrofit = builder.build();
        SendLocation cleint = retrofit.create(SendLocation.class);

        Call<com.aamir.friendlocator.friendlocator.Models.SendLocation> call = cleint.updateLocation(String.valueOf(lat), String.valueOf(lon), Key);

        call.enqueue(new Callback<com.aamir.friendlocator.friendlocator.Models.SendLocation>() {
            @Override
            public void onResponse(Call<com.aamir.friendlocator.friendlocator.Models.SendLocation> call, Response<com.aamir.friendlocator.friendlocator.Models.SendLocation> response) {
                Log.d("Response", response.body().getLocationStatus());
                if (!response.body().getLocationStatus().isEmpty()) {
                    Toast.makeText(MainActivity.this,response.body().getLocationStatus(),Toast.LENGTH_LONG).show();

                }

            }

            @Override
            public void onFailure(Call<com.aamir.friendlocator.friendlocator.Models.SendLocation> call, Throwable t) {
                Log.e("Response", t.toString());
            }
        });

    }


}

}

On some devices, it's working perfectly. I did change context from this to getApplicationContext but no progress. I have updated the code.

Edit:

tl;dr : you write the wrong variable into the preferences.

Your variable userKey is never written and always an empty string. In your retrofit onResponse you put userKey as value of "key" into the preferences. This writes an empty string into the preferences. This will work and give you no error.

Please assign userKey with the value of key_user . Your response is only stored to key_user .

Or directly remove the local variable key_user as follows:

public void onResponse(Call<com.aamir.friendlocator.friendlocator.Models.SendLocation> call, Response<com.aamir.friendlocator.friendlocator.Models.SendLocation> response) {
                Log.d("Response", response.body().getUserKey());
                if (!response.body().getUserKey().isEmpty()) {

                    String userKey = response.body().getUserKey();
                    textViewKeyDisplay.setText(userKey);

                    // Writing data to SharedPreferences
                    SharedPreferences.Editor editor = sharedPreferences.edit();
                    editor.putString("key", userKey);
                    if(editor.commit()){
                        Log.d("saved","saved");
                    }
                }  
            }

Before:

In your code to save, you directly try to gather the previously saved value using editor.apply();

As documentation states out, apply will save your changes in background on a different thread.

Therefore your changes might not be saved at the time you try to get the value, some lines below.

Try to use editor.commit(); instead and check if the problem is still there.

I'm share here my own Preference Class it's too easy so you can put in any project.

Put this class into your util folder or anywhere.

AppPreference.java

package util;

import android.content.Context;
import android.content.SharedPreferences;

/**
 * Created by Pranav on 25/06/16.
 */
public class AppPreference {

    public static final String PREF_IS_LOGIN = "prefIsLogin";

        public static final class PREF_KEY {
        public static final String LOGIN_STATUS = "loginstatus";
    }

    public static final void setStringPref(Context context, String prefKey, String key, String value) {
        SharedPreferences sp = context.getSharedPreferences(prefKey, 0);
        SharedPreferences.Editor edit = sp.edit();
        edit.putString(key, value);
        edit.commit();
    }

    public static final String getStringPref(Context context, String prefName, String key) {
        SharedPreferences sp = context.getSharedPreferences(prefName, 0);
        return sp.getString(key, "");
    }

}

Set Preference Value in Login.java when user Login set value like this :

 AppPreference.setStringPref(context, AppPreference.PREF_IS_LOGIN, AppPreference.PREF_KEY.LOGIN_STATUS, "0");

Then you will get Login Status Value in any Class by Calling like this :

 String LoginStatus = AppPreference.getStringPref(context, AppPreference.PREF_IS_LOGIN, AppPreference.PREF_KEY.LOGIN_STATUS);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM