2014-11-28 17 views
9

ho potuto implementare con successo deeplinking di applicazione utilizzando seguente filtro nella intent-filtro nel mio manifesto:Escludi alcuni indirizzi da deeplinking

<data android:host="myhost.com" 
    android:pathPrefix="/v" 
    android:scheme="http" /> 

Eg. I miei URL sono:

http://myhost.com/v/login1.php?id=123&name=abc&type=a 
http://myhost.com/v/login1.php?id=123&name=abc&type=b 

voglio escludere

http://myhost.com/v/login1.php?id=123&name=abc&type=c 

Ora voglio escludere alcuni indirizzi che hanno lo stesso prefisso. È possibile o Devo specificare esplicitamente tutti gli URL con android:path? In tal caso, come gestire i valori dei parametri di ricerca?

risposta

3

Purtroppo non è possibile escludere alcun URL, poiché Android non fornisce tale opzione.

La procedura consigliata è quella di fornire come pathPrefix il più preciso possibile.

Specificare solo l'host senza pathPrefix è OK, a condizione che tutte le azioni eseguite dall'applicazione abbiano senso. Ma se c'è un collegamento che dovrebbe fare qualcosa di specifico mentre l'applicazione non può gestire, allora dovrebbe permettere al servizio web di gestirlo correttamente. In questo caso, la whitelist non è una buona idea, se il tuo servizio web può fare più della tua applicazione.

Ad alcune persone piace associare solo l'host in manifest, quindi gestire diversi casi nel codice. Non si sa mai quale url inaspettato possa essere catturato, se davvero ha senso a gestirlo con la condizione di "altro". Meglio, fallo con attenzione, elenca solo il pathPrefix di cui siamo sicuri.

Torna al tuo caso, il più delle volte, credo che l'applicazione sia in grado di gestire l'url se è solo diverso nel parametro di query. Perché appartiene alla stessa azione (dal gestore di percorsi API), solo risultati diversi. Solo quando l'intero routing è diverso, dovresti trattarlo diversamente dando il giusto PathPrefix.

Così il valido esempio potrebbe essere:

// To handle: 
http://myhost.com/v/login1?id=123&name=abc&type=a 
// To exclude: 
http://myhost.com/v/login2?id=123&name=abc&type=a 

Poi nel AndroidManifest.xml:

<data android:scheme="http" 
     android:host="myhost.com" 
     android:pathPrefix="/v/login1" /> 

Nota: Nel caso in cui si inciampa su noindex.xml, cioè per l'indicizzazione delle app, non per profonda collegamento di esclusione.

3

potreste lasciare l'applicazione decidere se lasciare che il browser di gestire l'URL

@Override 
protected void onNewIntent(Intent intent) { 
    if (intent.getData().getQueryParameter("type").equals("c")) { 
     forwardToBrowser(intent); 
    } 
    else { 
     handleIntent(intent); 
    } 
}; 

// from https://stackoverflow.com/a/23268821/3221253 
private void forwardToBrowser(Intent i) { 
    Intent intent = new Intent(); 
    intent.setAction(android.content.Intent.ACTION_VIEW); 
    intent.setDataAndType(i.getData(), i.getType()); 
    List<ResolveInfo> activities = getPackageManager().queryIntentActivities(intent, 0); 
    ArrayList<Intent> targetIntents = new ArrayList<Intent>(); 
    String thisPackageName = getApplicationContext().getPackageName(); 
    for (ResolveInfo currentInfo : activities) { 
     String packageName = currentInfo.activityInfo.packageName; 
     if (!thisPackageName.equals(packageName)) { 
      Intent targetIntent = new Intent(android.content.Intent.ACTION_VIEW); 
      targetIntent.setDataAndType(intent.getData(),intent.getType()); 
      targetIntent.setPackage(intent.getPackage()); 
      targetIntent.setComponent(new ComponentName(packageName, currentInfo.activityInfo.name)); 
      targetIntents.add(targetIntent); 
     } 
    } 
    if(targetIntents.size() > 0) { 
     Intent chooserIntent = Intent.createChooser(targetIntents.remove(0), "Open with"); 
     chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[] {})); 
     startActivity(chooserIntent); 
     finish(); 
    } 
} 

Questa implementazione di forwardToBrowser (da https://stackoverflow.com/a/23268821/3221253) consente all'utente di scegliere un browser se hanno più di uno. Potresti semplicemente aprire Chrome se preferisci.

+0

Questo non funziona su Android 6. I queryIntentActivities() restituiscono solo 1 attività (la mia app) – NghiaDao

0

questo lavoro per me

if(Build.VERSION.SDK_INT < 23) { 
    Intent intent = new Intent(); 
    intent.setAction(android.content.Intent.ACTION_VIEW); 
    intent.setDataAndType(i.getData(), i.getType()); 
    List<ResolveInfo> activities = getPackageManager().queryIntentActivities(intent, 0); 
    ArrayList<Intent> targetIntents = new ArrayList<Intent>(); 
    String thisPackageName = getApplicationContext().getPackageName(); 
    for (ResolveInfo currentInfo : activities) { 
     String packageName = currentInfo.activityInfo.packageName; 
     if (!thisPackageName.equals(packageName)) { 
      Intent targetIntent = new Intent(android.content.Intent.ACTION_VIEW); 
      targetIntent.setDataAndType(intent.getData(), intent.getType()); 
      targetIntent.setPackage(intent.getPackage()); 
      targetIntent.setComponent(new ComponentName(packageName, currentInfo.activityInfo.name)); 
      targetIntents.add(targetIntent); 
     } 
    } 
    if (targetIntents.size() > 0) { 
     Intent chooserIntent = Intent.createChooser(targetIntents.remove(0), "Open with"); 
     chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[]{})); 
     startActivity(chooserIntent); 
     finish(); 
    } 
} 
// from SDK 23, queryIntentActivities only return your activity, so you need to disable you activity before forward to browser and enable it later. 
else { 
    final PackageManager pm = getPackageManager(); 
    final ComponentName component = new ComponentName(this, HandleDeepLinkActivity.class); 
    pm.setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); 
    Intent webIntent = new Intent(Intent.ACTION_VIEW); 
    webIntent.setData(i.getData()); 
    startActivity(webIntent); 
    Handler handler = new Handler(); 
    handler.postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      pm.setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0); 
     } 
    }, 500); 
} 
+0

Non è la OP. Per favore rileggi la domanda –

+0

Android non supporta l'esclusione per il link diretto come predefinito, quindi devi gestire questi URL esclusi nella tua attività (avanti al browser) – NghiaDao

0

ho risolto che disattivando il deep linking in seconda intento

manifesto

<activity android:name=".Deeplinking"> 
    <intent-filter> 
     <action android:name="android.intent.action.VIEW" /> 
     <data android:host="*.example.com" /> 
    </intent-filter> 
</activity> 

E nel codice posso capire se voglio il browser/maniglia app e, se necessario, innesca nuovi intenti.

private void openInBrowser(String url) { 
    setDeepLinkingState(PackageManager.COMPONENT_ENABLED_STATE_DISABLED); 

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

    setDeepLinkingState(PackageManager.COMPONENT_ENABLED_STATE_ENABLED); 
} 

private void setDeepLinkingState(int state) { 
    ComponentName compName = new ComponentName(getPackageName(), getPackageName() + ".Deeplinking"); 
    getApplicationContext().getPackageManager().setComponentEnabledSetting(
      compName, 
      state, 
      PackageManager.DONT_KILL_APP); 
}