2012-10-09 37 views
-2

可能重複:
Twitter API rate limits for posting updatesTwitter集成:請求被理解,但它已被拒絕。當請求被拒絕這段代碼是用來由於更新上限

我已經集成「在我的應用程序集成的Twitter的HttpClient-4.0.1.jar 」, 「路標-commonhttp4-1.2.1.1.jar」, 「路標 - 核心1.2.1.1.jar」, 「twitter4j核-2.1.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); 
     } 
    } 
} 

} 

TwitterUtils:

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) 
+0

我已經檢查過,但我沒有從這個問題得到任何提示.. – Kanika

+0

基於API密鑰 – nandeesh

+0

你也許超出你的速率限制,但我有啾啾只是2次,之後它給我例外 – Kanika

回答

10

從你的錯誤消息:

error - Status is a duplicate. 

這意味着你不能鳴叫相同的消息兩次。 如果您發推消息HI,請即時cannot(至少在當天發貨) - 不確定)。您將得到Status is a duplicate錯誤

+0

但我的要求是相同的..我想一次又一次發佈相同的消息。是否有任何其他方式來實現這? – Kanika

+0

@Kanika其實不可能,twitter不允許這樣做。 –

+0

嘿謝謝Mohit。你的答案真的幫了我很多..現在爲了同樣的要求,我已經添加了當前的日期和時間..所以時間區分了整個消息。 – Kanika