2015-10-15 11 views
9

Attualmente sto sviluppando un'applicazione Android con un webView. Su alcuni urls ho bisogno di utilizzare il metodo shouldOverrideUrlLoading, che è piuttosto semplice:Come gestire l'intento: // su un URL di WebView?

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

Il mio problema:

Alcuni URLS, sulla ricerca google per esempio, hanno la seguente URL schema:

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 

ho provato con:

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

Ma ho ottenuto un errore:

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 } 

Come devo gestire questo tipo di URL schema?


UPDATE:

In seguito alle osservazioni @CommonsWare, Ho provato con parseUri() su Intent per creare un Intent object dal URL e quindi provare startActivity(), qualcosa di simile a:

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

Ma continuo a ricevere:

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) } 

Forse ho ricevuto le istruzioni errate o semplicemente non sono in grado di costruire il intent come @CommonsWare specificato. Qualche consiglio su come costruire il Intent?

+1

O prendere il 'ActivityNotFoundException' o usare' 'PackageManager' e resolveActivity()' per rilevare questa situazione prima di chiamare 'startActivity()'. In questo caso, il 'Uri' è per un'app (Wikipedia), e se quell'app non è installata,' Intent' non si risolve. Sarà necessario presentare una sorta di messaggio di errore all'utente che indica questo fatto. – CommonsWare

+0

@CommonsWare Se si tocca un collegamento con 'intent: // ...' su di esso alcuni browser (Firefox, Chrome, Opera) aprono con successo l'applicazione, c'è un modo per inoltrare l'uri al browser predefinito e lasciarlo gestire vero? –

+0

Il browser predefinito non lo gestisce: l'app di Wikipedia dovrebbe. Anche se, ora che ci penso, ACTION_VIEW probabilmente non è la risposta giusta. Usa 'parseUri()' su 'Intento' per creare un oggetto' Intento' dall'URL, quindi prova 'startActivity()' su quell'intento'. – CommonsWare

risposta

14

Struttura di questo intento url è descritto qui https://developer.chrome.com/multidevice/android/intents.

Così siamo in grado di gestire in WebView interna come questo:

@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

perfetto! Finalmente una soluzione –

3

Il modo in cui sono riuscito a risolvere questo non è elegante ma funziona.

Per prima cosa verificare se l'URL startsWith con intent:// e contiene scheme=http, in caso affermativo, otteniamo il valore subito dopo intento: //everything until# e passarlo a Intent.ACTION_VIEW, se non, return false (ignoriamo clicca) .
Ho provato questa soluzione con diversi risultati di ricerca di Google Mobile, come ad esempio, Twitter, facebook, mappe google e wikipedia e ha funzionato senza problemi.

@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; 
} 

Se hai una soluzione migliore, mi piacerebbe sentirla.
Grazie a tutti per il supporto, specialmente CommonsWare.