我检查了所有的论坛,但没有找到解决方案 | "Open external links of my webview in browser and not in app" 无效

I check all the forum but not find a solution | "Open external links of my webview in browser and not in app" does not work

感谢阅读我的问题 :) 我在检查了所有论坛后无法解决此问题。我正在处理我的第一个网络视图。没什么特别的。这是一个带有进度条的网络视图。我在 "shouldOverrideUrlLoading" 方法中的代码不起作用。我希望我网站的所有外部链接都在浏览器中打开,而不是在应用程序中打开,但它不起作用。任何人都可以检查我的代码吗?

public class MainActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {

private WebView wv;
private ProgressBar progressBar;
private FrameLayout frameLayout;
SwipeRefreshLayout swipe;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    frameLayout = (FrameLayout) findViewById(R.id.frameLayout);
    progressBar = (ProgressBar) findViewById(R.id.progressBar);
    progressBar.setMax(100);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    swipe = (SwipeRefreshLayout) findViewById(R.id.swipe);
    swipe.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            String webUrl = wv.getUrl();
            wv.loadUrl(webUrl);
        }
    });
    LoadWeb();

}

public void LoadWeb(){

    wv = (WebView)findViewById(R.id.webView);
    WebSettings settings = wv.getSettings();
    settings.setJavaScriptEnabled(true);

    wv.loadUrl("example.com");
    swipe.setRefreshing(true);
    wv.setWebViewClient(new HelpClient());
    wv.setWebViewClient(new MyAppWebViewClient());

    wv.setWebChromeClient(new WebChromeClient(){
        public void onProgressChanged(WebView view, int progress){
            frameLayout.setVisibility(View.VISIBLE);
            progressBar.setProgress(progress);

            if (progress == 100){
                frameLayout.setVisibility(View.GONE);

            }
            super.onProgressChanged(view, progress);
        }
    });
    progressBar.setProgress(0);

    wv.setWebViewClient(new WebViewClient(){

        public void onPageFinished(WebView view, String url){
            swipe.setRefreshing(false);
        }
    });

}

private class HelpClient extends WebViewClient {

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url){
        view.loadUrl(url);
        frameLayout.setVisibility(View.VISIBLE);
        return true;

    }
}

private class MyAppWebViewClient extends WebViewClient {

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

        if(Uri.parse(url).getHost().endsWith("example.com")) {
            return false;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        view.getContext().startActivity(intent);
        return true;
    }

}

@Override
public void onBackPressed() {
    if(wv.canGoBack()) {
        wv.goBack();
    } else {
        super.onBackPressed();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement


    return super.onOptionsItemSelected(item);
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();

    if (id == R.id.nav_home) {
        wv.loadUrl("example.com");

    } else if (id == R.id.nav_facebook) {

        try {
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("fb://page/idfbpage"));
            startActivity(intent);
        } catch (Exception e) {
            Intent intent =  new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.facebook.com/idfbpage"));
            startActivity(intent);
        }

    } else if (id == R.id.nav_instagram) {

        Uri uri = Uri.parse("http://instagram.com/_u/idinstapage");
        Intent likeIng = new Intent(Intent.ACTION_VIEW, uri);
        likeIng.setPackage("com.instagram.android");

        try {
            startActivity(likeIng);
        } catch (Exception e) {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://instagram.com/idinstapage")));
        }

    } else if (id == R.id.nav_star) {

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse("market://details?id=idpackage"));
        startActivity(intent);

    } else if (id == R.id.nav_informazioni) {
        wv.loadUrl("example.com/info-app");

    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
 }

}

我希望删除这一行

wv.setWebViewClient(new MyAppWebViewClient());

将为您解决问题。

您正在使用两个 WebViewClient 实例,删除一个,

private class MyAppWebViewClient extends WebViewClient {

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
    Log.d("TAG",url);
    if(Uri.parse(url).getHost().equals("example.com")) {
        return false;
    }
    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
    view.getContext().startActivity(intent);//add the brakpoint here
    Log.d("TAG","Starting activity");
    return true;
}

}

就用这个

在您的方法 LoadWeb() 中有一个错误,因为您的 WebView 应该只有一个 WebViewClient 并且只有一个 WebChromeClient。所以会发生什么,如果你多次使用方法 wv.setWebViewClient(new YourWebViewClient()); 会发生的是之前设置的所有其他方法都将被忽略,因为你只能设置一次。

对于你的情况:
您设置 WebViewClient 三 (3) 次:

wv.setWebViewClient(new HelpClient());   //First time
wv.setWebViewClient(new MyAppWebViewClient());  //Second time

上次你用同样的方法设置它时,你设置了另一个类似的方法:

wv.setWebViewClient(new WebViewClient(){

    public void onPageFinished(WebView view, String url){
        swipe.setRefreshing(false);
    }
});

所以发生的事情是前两个方法被忽略了,唯一有效的方法是最后一个(第三个)。 这就是为什么我要你把第二种方法放到setWebClient((new MyAppWebViewClient());以便忽略前面的方法!

解决方案
现在你知道我们只需要为你的 webView 设置一个 WebViewClient 我们只需要设置 ONE Class 将被用来做通过覆盖所有必需的方法来完成所有其他三个 WebViewClient 的工作。在您的 activity 中创建此 class 但取代您的任何方法( 就像您在 HelpClient() Class 中所做的那样)。这是我们的 Class 请务必阅读其中的评论!

private class NewWebViewClient extends WebViewClient {
       //Now we have only one class to do a job of all the other three!

    @Override
    public void onPageFinished(WebView view, String url) {
        /*I here do whatever you want to do when the page has finished loading! Do it here inside this method and it will work may be control the framelayout visibility For example lets setRefreshing false to our swipe()*/
        swipe.setRefreshing(false);
        //.....add more methods you want here when the page loading is finished
    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        /*In this method we are going to tell the android system what kind of link we want and what kind of link we dont want for that what we want we will handle for the extra the browser should do so!*/
        if (Uri.parse(url).getHost().endsWith("example.com")) {
            //if the code gets here this is your link then right? Lets do whatever we want with our link and logic for example lets set framelayout visible or doing anything this link's host is example.com!
            frameLayout.setVisibility(View.VISIBLE);
            return false;
        } else {
            //Ooops This link is not yours lets just open browsers right 
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
            view.getContext().startActivity(intent);
            return true;
        }

    }

}

在你的class漂亮之后让我们只设置我们的WebViewClient ONCE.

wv.setWebViewClient(new NewWebViewClient());

你可以忽略 WebChromeClient 因为你只设置一次就好了。如果您发现任何困难,请在下方评论!