Twitter api我回调没有回复我的应用程序

时间:2012-05-18 13:33:43

标签: android api twitter android-emulator callback

我正在使用OAuth(通过twitter api me)开发一个使用twitter验证的应用程序。这是我的代码:

public final static String CALLBACK_URL = "twittappmarc://twitter";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    WebView webView = new WebView(this);
    setContentView(webView);

    WebViewOAuthDialogWrapper pageWrapper =
        new WebViewOAuthDialogWrapper(webView,CONSUMER_KEY,CONSUMER_SECRET,CALLBACK_URL,this);
    pageWrapper.setEnableCustomResultPages(false);
    pageWrapper.login();    
}

public void onAuthorize(Token accessToken) {
    Intent i = new Intent();
    i.setClass(this,FriendListActivity.class);
    i.putExtra("TOKEN_STRING", accessToken.toString());
    startActivity(i);
}
...

虽然我的代码似乎正在运行(我可以登录并获取令牌),但我不知道如何处理回调URL。我认为我的应用程序会自动使用“onAuthorize”方法回调,但这就是:

1:我在webview中成功连接到Twitter

2:webview尝试并且无法加载twittappmarc:// twitter?%token%

3:使用正确的令牌调用onAuthorize方法,启动我的FriendListActivity

第2步我该怎么做才不再发生?我的回调网址不正确吗?我应该使用意图过滤器将该网址的调用重定向到我的应用程序吗?我尝试了许多事情但没有成功......

2 个答案:

答案 0 :(得分:1)

Sunshirond的想法,对我来说很完美,我在http://www.android10.org/index.php/articleslibraries/291-twitter-integration-in-your-android-application源代码中进行了一些更改。登录和twitt的主要活动将是这样的:

public class PrepareRequestTokenActivity extends Activity {

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

private OAuthConsumer consumer; 
private OAuthProvider provider;
private  WebView webView;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.my_webview);

    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.");

    webView = (WebView) findViewById(R.id.mywebview);
    webView.setWebViewClient(new MyWebViewClient(getApplicationContext(), PreferenceManager.getDefaultSharedPreferences(this)));
    webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);

    WebSettings webSettings = webView.getSettings();

    webSettings.setSavePassword(false);                
    webSettings.setSupportZoom(false);
    webSettings.setSaveFormData(false);
    webSettings.setJavaScriptEnabled(true);
    webSettings .setCacheMode(WebSettings.LOAD_NO_CACHE);
    try {
        final String url = provider.retrieveRequestToken(consumer, Constants.OAUTH_CALLBACK_URL);
        webView.loadUrl(url);
    }
    catch (Exception e) {
        webView.clearHistory();
        webView.clearFormData();
        webView.clearCache(true);
        finish();
    }        

}

private class MyWebViewClient extends WebViewClient {

    private Context context;
    private SharedPreferences prefs;

    public MyWebViewClient(Context context, SharedPreferences prefs) {
        this.context = context;
        this.prefs = prefs;
    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.contains(Constants.OAUTH_CALLBACK_SCHEME)) {
            Uri uri = Uri.parse(url);
            new RetrieveAccessTokenTask(context,consumer,provider,prefs).execute(uri);
            finish();
            return true;
        }
        return false;
    }
}


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) {
        Log.d("hi there", "im gonna make the twitt");
        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);
        }
    }
}   

}

如果您遇到一些问题,请发邮件给我...我可以将projecto上传到Google代码。

注意 - 这是webview的XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<WebView
    android:id="@+id/mywebview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />

答案 1 :(得分:0)

我发现执行此操作的最佳方法是覆盖WebviewClient的shouldOverrideUrlLoading。

WebView webView = (WebView) findViewById(R.id.webview);
webView.setWebViewClient(new WebViewClient() {
    @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (url.contains(Const.CALLBACK_URL)) {
                Uri uri = Uri.parse(url);
                mIntent.setData(uri);
                setResult(RESULT_OK, mIntent);
                finish();
                return true;
            }
            return false;
        }
    });

请注意,如果url表单类似于“string1:// string2”,则只会调用shouldOverrideUrlLoading,其中string1和2是没有特殊字符的字符串(例如:myappname:// callback)。