Xamarin 使いあるあるなのですが, ググっても ホント 何も出て来なくて 本当に本当に苦労したので, ここに書き留めておきます.
Xamarin.Android での話です. myapp://example.jp とか自アプリ独自のURLスキーム( カスタムURL) を使って, 外部アプリから自アプリを起動させたときのハンドリングについてです.
ネイティブの (Javaの) 作法とはちょっと違くて数時間ほどハマりました.
目次
やりたいこと
- 他アプリ(外部アプリ)との連携などを想定している.
- web ブラウザなど他アプリで『myapp://example.jp/comment/view/801』へのリンクを叩くと, 自アプリが起動する
- その起動に使われた URL を parse してアプリ内で操作したい. (例: 『comment/view/801』が来たら, コメントID 801 のコメントを表示させる, など)
(iOS版はこちら)
まずカスタムURLスキームを登録
iOS アプリとは違い, Android アプリは Activity ベースなので, 目的の Activityクラスに attribute を付与します.
* ネイティブ開発環境(Java)とは違い, Xamarin の場合, AndroidManifest.xml をいじらず, 対象の Activity ファイルをいじる)
以下は,
myapp://example.jp
で 開かせるために必要な設定の記述例です
[Activity(Label = "" , ..略..)] [IntentFilter( actions: new [] { Intent.ActionView } , Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable } , DataHost = "example.jp" , DataScheme = "myapp" )] public class MainActivity : Activity {
この IntentFilter の記述が重要です
叩かれたURLをアプリ側で解析
叩かれたURLをアプリ側で解析しましょう
protected override void OnResume() { base.OnResume(); var intent = this.Intent; if (Intent.ActionView.Equals(intent.Action)) { var uri = intent.Data; // uri: myapp://example.jp/comment/view/801 if (uri != null) { // 渡ってきたURLをスラッシュ区切りでリストにして, それを表示させて確認 uri.PathSegments .ToList() .ForEach(Console.WriteLine); } } }
動かした時(= “myapp://example.jp/comment/view/801” を叩いて起動させた時) の
コンソールへの出力:
comment 05-22 19:07:03.239 I/mono-stdout(28560): comment 05-22 19:07:03.239 I/mono-stdout(28560): view view 05-22 19:07:03.249 I/mono-stdout(28560): 801 801
iOS では自前で path を解析しなければなりませんでしたが, Android では .PathSegments というプロパティが用意されていて非常に良さがありますね.
これで List で {“comment”, “view”, “801” }という文字列たちが得られたので, これらを使って目的の操作の実装したら良さそうです
ちゃんと起動するか確認
外部アプリから myapp://example.jp を叩いて, ちゃんと 自アプリが起動するか試してみましょう.
ここで, お手軽な webブラウザで試してみます.
iOS 版では URLバーにアドレス直打ちでいけましたが, Android版ではダメです!
1つ webページを作って, そこで
<a href="myapp://example.jp/comment/view/801">test</a>
などと言ってリンクを作ってください.
動作確認はコレを使います.
Android機を起動して, このリンクを踏んで, 自アプリが起動すれば成功です.
この作成方法はfirebase-Dynamic Linkを使用していますか?