Android Java WebView应用:实现唤起Facebook等第三方应用
解决WebView内点击分享链接无法唤起第三方应用的问题
你的核心问题出在webClient的shouldOverrideUrlLoading方法——它把所有URL都强制在WebView内部加载了,但Facebook、WhatsApp这类分享链接大多使用自定义Scheme(如fb://、whatsapp://)或者intent://协议,这些需要交给系统去唤起对应第三方应用,而不是在WebView里打开。
修改后的完整代码
import android.annotation.SuppressLint; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.webkit.WebChromeClient; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.ProgressBar; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { WebView webView; ProgressBar progressBar; @SuppressLint("SetJavaScriptEnabled") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = findViewById(R.id.webview); progressBar = findViewById(R.id.progress); webView.setWebChromeClient(new MyWebChromeClient()); webView.setWebViewClient(new webClient()); webView.getSettings().setLoadWithOverviewMode(true); webView.getSettings().setSupportZoom(true); webView.getSettings().setJavaScriptEnabled(true); webView.loadUrl("https://www.hindnc.nl/"); } public class MyWebChromeClient extends WebChromeClient { public void onProgressChanged(WebView view, int newProgress) { progressBar.setVisibility(View.VISIBLE); progressBar.setProgress(newProgress); // 加载完成后隐藏进度条 if (newProgress == 100) { progressBar.setVisibility(View.GONE); } } } public class webClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { // 判断是否是第三方应用的Scheme链接(如fb://、whatsapp://等) if (url.startsWith("fb://") || url.startsWith("whatsapp://") || url.startsWith("twitter://") || url.startsWith("linkedin://")) { try { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); startActivity(intent); return true; } catch (Exception e) { // 如果应用未安装,跳转到对应应用的应用商店页面 Uri marketUri = Uri.parse("market://details?id=" + getPackageNameFromScheme(url)); startActivity(new Intent(Intent.ACTION_VIEW, marketUri)); return true; } } // 处理intent://协议的链接(部分网页分享会使用这种格式) else if (url.startsWith("intent://")) { try { Intent intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); return true; } // 没有对应应用时,处理网页提供的 fallback 链接 String fallbackUrl = intent.getStringExtra("browser_fallback_url"); if (fallbackUrl != null) { view.loadUrl(fallbackUrl); return true; } } catch (Exception e) { // 解析失败则在WebView内加载该链接 view.loadUrl(url); return true; } } // 常规网页链接继续在WebView内加载 view.loadUrl(url); return true; } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); progressBar.setVisibility(View.GONE); } } // 根据Scheme获取对应应用的包名,用于跳转应用商店 private String getPackageNameFromScheme(String url) { if (url.startsWith("fb://")) { return "com.facebook.katana"; } else if (url.startsWith("whatsapp://")) { return "com.whatsapp"; } else if (url.startsWith("twitter://")) { return "com.twitter.android"; } else if (url.startsWith("linkedin://")) { return "com.linkedin.android"; } return ""; } @Override public void onBackPressed() { if (webView.canGoBack()) { webView.goBack(); } else { super.onBackPressed(); } } }
关键修改点说明
- Scheme链接拦截处理:在
shouldOverrideUrlLoading里先检测URL是否是目标应用的自定义Scheme,匹配成功则创建Intent唤起对应应用;若应用未安装,自动跳转到应用商店。 - Intent协议解析:针对网页中常用的
intent://格式分享链接,解析Intent并唤起应用,无对应应用时自动处理网页提供的备用链接。 - 进度条逻辑补全:在
MyWebChromeClient里补充了进度100%时隐藏进度条的逻辑,避免加载完成后进度条残留。
Android 11+ 额外配置
如果你的应用目标SDK版本为30及以上,需要在AndroidManifest.xml中添加<queries>标签,声明要唤起的应用包名,否则系统会限制应用的查询权限:
<manifest ...> <queries> <package android:name="com.facebook.katana" /> <package android:name="com.whatsapp" /> <package android:name="com.twitter.android" /> <package android:name="com.linkedin.android" /> </queries> ... </manifest>
内容的提问来源于stack exchange,提问作者Ashis Autar
相关产品推荐
相关产品推荐

