Search code examples
androidandroid-webview

Android- Webview onPageFinished Called Twice


I have an activity that does OAuth authentication by intercepting the redirect url once it show up in the webview. However, the onPageFinished function is somehow called twice for some reason, which really messes up my application. Here's the code:

public class WebViewActivity extends Activity {
private WebView gWebView;
final String REDIRECT_URI = "https://localhost:5000/receive_code";
final String CLIENT_ID = "can't post it here";
final String CLIENT_SECRET = "can't post it here";
final String SCOPE = "basic names genomes analyses";
Hashtable<String, String> riskPairs;

public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.webview);

    gWebView = (WebView) findViewById(R.id.webView1);

    gWebView.loadUrl("https://api.23andme.com/authorize/?redirect_uri="
            + REDIRECT_URI + "&response_type=code&client_id=" + CLIENT_ID
            + "&scope=" + SCOPE);

    Log.d("WEBVIEW", "got to webpage");

    gWebView.setWebViewClient(new WebViewClient() {

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if (url.startsWith(REDIRECT_URI)) {
                Log.d("WEBVIEW", "onpagefinished is called");
                System.out.println("got to override");
                if (url.indexOf("code=") != -1) {
                    //if the query contains code
                    String queryString = null;
                    try {
                        queryString = new URL(url).getQuery();
                    } catch (MalformedURLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println(queryString);
                    String[] params = queryString.split("&");
                    String code = null;
                    for (String param : params) {
                        if (param.startsWith("code=")) {
                            code = param.substring(param.indexOf('=') + 1);
                        }
                    }
                    gWebView.setVisibility(View.GONE);
                    new PostRequest().execute(code);
                    // don't go to redirectUri
                }
            }
        }
    });


}
class PostRequest extends AsyncTask<String,Void,String>{ code getting client data...}

P.S. Please don't mark this as a duplicate...I've read a similar question on StackOverflow and calling ShouldOverrideUrlLoading does not work for me(which is why I used onPageFinished() in the first place).


Solution

  • If the url is OK after onPageStarted method starts onPageFinished, but if the url is redirected after onPageStarted starts shouldOverrideUrlLoading and then onPageFinished. You should just check if the loading URL is redirected or not

    private boolean isRedirected;
    
    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {   
    
      if (!isRedirected) {      
        //Do something you want when starts loading
      }
    
      isRedirected = false;
    }
    

    If the URL is redirected the callback starts this function

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
    
      view.loadUrl(url);
      isRedirected = true;
      return true;
    }
    

    Before doing something in onPageFinished check if the callback has entered into shouldOverrideUrlLoading method

    @Override
    public void onPageFinished(WebView view, String url) {
    
      if (!isRedirected) {
        //Do something you want when finished loading 
      }
    }