Фильтр намерений для медиаплеера (Youtube Video Play) - PullRequest
4 голосов
/ 20 декабря 2010

Я разработал собственный медиаплеер и хочу, чтобы, когда я хочу посмотреть видео с Youtube, оно открывалось из моего приложения.По крайней мере, в представлении должен быть список мультимедийных приложений, и я должен иметь возможность выбрать свое приложение из списка.Я не знаю много о фильтрах намерений.Как я могу предоставить это в моем файле манифеста?Я работаю над тем, чтобы сделать это для локальных файлов для обучения, но я тоже пока не смог сделать это.Мне очень нужна твоя помощь: /

Ответы [ 2 ]

11 голосов
/ 05 сентября 2011

Если вы посмотрите на фильтр намерений, используемый официальным приложением YouTube, вы увидите следующее:

<activity android:name="Player">

    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="http"  android:host="youtube.com" android:pathPrefix="/watch" />
        <data android:scheme="https" android:host="youtube.com" android:pathPrefix="/watch" />
    </intent-filter>

    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="http"  android:host="*.youtube.com" android:pathPrefix="/watch" />
        <data android:scheme="https" android:host="*.youtube.com" android:pathPrefix="/watch" />
    </intent-filter>

    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="http"  android:host="www.youtube.com" android:pathPrefix="/v/" />
        <data android:scheme="https" android:host="www.youtube.com" android:pathPrefix="/v/" />
        <data android:scheme="http"  android:host="www.youtube.com" android:pathPrefix="/e/" />
        <data android:scheme="https" android:host="www.youtube.com" android:pathPrefix="/e/" />
        <data android:scheme="http"  android:host="www.youtube.com" android:pathPrefix="/embed/" />
        <data android:scheme="https" android:host="www.youtube.com" android:pathPrefix="/embed/" />
    </intent-filter>

    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="vnd.youtube" />
    </intent-filter>

</activity>

Чтобы получить идентификатор видео, вы можете проанализировать полученную строку:

Uri uri = this.getIntent().getData();

Как видите, для youtu.be не существует фильтра, но его можно добавить с помощью:

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="http"  android:host="youtu.be" />
    <data android:scheme="https" android:host="youtu.be" />
</intent-filter>
2 голосов
/ 12 января 2015

Я обновляю ответ H9kDroid от 2011 года. Это соответствующие декомпилированные фильтры намерений из последней версии YouTube APK (11 января 2015 г.).

<activity-alias android:theme="@01030055"
    android:name="com.google.android.youtube.UrlActivity"
    android:exported="true"
    android:targetActivity="com.google.android.apps.youtube.app.honeycomb.Shell$UrlActivity">
  <intent-filter>
    <action android:name="android.intent.action.VIEW">
    </action>
    <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH">
    </action>
    <action android:name="android.nfc.action.NDEF_DISCOVERED">
    </action>
    <category android:name="android.intent.category.DEFAULT">
    </category>
    <category android:name="android.intent.category.BROWSABLE">
    </category>
    <data android:scheme="http">
    </data>
    <data android:scheme="https">
    </data>
    <data android:host="youtube.com">
    </data>
    <data android:host="www.youtube.com">
    </data>
    <data android:host="m.youtube.com">
    </data>
    <data android:host="youtu.be">
    </data>
    <data android:pathPattern=".*">
    </data>
  </intent-filter>
  <intent-filter>
    <action android:name="android.intent.action.VIEW">
    </action>
    <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH">
    </action>
    <action android:name="android.nfc.action.NDEF_DISCOVERED">
    </action>
    <category android:name="android.intent.category.DEFAULT">
    </category>
    <category android:name="android.intent.category.BROWSABLE">
    </category>
    <data android:scheme="vnd.youtube">
    </data>
    <data android:scheme="vnd.youtube.launch">
    </data>
  </intent-filter>
</activity-alias>

И этокак эти намерения, кажется, анализируются в коде.Извините, что это запутано, но все равно было полезно в моем случае:

import android.net.Uri;
import android.net.Uri.Builder;
import android.text.TextUtils;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public final class glb
{
  public final List a;
  public final int b;

  private glb(String paramString, Map paramMap, int paramInt)
  {
    this(Collections.singletonList(paramString), paramMap, paramInt);
  }

  private glb(List paramList, Map paramMap, int paramInt)
  {
    this.a = Collections.unmodifiableList((List)b.c(paramList, "videoIds can not be null"));
    if (!this.a.isEmpty()) {}
    for (boolean bool = true;; bool = false)
    {
      b.c(bool, "videoIds cannot be empty");
      Collections.unmodifiableMap((Map)b.c(paramMap, "params can not be null"));
      this.b = paramInt;
      return;
    }
  }

  private static int a(Uri paramUri, Map paramMap)
  {
    String str1 = (String)paramMap.get("t");
    if (str1 == null)
    {
      String str2 = Uri.decode(paramUri.getEncodedFragment());
      if (!TextUtils.isEmpty(str2))
      {
        String[] arrayOfString1 = str2.split("&");
        int i = arrayOfString1.length;
        for (int j = 0; j < i; j++)
        {
          String[] arrayOfString2 = arrayOfString1[j].split("=");
          if ((arrayOfString2.length == 2) && ("t".equals(arrayOfString2[0]))) {
            str1 = arrayOfString2[1];
          }
        }
      }
    }
    return a(str1);
  }

  private static int a(String paramString)
  {
    if (paramString == null) {
      return 0;
    }
    int i = paramString.indexOf("h");
    int j;
    if (i >= 0)
    {
      j = 0 + 3600000 * a.b(paramString.substring(0, i), 0);
      paramString = paramString.substring(i + 1);
    }
    for (;;)
    {
      int k = paramString.indexOf("m");
      if (k >= 0)
      {
        j += 60000 * a.b(paramString.substring(0, k), 0);
        paramString = paramString.substring(k + 1);
      }
      if (paramString.endsWith("s")) {
        paramString = paramString.substring(0, -1 + paramString.length());
      }
      return j + (int)(1000.0F * a.a(paramString, 0.0F));
      j = 0;
    }
  }

  public static glb a(Uri paramUri)
  {
    if ("https".equals(paramUri.getScheme())) {
      paramUri = paramUri.buildUpon().scheme("http").build();
    }
    if ("vnd.youtube".equals(paramUri.getScheme()))
    {
      String str7 = paramUri.getSchemeSpecificPart();
      if (str7.startsWith("//")) {
        str7 = str7.substring(2);
      }
      if (TextUtils.isEmpty(str7))
      {
        String str9 = String.valueOf(paramUri);
        throw new ParseException(24 + String.valueOf(str9).length() + "No video id in the Uri: " + str9, 0);
      }
      int i = str7.indexOf('?');
      if (i > 0) {}
      for (String str8 = str7.substring(0, i);; str8 = str7)
      {
        Map localMap3 = b(paramUri);
        return new glb(str8, localMap3, a((String)localMap3.get("t")));
      }
    }
    if ("youtu.be".equalsIgnoreCase(paramUri.getHost()))
    {
      List localList = paramUri.getPathSegments();
      if ((localList.isEmpty()) || (TextUtils.isEmpty((CharSequence)localList.get(0))))
      {
        String str6 = String.valueOf(paramUri);
        throw new ParseException(29 + String.valueOf(str6).length() + "No video id in the Uri path: " + str6, 0);
      }
      Map localMap2 = b(paramUri);
      return new glb(localList.subList(0, 1), a(localMap2), a(paramUri, localMap2));
    }
    String str1 = paramUri.getPath();
    String str2 = paramUri.getFragment();
    if ((str1.startsWith("/watch")) || (str1.startsWith("/movie"))) {
      return c(paramUri);
    }
    if (str1.startsWith("/get_video"))
    {
      Map localMap1 = b(paramUri);
      String str4 = (String)localMap1.get("video_id");
      if (!TextUtils.isEmpty(str4)) {
        return new glb(str4, a(localMap1), a(paramUri, localMap1));
      }
      String str5 = String.valueOf(paramUri);
      throw new ParseException(24 + String.valueOf(str5).length() + "No id found in the uri: " + str5, 0);
    }
    if (str1.startsWith("/v/")) {
      return d(paramUri);
    }
    if ((str1.startsWith("/e/")) || (str1.startsWith("/embed/"))) {
      return new glb(paramUri.getLastPathSegment(), b(paramUri), a(paramUri.getQueryParameter("start")));
    }
    if ((str2 != null) && ((str2.startsWith("/watch")) || (str2.startsWith("watch"))))
    {
      String str3 = paramUri.getFragment();
      return c(Uri.parse(paramUri.buildUpon().encodedPath(str3).fragment("").build().toString()));
    }
    throw new ParseException("Unrecognised URI", 0);
  }

  private static Map a(Map paramMap)
  {
    HashMap localHashMap = new HashMap(paramMap);
    localHashMap.remove("v");
    localHashMap.remove("video_id");
    localHashMap.remove("video_ids");
    localHashMap.remove("feature");
    return localHashMap;
  }

  private static Map b(Uri paramUri)
  {
    if (paramUri.isOpaque()) {
      return Collections.emptyMap();
    }
    HashMap localHashMap = new HashMap();
    Iterator localIterator = paramUri.getQueryParameterNames().iterator();
    while (localIterator.hasNext())
    {
      String str = (String)localIterator.next();
      localHashMap.put(str, paramUri.getQueryParameter(str));
    }
    return localHashMap;
  }

  private static glb c(Uri paramUri)
  {
    Map localMap = b(paramUri);
    String str1 = (String)localMap.get("v");
    String str2 = (String)localMap.get("video_ids");
    if ((TextUtils.isEmpty(str1)) && (TextUtils.isEmpty(str2)))
    {
      List localList = paramUri.getPathSegments();
      int i = localList.indexOf("watch");
      if (i < 0)
      {
        String str6 = String.valueOf(paramUri);
        throw new ParseException(28 + String.valueOf(str6).length() + "No /watch/ part in the Uri: " + str6, 0);
      }
      if (i + 1 >= localList.size())
      {
        String str5 = String.valueOf(paramUri);
        throw new ParseException(24 + String.valueOf(str5).length() + "No id found in the Uri: " + str5, 0);
      }
      str1 = (String)localList.get(i + 1);
      if (TextUtils.isEmpty(str1))
      {
        String str4 = String.valueOf(paramUri);
        throw new ParseException(24 + String.valueOf(str4).length() + "No video id in the Uri: " + str4, 0);
      }
    }
    String str3 = str1;
    if (str2 == null) {
      return new glb(str3, a(localMap), a(paramUri, localMap));
    }
    return new glb(Arrays.asList(str2.split(",")), a(localMap), a(paramUri, localMap));
  }

  private static glb d(Uri paramUri)
  {
    String[] arrayOfString1 = paramUri.getLastPathSegment().split("&");
    String str = arrayOfString1[0];
    HashMap localHashMap = new HashMap();
    for (int i = 1; i < arrayOfString1.length; i++)
    {
      String[] arrayOfString2 = arrayOfString1[i].split("=");
      if (arrayOfString2.length == 2) {
        localHashMap.put(arrayOfString2[0], arrayOfString2[1]);
      }
    }
    return new glb(str, localHashMap, a((String)localHashMap.get("start")));
  }
}
...