我正在使用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步我该怎么做才不再发生?我的回调网址不正确吗?我应该使用意图过滤器将该网址的调用重定向到我的应用程序吗?我尝试了许多事情但没有成功......
答案 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)。