Android
URL
URI
AndroidManifest.xml

AndroidManifest.xml で URI の Host/Path の有無を識別して Activity を起動し分けてみた件


前提

架空の「スマート LED 操作用アプリ」を題材にします :iphone:


Host の有無の識別

以下の URI が叩かれた場合にアプリ側で対応した Activity を直接立ち上げたいとします。

URI
Activity

smart-led-controller://
MainActivity

smart-led-controller://timer
TimerActivity


問題のあるコード :no_good:


strings.xml

<resources>

<string name="app_name">Smart LED controller</string>

<string name="scheme">smart-led-controller</string>
<string name="host_timer">timer</string>
</resources>



AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.sample.smart_led_controller">

<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</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="@string/scheme" />
</intent-filter>
</activity>

<activity android:name=".TimerActivity">
<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:host="@string/host_timer"
android:scheme="@string/scheme" />
</intent-filter>
</activity>
</application>

</manifest>



問題点

smart-led-controller://timer の URI が叩かれた場合に MainActivityTimerActivity が遷移先の候補として挙がってしまいます :cry:

Screenshot_1532802953.png


対策 :hammer_pick:

MainActivity<data />android:host="" を追記することで smart-led-controller://timer が踏まれても MainActivity は起動先の候補に挙がらなくなりました :grinning:


修正後のコード :ok_woman:


AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.sample.smart_led_controller">

<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</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:host=""
android:scheme="@string/scheme" />
</intent-filter>
</activity>

<activity android:name=".TimerActivity">
<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:host="@string/host_timer"
android:scheme="@string/scheme" />
</intent-filter>
</activity>
</application>
</manifest>



備考 :information_desk_person:

但し Android Studio 様から「ホストを空にすることはできない」と警告を受けます :warning:

android:host cannot be empty.

Ensure the URL is supported by your app, to get installs and traffic to your app from Google Search.

More info: https://g.co/AppIndexing/AndroidStudio


Path の有無の識別

以下の URL が叩かれた場合にアプリ側で対応した Activity を直接立ち上げたいとします。

URL
Activity

https://smart-led-controller
MainActivity

https://smart-led-controller/settings/wi-fi
WifiSettingActivity


問題のあるコード :ng:


strings.xml

<resources>

<string name="app_name">Smart LED controller</string>

<string name="scheme_https">https</string>
<string name="host_smart_led_controller">smart-led-controller</string>
<string name="path_settings_wifi">/settings/wi-fi</string>
</resources>



AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.sample.smart_led_controller">

<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</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:host="@string/host_smart_led_controller"
android:scheme="@string/scheme_https" />
</intent-filter>
</activity>

<activity android:name=".WifiSettingActivity">
<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:host="@string/host_smart_led_controller"
android:path="@string/path_settings_wifi"
android:scheme="@string/scheme_https" />
</intent-filter>
</activity>
</application>
</manifest>



問題点

https://smart-led-controller/settings/wi-fi の URL が叩かれた場合に MainActivityWifiSettingActivity が遷移先の候補として挙がってしまいます :sob:

Screenshot_1532801360.png


対策 :hammer_pick:

MainActivity<data />android:path="" を追記することで https://smart-led-controller/settings/wi-fi が踏まれても MainActivity は起動先の候補に挙がらなくなりました :sparkles:


修正後のコード :ok:


AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.sample.smart_led_controller">

<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</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:host="@string/host_smart_led_controller"
android:path=""
android:scheme="@string/scheme_https" />
</intent-filter>
</activity>

<activity android:name=".WifiSettingActivity">
<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:host="@string/host_smart_led_controller"
android:path="@string/path_settings_wifi"
android:scheme="@string/scheme_https" />
</intent-filter>
</activity>
</application>
</manifest>



備考 :information_source:

但し Android Studio 様から「パスを空にすることはできない」と警告を受けます :rotating_light:

android:path cannot be empty. 

Ensure the URL is supported by your app, to get installs and traffic to your app from Google Search.

More info: https://g.co/AppIndexing/AndroidStudio


One more thing...

https://smart-led-controller/ の URL がタップされた場合にも MainActivity が遷移先の候補に挙るようにしてみます。


方法

MainActivity<intent-filter />android:path="/" を含む <data /> 追記します :writing_hand:


コード


AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.sample.smart_led_controller">

<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</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:host="@string/host_smart_led_controller"
android:path=""
android:scheme="@string/scheme_https" />

<data
android:host="@string/host_smart_led_controller"
android:path="/"
android:scheme="@string/scheme_https" />
</intent-filter>
</activity>

<activity android:name=".WifiSettingActivity">
<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:host="@string/host_smart_led_controller"
android:path="@string/path_settings_wifi"
android:scheme="@string/scheme_https" />
</intent-filter>
</activity>
</application>
</manifest>



参考 :books:

Deep Link のテスト方法について :bulb: