虚構新聞スポイラー(暗黙のIntentでのURLフック) - ReDo

2010年11月 6日

虚構新聞スポイラー(暗黙のIntentでのURLフック)

虚構新聞(http://kyoko-np.net/)に何度も騙されるので、URLフックなIntentの勉強ついでに虚構新聞スポイラーを作ってみました。

kyoko1.png kyoko2.png

  • "http://kyoko-np.net/"というURLをフックします。
  • フックした後の確認ダイアログでのリンクボタン押下時に、いったんフックを無効化します。
  • onStopで再度フックを有効化します。

ポイントは2点。

ポイント1. intent-filterにscheme="http" host="kyoko-np.net"と設定すると、http://kyoko-np.net/以下のURLをフックしてブラウザと並んで呼び出すActivity一覧に出現してくれます。

参考:http://www.techdoctranslator.com/android/guide/manifest/data-element

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest
	xmlns:android="http://schemas.android.com/apk/res/android"
	package="youten.redo.kyoko"
	android:versionCode="1"
	android:versionName="1.0">
	<application
		android:icon="@drawable/ic_launcher"
		android:label="@string/app_name">
		<activity
			android:name=".KyokoActivity"
			android:label="@string/app_name"
			android:theme="@android:style/Theme.Dialog"
			android:enabled="true">
			<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="http"
					android:host="kyoko-np.net" />
			</intent-filter>
		</activity>
	</application>
	<uses-sdk android:minSdkVersion="3" />
</manifest>

ポイント2. 本当のリンク先にIntentジャンプするButtonを作ると、自分自身がジャンプ先Activityに引っかかってしまうので、これを一時的に無効化してやる必要があります。

参考:Taosoftware:Android Intent呼び出しを自分でコントロール方法
http://www.taosoftware.co.jp/blog/2010/04/android_intent.html

package youten.redo.kyoko;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

/**
 * リンク先は虚構新聞だが大丈夫か?
 */
public class KyokoActivity extends Activity {
	/** ログタグ */
	private static final String TAG = "KyokoSpoiler";
	/** Context*/
	private Context mContext = null;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// コンテキスト。
		mContext = this;

		/** リンク先のURLを取得する。 */
		Intent intent = getIntent();
		if( intent != null ) {
			String scheme = intent.getScheme();
			String data = intent.getDataString();
			Log.d(TAG, "scheme = " + scheme + " data = " + data);
			requestWindowFeature(Window.FEATURE_NO_TITLE);
			setContentView(R.layout.main);

			// リンク先が有効ならジャンプ設定。
			if(data != null) {
				// イベントリスナー設定
				Button goButton = (Button)findViewById(R.id.goButton);
				// URLをtagに設定しておく。
				goButton.setTag(data);
				goButton.setOnClickListener(new OnClickListener() {
					public void onClick(View v) {
						PackageManager pm = mContext.getPackageManager();
						// ジャンプ前にActivity一覧に出ない様にする。
						pm.setComponentEnabledSetting(new ComponentName(mContext, KyokoActivity.class),
								PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

						// リンク先へのジャンプを設定。
						Intent bi = new Intent(Intent.ACTION_VIEW, Uri.parse((String)v.getTag()));
						startActivity(bi);

						finish();
					}
				});
				goButton.setVisibility(View.VISIBLE);

				// URLとメッセージを設定。
				TextView confirmText = (TextView)findViewById(R.id.confirmText);
				String suffix = getResources().getText(R.string.msg_confirm_suffix).toString();
				confirmText.setText(data + suffix);
				confirmText.setVisibility(View.VISIBLE);
			}
		}
	}

	@Override
	protected void onStop() {
		super.onStop();
		// Activity一覧に出る様に戻す。
		getPackageManager().setComponentEnabledSetting(new ComponentName(mContext, KyokoActivity.class),
				PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
	}

}
2011.10.11 追記 ものすごくいまさらですが、短縮URLの展開とか、そもそもブラウザ内の遷移でIntentを用いてないケースがあるので、単純なURLフック設定のみではイマイチなことが多く、本アプリも微妙な感じになっております。 Intentの楽しさが減ってしまうのは残念なのですがサービス側としては情報を抱え込みたいだろうししょうがない...。

コメントする