1

您好,我正在尝试从 SharedPreferences 存储和获取值。

我的问题是,当我尝试获取我的值时,我得到了空值。

这是我的代码:

public class TwitterSession {
    private SharedPreferences sharedPref;
    private Editor editor;

    private static final String TWEET_AUTH_KEY = "tweet_auth_key";
    private static final String TWEET_AUTH_SECRET_KEY = "tweet_auth_secret_key";
    private static final String TWEET_USER_NAME = "";
    private static final String SHARED = "Twitter_Preferences";

    public TwitterSession(Context context) {

        sharedPref = context.getSharedPreferences(SHARED, Context.MODE_PRIVATE);

        editor = sharedPref.edit();
    }

    public void storeAccessToken(AccessToken accessToken, String username) {

        String token = accessToken.getToken();
        String tokenSecret = accessToken.getTokenSecret();

        Log.i("accessToken.getToken()", token);
        Log.i("accessToken.getTokenSecret()", tokenSecret);

        editor.putString(TWEET_AUTH_KEY, token);
        editor.putString(TWEET_AUTH_SECRET_KEY, tokenSecret);
        editor.putString(TWEET_USER_NAME, username);

        if(editor.commit())
            Log.i("check","ok");
        else
            Log.i("token","not ok");

    }


    public AccessToken getAccessToken() {

        String token = sharedPref.getString(TWEET_AUTH_KEY, null);
        String tokenSecret = sharedPref.getString(TWEET_AUTH_SECRET_KEY, null);
        String userName = sharedPref.getString(TWEET_USER_NAME, null);

        if(token != null)
            Log.i("token",token);
        else
            Log.i("token","null");

        if(tokenSecret != null)
            Log.i("tokenSecret", tokenSecret);
        else
            Log.i("tokenSecret", "null");

        if(userName != null)
            Log.i("userName", userName);
        else
            Log.i("userName", "null");

        if (token != null && tokenSecret != null)
            return new AccessToken(token, tokenSecret);
        else
            return null;
    }
}

首先我使用 storeAccessToken() 方法。我的日志得到了很好的结果。

Log.i("accessToken.getToken()", token);
Log.i("accessToken.getTokenSecret()", tokenSecret);

返回良好的值,因为if(editor.commit())我在我的日志中得到“好的”。

当我尝试调用 getAccessToken() 时,我得到空字符串

Log.i("token","null");
Log.i("userName", "null");
Log.i("tokenSecret", "null");

被触发

在我的活动中,我这样使用它:

TwitterSession twitter = new TwitterSession(this);
twitter.getAccessToken();

感谢您的帮助

更新1:

public AccessToken getAccessToken() {

    sharedPref = contextTwitter.getSharedPreferences(SHARED, Context.MODE_PRIVATE);

    String token = sharedPref.getString(TWEET_AUTH_KEY, null);
    String tokenSecret = sharedPref.getString(TWEET_AUTH_SECRET_KEY, null);
    String userName = sharedPref.getString(TWEET_USER_NAME, null);

    if(token != null)
        Log.i("token",token);
    else
        Log.i("token","null");

    if(tokenSecret != null)
        Log.i("tokenSecret", tokenSecret);
    else
        Log.i("tokenSecret", "null");

    if(userName != null)
        Log.i("userName", userName);
    else
        Log.i("userName", "null");

    if (token != null && tokenSecret != null)
        return new AccessToken(token, tokenSecret);
    else
        return null;
}

这个试过了,不行。

我试图通过我的活动访问我的 SharedPreferences 并且也失败了

4

3 回答 3

1

我也注意到了这种行为。从我执行的调查来看,只有在退出活动时,我的结果才会保存到专用于SharedPreferences. 从 I/O 的角度来看,这与 API 命名法是一致的;

更普遍...

  • 提交 => 我想永久保存这些暂定的更改集。
  • 提交并刷新 † => 我想保留这些更改并将其反映在存储中。

...重要的是,简单的“提交”定义从未说过“这绝对会立即保存到真实的地方”...

特别是在安卓...

  • SharedPreferences...commit=> "...将其首选项同步写入持久存储"
  • SharedPreferences...apply=> "...立即将其更改提交到内存中的 SharedPreferences 但开始异步提交到磁盘,并且您不会收到任何失败的通知"

    结论

    我得出的结论是,我无法控制何时将项目持久保存到 SharedPreferences 存储中。相反,如果我正在访问我保存在同一个类/活动(无论如何)中的变量,我应该修改该变量的范围,以便可以通过使用它的类访问它。在您的实例中,将令牌信息分配TwitterSession到类级别的私有变量中。希望有帮助。

    † 不确定 SharedPreference 存储下的机制是否有这个概念,但这个社区的答案仍然提供了一个有趣的阅读。

  • 于 2013-10-17T09:24:18.880 回答
    0

    尝试如下:

    public AccessToken getAccessToken() {
         SharedPreferences pref = getSharedPreferences(SHARED, MODE_PRIVATE);
        String token = pref .getString(TWEET_AUTH_KEY, null);
        String tokenSecret = pref .getString(TWEET_AUTH_SECRET_KEY, null);
        String userName = pref .getString(TWEET_USER_NAME, null);
      }
    
    于 2013-10-17T08:39:25.060 回答
    -1

    请看一下这段代码,希望对你有帮助

    import twitter4j.Twitter;
    import twitter4j.TwitterException;
    import twitter4j.TwitterFactory;
    import twitter4j.User;
    import twitter4j.auth.AccessToken;
    import twitter4j.auth.RequestToken;
    import twitter4j.conf.Configuration;
    import twitter4j.conf.ConfigurationBuilder;
    import android.app.Activity;
    import android.app.ProgressDialog;
    import android.content.Intent;
    import android.content.SharedPreferences;
    import android.content.SharedPreferences.Editor;
    import android.content.pm.ActivityInfo;
    import android.net.Uri;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.text.Html;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class MainActivity extends Activity {
        // Constants
        /**
         * Register your here app https://dev.twitter.com/apps/new and get your
         * consumer key and secret
         * */
        static String TWITTER_CONSUMER_KEY = "LsCQaPOwd8k7WkyRFRZF4Q";
        static String TWITTER_CONSUMER_SECRET = "KJbJu5IQrlwxW7Cwnax3mMzAc4j3n6Wd2dG125srgk";
    
        // Preference Constants
        static String PREFERENCE_NAME = "twitter_oauth";
        static final String PREF_KEY_OAUTH_TOKEN = "oauth_token";
        static final String PREF_KEY_OAUTH_SECRET = "oauth_token_secret";
        static final String PREF_KEY_TWITTER_LOGIN = "isTwitterLogedIn";
    
        static final String TWITTER_CALLBACK_URL = "oauth://t4jsample";
    
        // Twitter oauth urls
        static final String URL_TWITTER_AUTH = "auth_url";
        static final String URL_TWITTER_OAUTH_VERIFIER = "oauth_verifier";
        static final String URL_TWITTER_OAUTH_TOKEN = "oauth_token";
    
        // Login button
        Button btnLoginTwitter;
        // Update status button
        Button btnUpdateStatus;
        // Logout button
        Button btnLogoutTwitter;
        // EditText for update
        EditText txtUpdate;
        // lbl update
        TextView lblUpdate;
        TextView lblUserName;
    
        // Progress dialog
        ProgressDialog pDialog;
    
        // Twitter
        private static Twitter twitter;
        private static RequestToken requestToken;
    
        // Shared Preferences
        private static SharedPreferences mSharedPreferences;
    
        // Internet Connection detector
        private ConnectionDetector cd;
    
        // Alert Dialog Manager
        AlertDialogManager alert = new AlertDialogManager();
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    
            cd = new ConnectionDetector(getApplicationContext());
    
            // Check if Internet present
            if (!cd.isConnectingToInternet()) {
                // Internet Connection is not present
                alert.showAlertDialog(MainActivity.this, "Internet Connection Error",
                        "Please connect to working Internet connection", false);
                // stop executing code by return
                return;
            }
    
            // Check if twitter keys are set
            if(TWITTER_CONSUMER_KEY.trim().length() == 0 || TWITTER_CONSUMER_SECRET.trim().length() == 0){
                // Internet Connection is not present
                alert.showAlertDialog(MainActivity.this, "Twitter oAuth tokens", "Please set your twitter oauth tokens first!", false);
                // stop executing code by return
                return;
            }
    
            // All UI elements
            btnLoginTwitter = (Button) findViewById(R.id.btnLoginTwitter);
            btnUpdateStatus = (Button) findViewById(R.id.btnUpdateStatus);
            btnLogoutTwitter = (Button) findViewById(R.id.btnLogoutTwitter);
            txtUpdate = (EditText) findViewById(R.id.txtUpdateStatus);
            lblUpdate = (TextView) findViewById(R.id.lblUpdate);
            lblUserName = (TextView) findViewById(R.id.lblUserName);
    
            // Shared Preferences
            mSharedPreferences = getApplicationContext().getSharedPreferences(
                    "MyPref", 0);
    
            /**
             * Twitter login button click event will call loginToTwitter() function
             * */
            btnLoginTwitter.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View arg0) {
                    // Call login twitter function
                    loginToTwitter();
                }
            });
    
            /**
             * Button click event to Update Status, will call updateTwitterStatus()
             * function
             * */
            btnUpdateStatus.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // Call update status function
                    // Get the status from EditText
                    String status = txtUpdate.getText().toString();
    
                    // Check for blank text
                    if (status.trim().length() > 0) {
                        // update status
                        new updateTwitterStatus().execute(status);
                    } else {
                        // EditText is empty
                        Toast.makeText(getApplicationContext(),
                                "Please enter status message", Toast.LENGTH_SHORT)
                                .show();
                    }
                }
            });
    
            /**
             * Button click event for logout from twitter
             * */
            btnLogoutTwitter.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View arg0) {
                    // Call logout twitter function
                    logoutFromTwitter();
                }
            });
    
            /** This if conditions is tested once is
             * redirected from twitter page. Parse the uri to get oAuth
             * Verifier
             * */
            if (!isTwitterLoggedInAlready()) {
                Uri uri = getIntent().getData();
                if (uri != null && uri.toString().startsWith(TWITTER_CALLBACK_URL)) {
                    // oAuth verifier
                    String verifier = uri
                            .getQueryParameter(URL_TWITTER_OAUTH_VERIFIER);
    
                    try {
                        // Get the access token
                        AccessToken accessToken = twitter.getOAuthAccessToken(
                                requestToken, verifier);
    
                        // Shared Preferences
                        Editor e = mSharedPreferences.edit();
    
                        // After getting access token, access token secret
                        // store them in application preferences
                        e.putString(PREF_KEY_OAUTH_TOKEN, accessToken.getToken());
                        e.putString(PREF_KEY_OAUTH_SECRET,
                                accessToken.getTokenSecret());
                        // Store login status - true
                        e.putBoolean(PREF_KEY_TWITTER_LOGIN, true);
                        e.commit(); // save changes
    
                        Log.e("Twitter OAuth Token", "> " + accessToken.getToken());
    
                        // Hide login button
                        btnLoginTwitter.setVisibility(View.GONE);
    
                        // Show Update Twitter
                        lblUpdate.setVisibility(View.VISIBLE);
                        txtUpdate.setVisibility(View.VISIBLE);
                        btnUpdateStatus.setVisibility(View.VISIBLE);
                        btnLogoutTwitter.setVisibility(View.VISIBLE);
    
                        // Getting user details from twitter
                        // For now i am getting his name only
                        long userID = accessToken.getUserId();
                        User user = twitter.showUser(userID);
                        String username = user.getName();
    
                        // Displaying in xml ui
                        lblUserName.setText(Html.fromHtml("<b>Welcome " + username + "</b>"));
                    } catch (Exception e) {
                        // Check log for login errors
                        Log.e("Twitter Login Error", "> " + e.getMessage());
                    }
                }
            }
    
        }
    
        /**
         * Function to login twitter
         * */
        private void loginToTwitter() {
            // Check if already logged in
            if (!isTwitterLoggedInAlready()) {
                ConfigurationBuilder builder = new ConfigurationBuilder();
                builder.setOAuthConsumerKey(TWITTER_CONSUMER_KEY);
                builder.setOAuthConsumerSecret(TWITTER_CONSUMER_SECRET);
                Configuration configuration = builder.build();
    
                TwitterFactory factory = new TwitterFactory(configuration);
                twitter = factory.getInstance();
    
                try {
                    requestToken = twitter
                            .getOAuthRequestToken(TWITTER_CALLBACK_URL);
                    this.startActivity(new Intent(Intent.ACTION_VIEW, Uri
                            .parse(requestToken.getAuthenticationURL())));
                } catch (TwitterException e) {
                    e.printStackTrace();
                }
            } else {
                // user already logged into twitter
                Toast.makeText(getApplicationContext(),
                        "Already Logged into twitter", Toast.LENGTH_LONG).show();
            }
        }
    
        /**
         * Function to update status
         * */
        class updateTwitterStatus extends AsyncTask<String, String, String> {
    
            /**
             * Before starting background thread Show Progress Dialog
             * */
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                pDialog = new ProgressDialog(MainActivity.this);
                pDialog.setMessage("Updating to twitter...");
                pDialog.setIndeterminate(false);
                pDialog.setCancelable(false);
                pDialog.show();
            }
    
            /**
             * getting Places JSON
             * */
            protected String doInBackground(String... args) {
                Log.d("Tweet Text", "> " + args[0]);
                String status = args[0];
                try {
                    ConfigurationBuilder builder = new ConfigurationBuilder();
                    builder.setOAuthConsumerKey(TWITTER_CONSUMER_KEY);
                    builder.setOAuthConsumerSecret(TWITTER_CONSUMER_SECRET);
    
                    // Access Token 
                    String access_token = mSharedPreferences.getString(PREF_KEY_OAUTH_TOKEN, "");
                    // Access Token Secret
                    String access_token_secret = mSharedPreferences.getString(PREF_KEY_OAUTH_SECRET, "");
    
                    AccessToken accessToken = new AccessToken(access_token, access_token_secret);
                    Twitter twitter = new TwitterFactory(builder.build()).getInstance(accessToken);
    
                    // Update status
                    twitter4j.Status response = twitter.updateStatus(status);
    
                    Log.d("Status", "> " + response.getText());
                } catch (TwitterException e) {
                    // Error in updating status
                    Log.d("Twitter Update Error", e.getMessage());
                }
                return null;
            }
    
            /**
             * After completing background task Dismiss the progress dialog and show
             * the data in UI Always use runOnUiThread(new Runnable()) to update UI
             * from background thread, otherwise you will get error
             * **/
            protected void onPostExecute(String file_url) {
                // dismiss the dialog after getting all products
                pDialog.dismiss();
                // updating UI from Background Thread
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(),
                                "Status tweeted successfully", Toast.LENGTH_SHORT)
                                .show();
                        // Clearing EditText field
                        txtUpdate.setText("");
                    }
                });
            }
    
        }
    
        /**
         * Function to logout from twitter
         * It will just clear the application shared preferences
         * */
        private void logoutFromTwitter() {
            // Clear the shared preferences
            Editor e = mSharedPreferences.edit();
            e.remove(PREF_KEY_OAUTH_TOKEN);
            e.remove(PREF_KEY_OAUTH_SECRET);
            e.remove(PREF_KEY_TWITTER_LOGIN);
            e.commit();
    
            // After this take the appropriate action
            // I am showing the hiding/showing buttons again
            // You might not needed this code
            btnLogoutTwitter.setVisibility(View.GONE);
            btnUpdateStatus.setVisibility(View.GONE);
            txtUpdate.setVisibility(View.GONE);
            lblUpdate.setVisibility(View.GONE);
            lblUserName.setText("");
            lblUserName.setVisibility(View.GONE);
    
            btnLoginTwitter.setVisibility(View.VISIBLE);
        }
    
        /**
         * Check user already logged in your application using twitter Login flag is
         * fetched from Shared Preferences
         * */
        private boolean isTwitterLoggedInAlready() {
            // return twitter login status from Shared Preferences
            return mSharedPreferences.getBoolean(PREF_KEY_TWITTER_LOGIN, false);
        }
    
        protected void onResume() {
            super.onResume();
        }
    
    }`enter code here`
    
    于 2013-10-17T08:39:55.240 回答