読者です 読者をやめる 読者になる 読者になる

SIN@SAPPOROWORKSの覚書

C#を中心に、夜な夜な試行錯誤したコードの記録です。

1 インテント

インテントには、暗黙的インテントと明示的インテントがあります。

(1) 明示的インテント

アクティビティ名を具体的に指定する。先のActivity起動が、そのものズバリです。

StartActivity(new Intent(this,typeof (Activity2)));

(2) 暗黙的インテント
データとアクションを指定して、システムがアクティビティを選択するのも。

//var intent = new Intent(Intent.ActionView, Android.Net.Uri.Parse("http://www.google.com"));
var intent = new Intent(Intent.ActionView);
intent.SetData(Android.Net.Uri.Parse("http://www.google.com"));
StartActivity(intent);

下記のコードで、デフォルトでインストールされているブラウザが起動する。

//アクション : ACTION_VIEW 
//データ : URL
var intent = new Intent(Intent.ActionView);
intent.SetData(Android.Net.Uri.Parse("http://www.google.com"));

StartActivity(intent); //暗黙的インテントによるActivity起動

2 マニュフェストの編集

システムが暗黙的にインテントを選択するとき、インテントフィルタが使用される。
AndroidManifest.xmlを追加することで、独自に作成したActivityをインテントフィルタに登録できます。

(1) AndroidManifest.xmlの自動生成

Xamarin Developer CenterのGuidesには、Xamarinでは、AndroidManifest.xmlを手動でいじることは99%ないと書かれていました。
http://docs.xamarin.com/guides/android/advanced_topics/working_with_androidmanifest.xml/

属性を指定することで、AndroidManifest.xmlに自動追加させる事が推奨されているようです。

ソリューションエクスプローラで見えているAndroidManifest.xmlは、自動追加前の状態で、コンパイル後に自動追加されたものが、ソリューション\\obj\\Debug\\androidの下に生成されています。

ソリューションエクスプローラで見えているもの

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
	<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="8" />
	<application></application>
  <my>試験的に手動で追加</my>
</manifest>

自動生成されたもの

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="AndroidApplication1.AndroidApplication1">
  <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="8" />
  <application android:name="mono.android.app.Application" android:debuggable="true">
    <activity android:icon="@drawable/icon" android:label="AndroidApplication1" android:name="androidapplication1.Activity1">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    <provider android:name="mono.MonoRuntimeProvider" android:exported="false" android:initOrder="2147483647" android:authorities="AndroidApplication1.AndroidApplication1.mono.MonoRuntimeProvider.__mono_init__" />
    <receiver android:name="mono.android.Seppuku">
      <intent-filter>
        <action android:name="mono.android.intent.action.SEPPUKU" />
        <category android:name="mono.android.intent.category.SEPPUKU.AndroidApplication1.AndroidApplication1" />
      </intent-filter>
    </receiver>
  </application>
  <my>試験的に手動で追加</my>
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>


(2) inten-filterの追加

属性指定でinten-filterを追加するコードは下記のようになります。

[Activity(Label = "MyApp")]
    [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault },DataScheme = "http")]

この時、自動生成されたAndroidManifest.xmlには、ちゃんとinten-filter追加されていた。


<activity android:label="MyApp" android:name="test1.HTTPActivty">
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="http" />
      </intent-filter>
    </activity>


3 インテント解決

(1) スキーム追加

新しいActivity(Activity2)を追加し、先の要領でプロトコルhttpにインテントフィルタを追加すると、暗黙的インテントで、httpを呼び出したとき、選択ダイアログが表示されるようになります。


[Activity(Label = "MyApp")]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "http")]
public class Activity2 : Activity{

無題2

(2) ホストやポート番号の追加

スキーム以外にも、ホストやポート番号なども指定可能です。スキームだけでなくホスト、ポート番号を指定する要領は、次のようになります。

[Activity(Label = "MyApp")]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault },
         DataScheme = "http", DataHost = "sample.com", DataPort = "1234")]
public class Activity2 : Activity{

この時生成されたマニフェストは下記の通り。

<activity android:label="MyApp" android:name="androidapplication1.Activity2">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:host="sample.com" android:port="1234" android:scheme="http" />
    </intent-filter>
</activity>

上記のフィルタを登録した状態では、「http://sample.com:1234」を指定した場合だけ、選択ダイアログが表示され、それ以外のhttpでは、ダイレクトにブラウザが起動します。

なお、Activity2は、同一アプリ内に存在する必要はありません。別のアプリにあるActivityでも動作は同じです。

ちなみに、登録されるのに少し時間がかかるのか・・・?
呼び出されるActivitiyを再コンパイルすると、利用できるようになるまでに数十秒かかる事がありました。