Проблема в обратном вызове в Twitter в Android - PullRequest
4 голосов
/ 25 июля 2011

Я реализовал Twitter в своем приложении, у меня проблема с обратным вызовом.

API Twitter был недавно обновлен, поэтому я не могу отправить URL обратного вызова.

Кроме того, теперь можно изменить страницу настроек. Нет опции для выбора веб-приложения или настольного приложения.

Если я отправлю Обратный звонок в этой строке:

authUrl = provider.retrieveRequestToken(consumer,CALLBACK_URL);

Всегда возвращается

oauth.signpost.exception.OAuthNotAuthorizedException: Authorization failed (server replied with a 401). This can happen if the consumer key was not correct or the signatures did not match.

но если я отправлю как Нуль , это Перенаправление на страницу входа в Twitter , но после успешной авторизации оно не вернется в мое приложение.

После того, как отображается ПИН-код, я хочу перенаправить обратно в мое приложение.

Примечание: Twitter обновил свой API, поэтому старые Коды, доступные в Посте, не работают.

Я перепробовал все следующие ссылки

Ссылка 1 , Ссылка 2 , Ссылка 3 , Ссылка4 , Ссылка5 , Ссылка 6

Мой код выглядит следующим образом:

public class Main extends Activity {
OAuthConsumer consumer;
OAuthProvider provider;
Twitter twitter;
private static  String CALLBACK_URL = "twitterapptest://connect";


@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);

    consumer = new DefaultOAuthConsumer(
            "XXXXXXXXXXX",
            "XXXXXXXXXXXXX");

    provider = new DefaultOAuthProvider(
            "https://api.twitter.com/oauth/request_token",
            "https://api.twitter.com/oauth/access_token",
            "https://api.twitter.com/oauth/authorize");

    String authUrl = null;
    try {
        authUrl = provider.retrieveRequestToken(consumer,null);
         this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));
    } catch (OAuthMessageSignerException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (OAuthNotAuthorizedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (OAuthExpectationFailedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (OAuthCommunicationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String pin = null;
    try {
        pin = br.readLine();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        provider.retrieveAccessToken(consumer, "4947222");
    } catch (OAuthMessageSignerException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (OAuthNotAuthorizedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (OAuthExpectationFailedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (OAuthCommunicationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    URL url = null;
    try {
        url = new URL("http://twitter.com/statuses/mentions.xml");
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    HttpURLConnection request = null;
    try {
        request = (HttpURLConnection) url.openConnection();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        consumer.sign(request);
    } catch (OAuthMessageSignerException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (OAuthExpectationFailedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (OAuthCommunicationException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    try {
        request.connect();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        System.out.println("Response: " + request.getResponseCode() + " "
                + request.getResponseMessage());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}


/**
 * As soon as the user successfully authorized the app, we are notified
 * here. Now we need to get the verifier from the callback URL, retrieve
 * token and token_secret and feed them to twitter4j (as well as
 * consumer key and secret).
 */

     @Override
    protected void onNewIntent(Intent intent) {

        super.onNewIntent(intent);

        Uri uri = intent.getData();
        if (uri != null && uri.toString().startsWith(CALLBACK_URL)) {

            String verifier = uri
                    .getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER);

            try {
                // this will populate token and token_secret in consumer

                provider.retrieveAccessToken(consumer,
                        verifier);

                // TODO: you might want to store token and token_secret in you
                // app settings!!!!!!!!

                AccessToken a = new AccessToken(consumer.getToken(),
                        consumer.getTokenSecret());

                // initialize Twitter4J

                twitter = new TwitterFactory().getInstance();
                twitter.setOAuthConsumer("XXXXXXX", "XXXXXXXXXX");
                twitter.setOAuthAccessToken(a);

                // create a tweet

                Date d = new Date(System.currentTimeMillis());
                String tweet = "#OAuth working! " + d.toLocaleString();

                // send the tweet

                twitter.updateStatus(tweet);

            } catch (Exception e) {

                Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
            }
        }
    }
}

Мой манифест:

<?xml version="1.0" encoding="utf-8"?>

    <activity android:name=".OAuthForTwitter"  android:label="@string/app_name"
            android:configChanges="orientation|keyboardHidden"  android:launchMode="singleInstance">
     <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="twitterapptest" android:host="connect" />
    </intent-filter>

</activity>

</application>
<uses-sdk android:minSdkVersion="4" />
<uses-permission android:name="android.permission.INTERNET" />

Ответы [ 3 ]

8 голосов
/ 26 июля 2011

Проблема в том, что Callback URl.Мы должны указать один фиктивный URL обратного вызова в поле Имя URL обратного вызова на странице настроек приложения.

Если мы сделаем это и отправим URL обратного вызова в нашем коде, после успешного входа будет возможность Переадресация на ваше приложение

. Для дальнейшей справки отметьте эту ссылку для Twitter

3 голосов
/ 10 августа 2011

Нашли ли вы, откуда возникла проблема? У меня было то же исключение, и, наконец, я нашел, откуда это взялось. Это верно, что страница настроек Twitter изменилась, и вы больше не можете выбирать веб-приложение или настольное приложение. Но вот советы: в настройках приложения Twitter просто заполните URL обратного вызова фиктивным, например http://www.dummy.com. Это неявно установит, что ваше приложение имеет веб-браузер, а затем, когда вы отправите свой собственный обратный вызов, оно заменит фиктивный. Я потратил много раз, чтобы найти это, поэтому я надеюсь, что этот ответ кому-нибудь поможет.

0 голосов
/ 04 декабря 2014

Добавление ниже Callback URL в приложение решит проблему.Он перенаправит пользователя на Application, который начнет его аутентификацию Twitter account_

пользователя в Manifest _

<activity android:name="<YOUR ACTIVITY NAME>"
        android:launchMode="singleTask" android:theme="@android:style/Theme.Translucent.NoTitleBar"
        android:screenOrientation="portrait">
        <intent-filter>
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="x-oauthflow-twitter" android:host="callback" />
        </intent-filter>

In Your TwitterManager где у вас есть все ваши TwitterFactory и необходимые вещи_

final public static String  CALLBACK_SCHEME = "x-oauthflow-twitter";    
final public static String  CALLBACK_URL = CALLBACK_SCHEME + "://callback";
public static final String TWITTER_IEXTRA_OAUTH_VERIFIER = "oauth_verifier";

Наконец вы можете получить все, что вам нужно - например, getHost, getScheme, getEncodedQuery, getQuery, getEncodedSchemeSpecificPart и более в соответствии с вашими потребностями, используя intent, которые возвращаются при обратном вызове_

@Override
protected void onNewIntent(final Intent intent) {
    super.onNewIntent(intent);

    new AsyncTask<Void,Void,Void>(){
        @Override
        protected Void doInBackground(Void... arg0) {
            Uri uri = intent.getData();
            if (uri != null && uri.toString().startsWith(TwitterManager.TWITTER_CALLBACK_URL)) {
                String verifier = uri.getQueryParameter(TwitterManager.TWITTER_IEXTRA_OAUTH_VERIFIER);
                Log.e("---ActivityMain-onNewIntent---", "verifier:"+verifier+", uri- getQuery:"+uri.getQuery());
                Log.i(ApplicationPockets.TAG, "verifier : "+verifier);
                if(verifier != null){
                    try {
                     /*
                      *---Get the AccessToken and do what you like ... :)
                      */
                        AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, verifier);
                       SharedPreferences.Editor e = context.getSharedPreferences(SF_TWITTER, Context.MODE_PRIVATE).edit();
                       e.putString(TWITTER_PREF_KEY_TOKEN, accessToken.getToken());
                       e.putString(TWITTER_PREF_KEY_SECRET, accessToken.getTokenSecret());
                      e.commit();
                     //Extra you would like to do...
                    } catch (TwitterException e) {
                        e.printStackTrace();
                    }
                }else{
                    //Logout Twitter.
                }
            }
            return null;
        }
    }.execute();
}

Ваш запросToken_

  try {
         RequestToken requestToken = twitter.getOAuthRequestToken(TWITTER_CALLBACK_URL);
        //Toast.makeText(activity, "Please authorize this app!", Toast.LENGTH_LONG).show();
        activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(requestToken.getAuthenticationURL())));
      } catch (TwitterException e) {

          e.printStackTrace();
    }

Надеюсь, это поможет всем

...