2015-10-15 283 views
9

我目前正在開發一個webView的Android應用程序。在某些urls我需要使用shouldOverrideUrlLoading方法,這是非常簡單的:如何處理intent://在webView URL上?

if(url.startsWith("something")){ 
//do something 
return true; 
} 

我的問題:

一些URLS,在谷歌搜索的例子,有以下URL方案:

intent://en.m.wikipedia.org/wiki/Test_cricket#Intent;scheme=http;package=org.wikipedia;S.browser_fallback_url=https%3A%2F%2Fwww.google.pt%2Fsearchurl%2Fr.html%23app%3Dorg.wikipedia%26pingbase%3Dhttps%3A%2F%2Fwww.google.pt%2F%26url%3Dhttps%3A%2F%2Fen.m.wikipedia.org%2Fwiki%2FTest_cricket;S.android.intent.extra.REFERRER_NAME=https%3A%2F%2Fwww.google.pt;launchFlags=0x8080000;end 

我試過使用:

Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); 
startActivity(browserIntent); 

但我得到了一個錯誤:

10-15 15:18:15.546: W/System.err(29086): android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=intent://en.m.wikipedia.org/wiki/Test_cricket } 

我應該如何處理這種URL方案?


UPDATE:

Intent myIntent = new Intent().parseUri(url, Intent.URI_INTENT_SCHEME); 
startActivity(myIntent); 

繼@CommonsWare意見,我已經使用上IntentparseUri()創建從URL一個Intent object,然後嘗試startActivity(),類似嘗試但我仍然得到:

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=http://en.m.wikipedia.org/wiki/Test_cricket flg=0x8080000 pkg=org.wikipedia (has extras) } 

我可能得到的指示錯誤或者我根本無法構建@CommonsWare指定的intent。有關如何構建Intent的任何提示?

+1

要麼趕上'ActivityNotFoundException'或使用'PackageManager'和'resolveActivity()'調用之前檢測到這種情況'startActivity()'。在這種情況下,'Uri'是一個應用程序(維基百科),如果該應用程序沒有安裝,「Intent」將無法解析。您將需要向用戶提供某種錯誤消息,指出這一事實。 – CommonsWare

+0

@CommonsWare如果點擊一個帶有'intent:// ...'的鏈接,一些瀏覽器(Firefox,Chrome,Opera)成功打開該應用程序,是否有辦法將uri轉發到默認瀏覽器並讓它處理它呢? –

+0

默認瀏覽器沒有處理它 - 維基百科應用程序應該這樣做。儘管現在我想到了,但「ACTION_VIEW」可能不是正確的答案。使用'Intent'上的'parseUri()'從URL創建一個'Intent'對象,然後在'Intent'上嘗試'startActivity()'。 – CommonsWare

回答

14

這個intent url的結構在這裏描述https://developer.chrome.com/multidevice/android/intents

所以我們可以處理它內部的WebView這樣的:

@Override 
public boolean shouldOverrideUrlLoading(WebView view, String url) { 
    if (url.startsWith("intent://")) { 
     try { 
      Context context = view.getContext(); 
      Intent intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME); 

      if (intent != null) { 
       view.stopLoading(); 

       PackageManager packageManager = context.getPackageManager(); 
       ResolveInfo info = packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); 
       if (info != null) { 
        context.startActivity(intent); 
       } else { 
        String fallbackUrl = intent.getStringExtra("browser_fallback_url"); 
        view.loadUrl(fallbackUrl); 

        // or call external broswer 
//     Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(fallbackUrl)); 
//     context.startActivity(browserIntent); 
       } 

       return true; 
      } 
     } catch (URISyntaxException e) { 
      if (GeneralData.DEBUG) { 
       Log.e(TAG, "Can't resolve intent://", e); 
      } 
     } 
    } 

    return false; 
} 
+0

完美!最後一個解決方案 –

3

我設法解決這個問題的方式不是優雅但它的工作原理。

首先,我們檢查,如果網址startsWithintent://和含有scheme=http,如果是這樣,我們之後意圖獲得的價值://everything until#並將它傳遞給Intent.ACTION_VIEW,如果沒有,我們return false(忽略點擊) 。
我測試過與谷歌移動搜索的幾個結果,如,嘰嘰喳喳Facebook的谷歌地圖維基百科,它完美地工作這一解決方案。

@Override 
public boolean shouldOverrideUrlLoading(WebView view, String url) { 
    if(url.startsWith("intent://") && url.contains("scheme=http")){ 
     url = Uri.decode(url); 
     String bkpUrl = null; 
     Pattern regexBkp = Pattern.compile("intent://(.*?)#"); 
     Matcher regexMatcherBkp = regexBkp.matcher(url); 
     if (regexMatcherBkp.find()) { 
      bkpUrl = regexMatcherBkp.group(1); 
      Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://"+bkpUrl)); 
      startActivity(myIntent); 
      return true; 
     }else{ 
      return false; 
     } 
    } 
return false; 
} 

如果您在一個更好的解決辦法,我想聽聽它。
謝謝大家的支持,特別是CommonsWare