-2

可能重复:
发布更新的 Twitter API 速率限制

我通过集成“httpclient-4.0.1.jar”、“signpost-commonhttp4-1.2.1.1.jar”、“signpost-core-1.2.1.1.jar”、“twitter4j-core-2.1”在我的应用程序中集成了 twitter。 11.jar”文件..

代码是:

   public class AndroidTwitterSample extends Activity {

private SharedPreferences prefs;
private final Handler mTwitterHandler = new Handler();
private TextView loginStatus;
String message="Hii";
final Runnable mUpdateTwitterNotification = new Runnable() {
    public void run() {
        Toast.makeText(getBaseContext(), "Tweet sent !", Toast.LENGTH_LONG).show();
    }
};

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    this.prefs = PreferenceManager.getDefaultSharedPreferences(this);

    loginStatus = (TextView)findViewById(R.id.login_status);
    Button tweet = (Button) findViewById(R.id.btn_tweet);
    Button clearCredentials = (Button) findViewById(R.id.btn_clear_credentials);

    tweet.setOnClickListener(new View.OnClickListener() {
        /**
         * Send a tweet. If the user hasn't authenticated to Tweeter yet, he'll be redirected via a browser
         * to the twitter login page. Once the user authenticated, he'll authorize the Android application to send
         * tweets on the users behalf.
         */
        public void onClick(View v) {
            if (TwitterUtils.isAuthenticated(prefs)) {
                sendTweet();
            } else {
                Intent i = new Intent(getApplicationContext(), PrepareRequestTokenActivity.class);
                i.putExtra("tweet_msg",getTweetMsg());
                startActivity(i);
            }
        }
    });

    clearCredentials.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            clearCredentials();
            updateLoginStatus();
        }
    });
}

@Override
protected void onResume() {
    super.onResume();
    updateLoginStatus();
}

public void updateLoginStatus() {
    loginStatus.setText("Logged into Twitter : " + TwitterUtils.isAuthenticated(prefs));
}


private String getTweetMsg() {
    return message;
}   

public void sendTweet() {
    Thread t = new Thread() {
        public void run() {

            try {
                TwitterUtils.sendTweet(prefs,getTweetMsg());
                mTwitterHandler.post(mUpdateTwitterNotification);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

    };
    t.start();
}

private void clearCredentials() {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    final Editor edit = prefs.edit();
    edit.remove(OAuth.OAUTH_TOKEN);
    edit.remove(OAuth.OAUTH_TOKEN_SECRET);
    edit.commit();
}
}

常量类:

  public class Constants {

public static final String CONSUMER_KEY = "<key>";
public static final String CONSUMER_SECRET= "<secret>";

public static final String REQUEST_URL = "https://api.twitter.com/oauth/request_token";
public static final String ACCESS_URL = "https://api.twitter.com/oauth/access_token";
public static final String AUTHORIZE_URL = "https://api.twitter.com/oauth/authorize";

public static final String  OAUTH_CALLBACK_SCHEME   = "x-oauthflow-twitter";
public static final String  OAUTH_CALLBACK_HOST     = "callback";
public static final String  OAUTH_CALLBACK_URL      = OAUTH_CALLBACK_SCHEME + "://" + OAUTH_CALLBACK_HOST;


}

OAuthRequestToken 类:

public class OAuthRequestTokenTask extends AsyncTask<Void, Void, Void> {

final String TAG = getClass().getName();
private Context context;
private OAuthProvider provider;
private OAuthConsumer consumer;

/**
 * 
 * We pass the OAuth consumer and provider.
 * 
 * @param   context
 *          Required to be able to start the intent to launch the browser.
 * @param   provider
 *          The OAuthProvider object
 * @param   consumer
 *          The OAuthConsumer object
 */
public OAuthRequestTokenTask(Context context,OAuthConsumer consumer,OAuthProvider provider) {
    this.context = context;
    this.consumer = consumer;
    this.provider = provider;
}

/**
 * 
 * Retrieve the OAuth Request Token and present a browser to the user to authorize the token.
 * 
 */
@Override
protected Void doInBackground(Void... params) {

    try {
        Log.i(TAG, "Retrieving request token from Google servers");
        final String url = provider.retrieveRequestToken(consumer, Constants.OAUTH_CALLBACK_URL);
        Log.i(TAG, "Popping a browser with the authorize URL : " + url);
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_FROM_BACKGROUND);
        context.startActivity(intent);
    } catch (Exception e) {
        Log.e(TAG, "Error during OAUth retrieve request token", e);
    }

    return null;
}

}

PrepareRequestTokenActivity:

 public class PrepareRequestTokenActivity extends Activity {

final String TAG = getClass().getName();

private OAuthConsumer consumer; 
private OAuthProvider provider;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    try {
        this.consumer = new CommonsHttpOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
        this.provider = new CommonsHttpOAuthProvider(Constants.REQUEST_URL,Constants.ACCESS_URL,Constants.AUTHORIZE_URL);
    } catch (Exception e) {
        Log.e(TAG, "Error creating consumer / provider",e);
    }

    Log.i(TAG, "Starting task to retrieve request token.");
    new OAuthRequestTokenTask(this,consumer,provider).execute();
}

/**
 * Called when the OAuthRequestTokenTask finishes (user has authorized the request token).
 * The callback URL will be intercepted here.
 */
@Override
public void onNewIntent(Intent intent) {
    super.onNewIntent(intent); 
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    final Uri uri = intent.getData();
    if (uri != null && uri.getScheme().equals(Constants.OAUTH_CALLBACK_SCHEME)) {
        Log.i(TAG, "Callback received : " + uri);
        Log.i(TAG, "Retrieving Access Token");
        new RetrieveAccessTokenTask(this,consumer,provider,prefs).execute(uri);
        finish();   
    }
}

public class RetrieveAccessTokenTask extends AsyncTask<Uri, Void, Void> {

    private Context context;
    private OAuthProvider provider;
    private OAuthConsumer consumer;
    private SharedPreferences prefs;

    public RetrieveAccessTokenTask(Context context, OAuthConsumer consumer,OAuthProvider provider, SharedPreferences prefs) {
        this.context = context;
        this.consumer = consumer;
        this.provider = provider;
        this.prefs=prefs;
    }


    /**
     * Retrieve the oauth_verifier, and store the oauth and oauth_token_secret 
     * for future API calls.
     */
    @Override
    protected Void doInBackground(Uri...params) {
        final Uri uri = params[0];
        final String oauth_verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);

        try {
            provider.retrieveAccessToken(consumer, oauth_verifier);

            final Editor edit = prefs.edit();
            edit.putString(OAuth.OAUTH_TOKEN, consumer.getToken());
            edit.putString(OAuth.OAUTH_TOKEN_SECRET, consumer.getTokenSecret());
            edit.commit();

            String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
            String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");

            consumer.setTokenWithSecret(token, secret);
            context.startActivity(new Intent(context,AndroidTwitterSample.class));

            executeAfterAccessTokenRetrieval();

            Log.i(TAG, "OAuth - Access Token Retrieved");

        } catch (Exception e) {
            Log.e(TAG, "OAuth - Access Token Retrieval Error", e);
        }

        return null;
    }


    private void executeAfterAccessTokenRetrieval() {
        String msg = getIntent().getExtras().getString("tweet_msg");
        try {
            TwitterUtils.sendTweet(prefs, msg);
        } catch (Exception e) {
            Log.e(TAG, "OAuth - Error sending to Twitter", e);
        }
    }
}   

}

推特工具:

public class TwitterUtils {

public static boolean isAuthenticated(SharedPreferences prefs) {

    String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
    String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");

    AccessToken a = new AccessToken(token,secret);
    Twitter twitter = new TwitterFactory().getInstance();
    twitter.setOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
    twitter.setOAuthAccessToken(a);

    try {
        twitter.getAccountSettings();
        return true;
    } catch (TwitterException e) {
        return false;
    }
}

public static void sendTweet(SharedPreferences prefs,String msg) throws Exception {
    String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
    String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");

    AccessToken a = new AccessToken(token,secret);
    Twitter twitter = new TwitterFactory().getInstance();
    twitter.setOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
    twitter.setOAuthAccessToken(a);
    twitter.updateStatus(msg);
}   
}

问题是在 2 条推文之后,它给了我一个例外:

    W/System.err(5104): 403:The request is understood, but it has been refused. An accompanying error message will explain why. This code is used when requests are being denied due to update limits (http://support.twitter.com/forums/10711/entries/15364).
    W/System.err(5104): error - Status is a duplicate.
    W/System.err(5104): request - /1/statuses/update.json
    W/System.err(5104): Relevant discussions can be on the Internet at:
     W/System.err(5104):    http://www.google.co.jp/search?q=15bb6564 or
     W/System.err(5104):    http://www.google.co.jp/search?q=010f3e5b
     W/System.err(5104): TwitterException{exceptionCode=[15bb6564-010f3e5b], statusCode=403, retryAfter=0, rateLimitStatus=null, version=2.1.11}
      W/System.err(5104):   at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:199)
      W/System.err(5104):   at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:75)
      W/System.err(5104):   at twitter4j.internal.http.HttpClientWrapper.post(HttpClientWrapper.java:112)
      W/System.err(5104):   at twitter4j.Twitter.updateStatus(Twitter.java:593)
    W/System.err(5104):     at com.ecs.android.sample.twitter.TwitterUtils.sendTweet(TwitterUtils.java:38)
      W/System.err(5104):   at com.ecs.android.sample.twitter.AndroidTwitterSample$4.run(AndroidTwitterSample.java:84)
4

1 回答 1

10

从您的错误消息中:

error - Status is a duplicate.

这意味着您不能两次发布相同的消息。如果您已经发布了该消息HI,那么您cannot将再次发布该消息(至少在那天 - 不确定)。你会得到Status is a duplicate错误

于 2012-10-09T13:16:16.403 回答