0

我正在开发一个使用 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 步不再发生?我的回调网址不正确吗?我应该使用意图过滤器将该 URL 的调用重定向到我的应用程序吗?我尝试了很多事情都没有成功...

4

2 回答 2

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);
        }
    }
}   

}

如果你有一些问题让它工作,给我发邮件......我可以将项目上传到谷歌代码。

注意 - 这是 web 视图的 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" />

于 2012-09-05T09:22:02.813 回答
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)。

于 2012-05-24T13:55:23.453 回答