【问题标题】:SharedPreferences gives default values on some devicesSharedPreferences 在某些设备上提供默认值
【发布时间】:2018-09-04 12:57:36
【问题描述】:

我正在使用此代码将键值对保存在共享首选项中,它在我的设备上运行良好,但在模拟器和其他真实设备上,它始终返回默认值。

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());
            }
        });

    }


}

}

在某些设备上,它运行良好。我确实将上下文从这里更改为 getApplicationContext 但没有进展。我已经更新了代码。

【问题讨论】:

  • 试试editor. commit(); 我也面临同样的问题。
  • 如果我的回答对你有帮助,那么请把我的回答从勾选标记广告中标记为正确,否则我会删除这个答案兄弟:google.com/…:

标签: java android sharedpreferences


【解决方案1】:

编辑:

tl;dr :您将错误的变量写入首选项。

您的变量userKey 永远不会被写入并且始终是一个空字符串。 在您的改造onResponse 中,您将userKey 作为“key”的值放入 喜好。这会将一个空字符串写入首选项。这将起作用并且不会给您带来任何错误。

请将userKey 赋值为key_user。 您的回复仅存储到key_user

或者直接去掉局部变量key_user如下:

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");
                    }
                }  
            }

之前:

在您要保存的代码中,您直接尝试使用editor.apply(); 收集之前保存的值

正如文档所述,apply 会将您在后台的更改保存在不同的线程上。

因此,在您尝试获取值时,您的更改可能不会保存, 下面几行。

尝试改用editor.commit(); 并检查问题是否仍然存在。

【讨论】:

  • 正如@JacksOnF1re 所说,apply 会将更改保存在另一个线程中。如果您在应用它们后立即检索这些值,则行为确实可能会因场景而异(即使在同一设备上)。您应该使用commitlisten for the changes applied
  • 好吧,我尝试了提交,但它不起作用。甚至提交返回 true 但即使默认值正在打印。
  • 那么您的代码还有一些其他问题,因为commit 可以原子地工作,如 Javadoc 所述。
  • 我怀疑您的运行代码是否存在问题,但是..您在哪里初始化了 sharedPreferences 的第一个实例?这是完整的代码吗?原样的代码应该抛出一个 NPE。
  • 不,这不是完整的代码。我在 onCreate 中初始化共享首选项,并在某些方法或 Retrofit 类中使用它。
【解决方案2】:

我在这里分享我自己的 Preference Class,它太简单了,所以你可以放在任何项目中。

把这个类放到你的 util 文件夹或任何地方。

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, "");
    }

}

当用户登录设置值时,在 Login.java 中设置偏好值:

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

然后您将通过这样的调用获得任何类中的登录状态值:

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

【讨论】:

  • 我为什么要重新发明轮子?
  • 我没听懂你什么意思?我有什么可以帮助你的吗? @Wijdan
  • 我在说如果我可以调试并让它工作,为什么我不应该使用共享偏好并创建一个全新的类似功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多