【Android】WebViewで、mailtoとかtelを開けずに詰まった話
AndroidのWebViewで、WebView内のリンクをタップした時に、mailto:やtel:だと、schemeに対応していないというメッセージが表示されて、電話アプリやメーラーが起動できないで詰まってました。
参考
-
公式ドキュメント
- こちらを読めば、理解が深まるかと思います。
原因と対策
-
原因
- WebViewに対して、setWebViewClientをだけをしていたので、mailto:などのURLをWebViewでロードされるようになっていた。
- そもそもWebViewは、httpリソースを表示するようなので、mailto:やtel:などのURLスキームに対応していないみたい…(ドキュメントで明記されていたわけではないです。)
-
対策
- WebViewClientに、shouldOverrideUrlLoadingメソッドを実装してあげて、処理を記述する。
- 記事を調べると、メールアプリの起動や電話アプリの起動を、スキーマで判別して、暗黙的Intentで起動するとしているものが多かったけど、ただアプリを起動して値を渡すだけなら、ブラウザを起動させてurlを渡すだけで動きました。
- Intent.ACTION_VIEWのドキュメントに、mailto:、tel:に対応してアプリ起動すると記載がありました。
SampleWebViewActivity.kt
public class SampleWebViewActivity extends FragmentActivity {
private WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample_web_view);
// 仮にwebViewというidがあるとして
mWebView = (WebView) findViewById(R.id.webview);
mWebView.setWebViewClient(new WebViewClient(){
// 大事なのはここです!
// ここで、WebView内でのurlのロード(リンクがタップされた時)を制御している
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
// ブラウザを起動しているだけ
// ブラウザの方で、mailto:やtel:を制御してくれる。
val intent = new Intent(Intent.ACTION_VIEW, request.url);
startActivity(intent);
// trueを返さないと、webViewで、このurlをロードしてしまいます。
return true;
}
});
}
最後に
今回の対策では、とりあえずmailto: とかtel:も対応できるようになっただけです。
そのため、電話アプリを起動する前にダイアログで知らせるとかになると、スキームで判定とかが必要かなと思います。
またdeep linkとかになると、また面倒な対応がさらに必要になります。