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 が正しくありませんか? インテント フィルターを使用して、その URL の呼び出しをアプリにリダイレクトする必要がありますか? 色々試したけど上手くいかない…

4

2 に答える 2

1

Sunshirondのアイデアは私にとって完璧に機能し、http://www.android10.org/index.php/articleslibraries/291-twitter-integration-in-your-android-applicationソースコードにいくつかの変更を加えました。ログインしてツイッターする主なアクティビティは次のようになります。

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

}

問題が発生した場合は、メールでお知らせください...プロジェクトをGoogleコードにアップロードできますか。

注-これが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;
        }
    });

ただし、注意してください。shouldOverrideUrlLoading は、url フォームが「string1://string2」のような場合にのみ呼び出されます。ここで、string1 と 2 は特殊文字を含まない文字列です (例: myappname://callback)。

于 2012-05-24T13:55:23.453 に答える