Android IntentFilter data標籤

部分內容參考了:https://blog.csdn.net/iispring/article/details/48481793

<intent-filter>
    <action android:name="com.lenovo.calendar.ACTION_SETTINGS_CHANGED" />

    <data android:scheme="content" />
    <data android:host="com.lenovo.calendar" />
    <data android:mimeType="vnd.lenovo.data/update" />

</intent-filter>

也可寫成這樣

<intent-filter>
    <action android:name="com.lenovo.calendar.ACTION_SETTINGS_CHANGED" />
    <data android:scheme="content" android:host="com.lenovo.calendar" android:mimeType="vnd.lenovo.data/update" />
</intent-filter>

也可以只包含android:scheme 和android:host android:mimeType一個屬性

每個<data />標籤都可以指定一個URI結構以及data的MIME類型。一個完整的URI由schemehostportpath組成,其結構如下所示:

<scheme>://<host>:<port>/<path>

其中scheme既可以是Android中常見的協議,也可以是我們自定義的協議。Android中常見的協議包括content協議、http協議、file協議等,自定義協議可以使用自定義的字符串。

  • 如下是一個content協議的URI: 
    content://com.example.project:200/folder/subfolder/etc 
    在該URI中,scheme是content,host是com.example.project,port是200,path是folder/subfolder/etc。

  • 如下是一個自定義協議的URI: 
    ispring://blog.csdn.net/sunqunsunqun 
    在該URI中,scheme是ispring,host是blog.csdn.net,沒有明確設定port,path是sunqunsunqun。

組成URI的這些屬性在<data />標籤中都是可選的 ,但存在如下的依賴關係:

  • 如果沒有指定scheme,那麼host參數會被忽略
  • 如果沒有指定host,那麼port參數會被忽略
  • 如果scheme和host都沒有指定,path參數會被忽略

當我們將intent對象中的Uri參數與intent-filter中的<data />標籤指定的URI格式進行對別時,我們我們只對比intent-filter的<data />標籤指定的部分,例如:

  • 如果intent-filter中只指定了scheme,那麼所有帶有該sheme的URI都能匹配到該intent-filter。
  • 如果intent-filter中只指定了scheme和authority(authority包括host和port兩部分)而沒有指定path,那麼所有具有相同scheme和authority的URI都能匹配到該intent-filter,而不用考慮path爲何值。
  • 如果intent-filter中同時指定了scheme、authority和path,那麼只有具有相同scheme、authority和path的URI才能匹配到該intent-filter。

需要注意的是,intent-filter的<data />標籤在指定path的值時,可以在裏面使用通配符*,起到部分匹配的效果。

data測試需要同時將intent對象中的URI、MIME類型與intent-filter的<data />標籤中指定的URI、MIME類型進行對比。 
我們知道一個intent-filter下可以有多個<data />標籤,intent對象無需通過所有的<data />標籤測試,一般情況下,我們的intent對象只需通過了其中一個<data />標籤的測試並滿足某些特定情形下的一些條件,那麼該intent對象就通過了該intent-filter的data測試。 
進行對比的規則分以下幾種情況:

  • intent對象不包含URI和MIME類型 
    這種情況下,只有當intent-filter也沒有指定任何URI和MIME類型的時候才能通過data測試。 
    例如我們有如下intent對象:

    Intent intent = new Intent();
    intent.setAction("com.ispring.action.ACTION_TEST1");
    • 1
    • 2
    • 上面的intent對象可以通過下面的intent-filter的data測試:

      <intent-filter>
          <action android:name="com.ispring.action.ACTION_TEST1" />
          <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
      • 1
      • 2
      • 3
      • 4
    • 上面的intent對象無法通過下面的intent-filter測試:

      <intent-filter>
          <action android:name="com.ispring.action.ACTION_TEST1" />
          <category android:name="android.intent.category.DEFAULT" />
          <data android:scheme="ispring" />
      </intent-filter>
      • 1
      • 2
      • 3
      • 4
      • 5
  • intent對象包含URI但不包含MIME類型 
    這種情況下,只有當intent對象的URI匹配到了intent-filter中的URI格式,並且intent-filter沒有指定MIME類型的時候才能通過data測試。需要注意的是,這裏所說的intent-filter沒有指定MIME類型的情形指的是intent-filter中所有的<data />標籤都沒有指定MIME類型,即整個intent-filter中完全沒有android:mimeType這幾個字,理解這點很重要,大家在下面的幾個示例中可以體會到這點。 
    例如有如下intent對象:

    Intent intent = new Intent();
    intent.setAction("com.ispring.action.ACTION_TEST1");
    Uri uri = Uri.parse("ispring://blog.csdn.net/sunqunsunqun");
    intent.setData(uri);
    • 1
    • 2
    • 3
    • 4
    • 上面的intent能通過如下的intent-filter的data測試:

      <intent-filter>
          <action android:name="com.ispring.action.ACTION_TEST1" />
          <category android:name="android.intent.category.DEFAULT" />
          <data android:scheme="ispring" android:host="blog.csdn.net" />
      </intent-filter>
      • 1
      • 2
      • 3
      • 4
      • 5
    • 上面的intent對象可以通過以下intent-filter的data測試:

      <intent-filter>
          <action android:name="com.ispring.action.ACTION_TEST1" />
          <category android:name="android.intent.category.DEFAULT" />
          <data android:scheme="ispring" android:host="blog.csdn.net" />
          <data android:scheme="sunqun" android:host="8080" />
      </intent-filter>
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      intent對象雖然不能通過scheme爲sunqun的<data />標籤測試,但是可以通過scheme爲ispring的data標籤測試,且intent對象和intent-filter中的兩個<data />標籤都沒有指定MIME,所以上面的intent對象可以通過該intent-filter測試。

    • 上面的intent對象無法通過以下intent-filter的<data />標籤測試:

      <intent-filter>
          <action android:name="com.ispring.action.ACTION_TEST1" />
          <category android:name="android.intent.category.DEFAULT" />
          <data android:mimeType="text/plain" android:scheme="ispring" android:host="blog.csdn.net" />
      </intent-filter>
      • 1
      • 2
      • 3
      • 4
      • 5

      上面的intent對象之所以不能通過intent-filter中唯一的一個<data />標籤測試是因爲我們的intent對象沒有指定MIME類型,但是上面的<data />標籤通過android:mimeType="text/plain"設置了MIME類型。

    • 上面的intent對象無法通過以下intent-filter的data測試:

      <intent-filter>
          <action android:name="com.ispring.action.ACTION_TEST1" />
          <category android:name="android.intent.category.DEFAULT" />
          <data android:scheme="ispring" android:host="blog.csdn.net" />
          <data android:mimeType="text/plain" />
      </intent-filter>
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      上面的intent對象之所以無法通過該intent-filter中的data測試,是因爲intent對象沒有設置MIME類型,但是intent-filter中第二個data標籤通過android:mimeType="text/plain"設置了MIME類型。

  • intent對象包含MIME類型但不包含URI 
    這種情況下,只有當intent中的MIME類型與intent-filter中列出的MIME類型相同,並且intent-filter沒有指定任何的URI格式的時候才能通過data測試。需要注意的是,這裏所說的intent-filter沒有指定任何的URI格式的情形指的是intent-filter中所有<data />標籤都沒有指定URI,即整個intent-filter中完全沒有android:schemeandroid:hostandroid:port以及android:path,理解這點很重要,大家在下面的幾個示例中可以體會到這點。 
    例如有如下intent對象:

    Intent intent = new Intent();
    intent.setAction("com.ispring.action.ACTION_TEST1");
    intent.setType("text/plain");
    • 1
    • 2
    • 3
    • 上面的intent對象可以通過以下intent-filter的data測試:

      <intent-filter>
          <action android:name="com.ispring.action.ACTION_TEST1" />
          <category android:name="android.intent.category.DEFAULT" />
          <data android:mimeType="text/plain" />
      </intent-filter>
      • 1
      • 2
      • 3
      • 4
      • 5
    • 上面的intent對象可以通過下面的intent-filter的data測試:

      <intent-filter>
          <action android:name="com.ispring.action.ACTION_TEST1" />
          <category android:name="android.intent.category.DEFAULT" />
          <data android:mimeType="image/*" />
          <data android:mimeType="text/plain" />
      </intent-filter>
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      上面的intent對象雖然沒有通過MIME類型爲image/*的第一個data標籤測試,但能通過第二個data標籤測試,並且intent對象和intent-filter都沒有指定任何的URI格式。

    • 上面的intent對象不能通過以下intent-filter中的data測試:

      <intent-filter>
          <action android:name="com.ispring.action.ACTION_TEST1" />
          <category android:name="android.intent.category.DEFAULT" />
          <data android:mimeType="text/plain" android:scheme="ispring" />
      </intent-filter>
      • 1
      • 2
      • 3
      • 4
      • 5

      上面的intent對象中沒有設置URI信息,但是在該intent-filter中設置了URI中的scheme值,所以intent無法通過intent-filter的data測試。

    • 上面的intent對象無法通過以下intent-filter中的data測試:

      <intent-filter>
          <action android:name="com.ispring.action.ACTION_TEST1" />
          <category android:name="android.intent.category.DEFAULT" />
          <data android:mimeType="text/plain"  />
          <data android:scheme="ispring" />
      </intent-filter>
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      上面的intent對象沒有指定URI信息,但是上面的intent-filter中第二個<data />標籤設置了URI中的scheme信息,所以intent對象無法通過該intent-filter的data測試。

  • intent對象同時包含URI和MIME類型 
    這種情況下,要分別測試URI以及MIME類型測試是否通過,只有URI以及MIME測試都通過了,data測試才能通過。

    • 對於MIME測試:如果intent的MIME類型能夠匹配intent-filter中列出的某一個<data />標籤中的MIME類型值,那麼MIME類型測試就通過了。
    • 對於URI測試: 
      又細分兩種情況,滿足下面的任何一種情況都可以通過URI測試。 
      • 如果intent的URI格式能夠匹配intent-filter中列出的某一個<data />中的URI,那麼URI測試就通過了。
      • 如果intent的URI是content:協議或file:協議,並且整個intent-filter的所有<data />標籤中都沒有指定URI,那麼該intent也能通過URI測試。換句話說,如果一個intent-filter只列出了MIME類型,沒有列出任何URI相關的格式的話,那麼這個intent-filter就默認是支持content:協議或file:協議的。

    下面舉幾個例子大家自己體會一下。

    • 假設有如下協議爲自定義協議ispring:的intent對象:

      Intent intent = new Intent();
      intent.setAction("com.ispring.action.ACTION_TEST1");
      Uri uri = Uri.parse("ispring://blog.csdn.net/sunqunsunqun");
      String type = "text/plain";
      intent.setDataAndType(uri, type);
      • 1
      • 2
      • 3
      • 4
      • 5
      • 上面的intent對象可以通過下面的intent-filter的data測試:

        <intent-filter>
              <action android:name="com.ispring.action.ACTION_TEST1" />
              <category android:name="android.intent.category.DEFAULT" />
              <data android:scheme="ispring" android:host="blog.csdn.net" />
              <data android:mimeType="text/plain"  />
        </intent-filter>
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
      • 上面的intent對象無法通過下面的intent-filter的data測試:

        <intent-filter>
              <action android:name="com.ispring.action.ACTION_TEST1" />
              <category android:name="android.intent.category.DEFAULT" />
              <data android:scheme="ispring" android:host="blog.csdn.net" android:port="8080" />
              <data android:mimeType="text/plain"  />
        </intent-filter>
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6

        port不滿足,URI測試不通過,導致data測試失敗。

      • 上面的intent對象無法通過下面的intent-filter的data測試:

        <intent-filter>
              <action android:name="com.ispring.action.ACTION_TEST1" />
              <category android:name="android.intent.category.DEFAULT" />
              <data android:scheme="ispring" android:host="blog.csdn.net" />
              <data android:mimeType="image/*"  />
        </intent-filter>
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6

        android:mimeType不滿足,MIME類型測試不通過,導致data測試失敗。

    • 假設有如下協議爲content:的intent對象:

      Intent intent = new Intent();
      intent.setAction("com.ispring.action.ACTION_TEST1");
      Uri uri = Uri.parse("content://com.ispring.test");
      String type = "text/plain";
      intent.setDataAndType(uri, type);
      • 1
      • 2
      • 3
      • 4
      • 5
      • 上面的intent對象無法通過下面的intent-filter的data測試:

        <intent-filter>
              <action android:name="com.ispring.action.ACTION_TEST1" />
              <category android:name="android.intent.category.DEFAULT" />
              <data android:scheme="ispring" />
              <data android:mimeType="text/plain"  />
        </intent-filter>
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6

        URI中的scheme不匹配,導致URI測試不通過,導致data測試失敗。

      • 上面的intent對象可以通過下面的intent-filter的data測試:

        <intent-filter>
              <action android:name="com.ispring.action.ACTION_TEST1" />
              <category android:name="android.intent.category.DEFAULT" />
              <data android:mimeType="text/plain"  />
        </intent-filter>
        • 1
        • 2
        • 3
        • 4
        • 5

        intent中使用的是content:協議,並且整個intent-filter中都沒有定義URI格式,所以URI測試是可以通過的,並且MIME類型能找到匹配項,所以可以通過data測試。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章