2012-10-01 13 views
11

OAuthを認証に使用するアプリケーションを開発していますが、OAuthコールバックの処理には少し問題があります。Webviewで認証が行われた場合、インテントフィルタでOAuth URLコールバックを処理する方法は?

認証

私のアプリはログイン画面としてのWebViewを持って、私は私のWebViewで認証フォームをロードするためのURLを与えられています。

https://myoauthhost.com/oauth/auth?response_type=code&client_id=XXXXXXX&redirect_uri=YYYYYYYY&scope=ZZZZZZZZZZ 

と認証活動(AuthActivity.java)で

、私は次ています:manifest.xmlに中

String authURL = https://myoauthhost.com/oauth/auth?response_type=code&client_id=XXXXXXX&redirect_uri=YYYYYYYY&scope=ZZZZZZZZZZ 
    myWebView.loadUrl(authURL); 

、私はOAuthのコールバックのために、次のしているのは、URLがあるとしましょう取り扱い:

<activity 
      android:name=".AuthActivity" 
      android:label="@string/app_name" 
      android:screenOrientation="portrait" > 

      <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:host="authprovider" 
        android:scheme="auth" /> 
      </intent-filter> 
</activity> 

PROBLEM

このURLはwebview(loadURL()メソッドで使用)でREAL OAUTH WEB FROM(webviewにロードする必要があります)を含む別のURLにリダイレクトします。問題は、このリダイレクトは、インテントの選択をAndroidで自動的に起動することです.URLはWebブラウザで処理する必要があるため、電話で利用可能なWebブラウザの1つを選択してURLを開きます。

これは私が欲しいものではありませんので、私はリダイレクトがWebViewの内部で処理されますが、Webブラウザ(または何でも)を起動しないように、次のコードを含める必要があります:

myWebView.setWebViewClient(new WebViewClient()); 

ので、これとコードでは、リダイレクトは「webview内で」処理され、ログイン画面が表示されます。

認証が完了すると、認証が行われるとコールバックが受信されますが、コールバックを処理するはずのアクティビティ(AuthActivityがマニフェストでコールバックを受信するように設定されています)起動されません。代わりに、webviewにurlコールバック(私たちの場合、マニフェストで設定されているauthprovider:// auth/XXX?xxx = yyy)が見つかりませんというメッセージが表示されます。

理由は、次のコードということがあります先に紹介し

myWebView.setWebViewClient(new WebViewClient()); 

は、WebViewのすべてを処理するのAndroidに伝えます。コールバックURLはWeb URLではないので、これを処理するのが難しく、処理できるインテントを起動することさえできません。

QUESTION

どのように私はこの問題を解決することができますか? 私は、アクティビティにコールバックを処理させることはできますが、webviewにはロードさせません。ある場合

任意のヘルプは、

答えて

0

さて、まずあなたは、サービスプロバイダによって提供されるURLを呼び出す必要があるかもしれません事前に

おかげでいただければ幸いです任意のリダイレクトは、HTTPステータスコード300番台を取得する存在。次に、リダイレクトが存在する場合は、実際のURLを呼び出すことができます。通常のHTTPレスポンスでは、HTTP 2xxのステータスコードを取得します。

+0

私はOAuthを 'AccountManager'と統合しようとしていましたが、' android:launchMode = "singleInstance" 'は私のために働いていました。 – d370urn3ur

23

マニフェストでまず第一に、ユーザーコード内で、その後のWebView

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="oauth-testing" /> 
</intent-filter> 

ようとインテントフィルタを追加ログインボタンのクリック

mReqToken = mTwitter.getOAuthRequestToken(CALLBACK_URL); 
WebView webView = new WebView(this); 
webView.requestFocus(View.FOCUS_DOWN); 
webView.setOnTouchListener(new View.OnTouchListener() { 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
      case MotionEvent.ACTION_UP: 
      if (!v.hasFocus()) { 
       v.requestFocus(); 
      } 
      break; 
     } 
     return false; 
    } 
}); 
webView.loadUrl(mReqToken.getAuthenticationURL()); 
mainLayout.removeAllViews(); 
mainLayout.addView(webView); 

ここでコールバックURLはです0 private static final String CALLBACK_URL = "oauth-testing:///";
動的Webviewを作成してユーザーに表示しています。ログイン後、webviewは閉じられ、コードはonNewIntent()になります。ログイン後に機能を実装する必要があります。

@Override 
protected void onNewIntent(Intent intent) { 
    super.onNewIntent(intent); 
    dealWithTwitterResponse(intent); 
} 
private void dealWithTwitterResponse(Intent intent) { 
    Uri uri = intent.getData(); 
    System.out.println("URI=" + uri); 
    if (uri != null && uri.toString().startsWith(CALLBACK_URL)) { 
     String oauthVerifier = uri.getQueryParameter("oauth_verifier"); 
     authoriseNewUser(oauthVerifier); 
    } 
} 

私は適切でない可能性がありますそれらのいくつかのコードスニペットの多くを、追加している知っているが、私はそれがいつか誰かを助けることを願っています。

+0

なぜこの回答が受け入れられていないのかわかりません! – Umair

0

WebViewのオブジェクトを持っているので、それをオーバーロードしてから、あなたのアクティビティに移動するURLをこの2通りの方法で処理できます。

private class MyWebView extends WebViewClient{ 
      @TargetApi(Build.VERSION_CODES.N) 
      @Override 
      public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest request) 
      { 
       Uri uri = request.getUrl(); 
       return shouldOverrideUrlLoading(uri.toString()); 
      } 

      private boolean shouldOverrideUrlLoading(final String url) 
      { 
       Log.i(TAG, "shouldOverrideUrlLoading() URL : " + url); 
        //your code to handle the url for navigation will go here 
       try{ 
         if(url.contains("yourcondition")){ 
         //1st way to handle 
         Intent intent = new Intent(Intent.ACTION_VIEW); 
         intent.setData(Uri.parse(url)); 
         YourActivity.this.startActivity(intent); 
         }else{ 
          //2nd way 
         Intent intent = new Intent(YourActivity.this,NewActivity.class); 
         //you can set the data 
         intent.setData(Uri.parse(url)); 
         YourActivity.this.startActivity(intent); 
         } 
        }catch(ActivityNotFoundException e) {  
         Log.e(LOGTAG,"Could not load url"+url); 
        }      
       return false; 
       // return true; // this True means that application wants to leave the WebView and try to go to browser and handle the url itself, otherwise return false. 
      } 
    @Override 
    public boolean shouldOverrideUrlLoading(WebView view, String url) 
    { 


     try { 
       if(url.contains("yourcondition")){ 
       //1st way to handle 
       Intent intent = new Intent(Intent.ACTION_VIEW); 
       intent.setData(Uri.parse(url)); 
       YourActivity.this.startActivity(intent); 
      }else{ 
      //2nd way 
      Intent intent = new Intent(YourActivity.this,NewActivity.class); 
      //you can set the data 
      intent.setData(Uri.parse(url)); 
      YourActivity.this.startActivity(intent); 
      } 

     } catch(ActivityNotFoundException e) { 

      Log.e(LOGTAG,"Could not load url"+url); 
     } 

     return false;  
    } 
} 

デフォルトであるmWebView.setWebViewClient(new WebViewClient());を設定したが によって単にデフォルトのカスタムWebViewClientだけWebViewのではなく、ブラウザのWebViewの内のいずれかのロードのURL自体、すなわちを処理することができます追加することができます。

いますが、mWebView.setWebViewClient(new MyWebView());ようclass MyWebView上方を通過することにより、過負荷ならば、あなたはuはあなたがWebViewのオブジェクトのコントロールを持っていない場合は

myWebView.setWebViewClient(new WebViewClient(){ 

       @TargetApi(Build.VERSION_CODES.N) 
       @Override 
       public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest request) 
       { 
        Uri uri = request.getUrl(); 
        return shouldOverrideUrlLoading(uri.toString()); 
       } 

       private boolean shouldOverrideUrlLoading(final String url) 
       { 
        Log.i(TAG, "shouldOverrideUrlLoading() URL : " + url); 
         //your code to handle the url for navigation will go here 
        try{ 
          if(url.contains("yourcondition")){ 
          //1st way to handle 
          Intent intent = new Intent(Intent.ACTION_VIEW); 
          intent.setData(Uri.parse(url)); 
          YourActivity.this.startActivity(intent); 
          }else{ 
           //2nd way 
          Intent intent = new Intent(YourActivity.this,NewActivity.class); 
          //you can set the data 
          intent.setData(Uri.parse(url)); 
          YourActivity.this.startActivity(intent); 
          } 
         }catch(ActivityNotFoundException e) {  
          Log.e(LOGTAG,"Could not load url"+url); 
         }      
        return false; 
        // return true; // this True means that application wants to leave the WebView and try to go to browser and handle the url itself, otherwise return false. 
       } 

    @Override 
    public boolean shouldOverrideUrlLoading(WebView view, String url) 
    { 

     try { 
      if(url.contains("yourcondition")){ 
      //1st way to handle 
      Intent intent = new Intent(Intent.ACTION_VIEW); 
      intent.setData(Uri.parse(url)); 
      YourActivity.this.startActivity(intent); 
      }else{ 
      //2nd way 
       Intent intent = new Intent(YourActivity.this,NewActivity.class); 
      //you can set the data 
      intent.setData(Uri.parse(url)); 
      YourActivity.this.startActivity(intent); 
      }  
     } catch(ActivityNotFoundException e) { 

      Log.e(LOGTAG,"Could not load url"+url); 
     } 

     return false;  

    }}); 

をachiveできるURLと同じことの荷重を制御することができ、これはではありません私がこれを解決すると解決策が更新されます。

関連する問題