【问题标题】:SharedPreferences empty after restarting service / device重新启动服务/设备后 SharedPreferences 为空
【发布时间】:2017-01-18 18:37:32
【问题描述】:

当我使用 Google Firebase 进行推送通知时,我想将 Instance Token 保存到 SharedPreferences。不幸的是,每当令牌被刷新并想要检查来自SharedPreferences 的前一个令牌时,它们都是空的......

是因为我在这里使用Service吗?

public class MyFirebaseIIDService : FirebaseInstanceIdService
{
    public override void OnTokenRefresh()
    {
        var sharedPreferences = PreferenceManager.GetDefaultSharedPreferences(this);
        var sharedPreferencesEditor = sharedPreferences.Edit();

        // Get Firebase Instance Token
        var refreshedToken = FirebaseInstanceId.Instance.Token;

        // Check if a Firebase Instance Token has been registered before and unregister it
        var oldToken = sharedPreferences.GetString("FirebaseInstanceToken", null);

        if (oldToken != null) // is ALWAYS null :(
        {
            // Unregister old token...
        }

        // Save the Firebase Instance Token locally
        sharedPreferencesEditor.PutString("FirebaseInstanceToken", refreshedToken);
        sharedPreferencesEditor.Apply();

        // At this point, the SharedPreferences have to token saved.
        // Next time, the app reaches this point, it is gone... 
    }
}

抱歉语法混乱,我使用 Xamarin,所以这是 C#,但它应该没有任何区别。

【问题讨论】:

    标签: firebase service xamarin.android sharedpreferences firebase-cloud-messaging


    【解决方案1】:

    我不知道它在 xamarin 中是如何工作的,但在本机 android 中,来自服务上下文的 getSharedPreferences 可能是错误的。打开共享首选项时,您应该只使用 applicationContext 或 MODE_MULTI_PROCESS。

    你可以看到类似的问题here

    当您打开某些文件时,Xamarin 和 C# 也有这种模式,所以我认为首选项完全相同。试试这样的,而不是使用 GetDefaultSharedPreferences:

    ISharedPreferences prefs = Application.Context.GetSharedPreferences ("PREF_NAME", FileCreationMode.MultiProcess);
    

    【讨论】:

    • Xamarin 是 C# 到 Java 的 1:1 映射,因此 Java-Android 中存在的所有内容也确实存在于 Xamarin 中。不幸的是,您提出的解决方案没有奏效。应用重新启动后仍然为空...
    【解决方案2】:

    您是否卸载了您的应用程序以刷新您的令牌?如果是,我认为您无法获取旧令牌,因为在您卸载应用程序时会清除 SharedPreferences

    我已尝试使用 java 代码来保存令牌:

    public void onTokenRefresh() {
            // Get updated InstanceID token.
    
            String refreshedToken = FirebaseInstanceId.getInstance().getToken();
            Log.d("Mike", "Refreshed token: " + refreshedToken);
    
            SharedPreferences mSharedPreferences = getSharedPreferences("hello",0);
            String oldToken = mSharedPreferences.getString("Token",null);
    
            if(oldToken == null)
            {
                Log.d("Mike", "oldToken: " + null);
            }
    
            SharedPreferences.Editor mEditor = mSharedPreferences.edit();
            mEditor.putString("Token", refreshedToken);
            mEditor.commit();
    
            // TODO: Implement this method to send any registration to your app's servers.
            //sendRegistrationToServer(refreshedToken);
    
        }
    

    第一次安装你的应用你会得到令牌并将它保存在SharedPreferences,下次你打开你的应用并在文本视图中显示旧令牌时你会发现你的令牌已经保存了,然后做不要卸载您的应用:

        TextView tv1 = (TextView)findViewById(R.id.tv1);
        SharedPreferences mSharedPreferences = getSharedPreferences("hello",0);
        String oldToken = mSharedPreferences.getString("Token",null);
        tv1.setText(oldToken);
    

    它有效。但是当您卸载您的应用程序时,textview 显示为 null。

    【讨论】:

    • 是的,我确实卸载并重新安装了应用程序以刷新令牌,但 Visual Studio 有一个 Preserve application data/cahce on device between deploys 选项,我已激活该选项。但是:我解决了这个问题。我正在测试的物理设备是root,所以这个选项不起作用。尝试使用无根电话,效果很好。
    【解决方案3】:

    我解决了这个问题,结果证明我的代码工作正常,但在我的测试设备上表现得很奇怪。

    重新构建应用程序后,SharedPreferences 已被清除,尽管我在 Visual Studio 中检查了在部署之间在设备上保留应用程序数据/缓存选项。那是因为我的物理测试设备是root并且不接受这个选项。

    在无根设备上尝试时,一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-21
      • 1970-01-01
      • 2013-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-21
      相关资源
      最近更新 更多