chrometophone (10)
とりあえず、Activity についておさらいしておく必要あり。
Manifest によれば
- HistoryActivity
- これが MAIN
- SetupActivity
- launchMode が singleTop って何でしょ
- スクリーンが縦固定
- HelpActivity
- スクリーンが縦固定
- ShareLinkActivity
- intent-filter が設定されてます。SEND で data の mimeType が text/plain って
ええと find|xargs grep かけたら HistoryActivity から Intent.ACTION_SEND な Intent を投げてる模様?
AlartDialog でリストなダイアログボックスの 3 番目の項目 (Share link とある) をクリックしたら以下な形で Intent を云々している。
} else if (which == 2) { // Share link Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_TEXT, mSelectedLink.mUrl); intent.setType("text/plain"); startActivity(Intent.createChooser(intent, getString(R.string.share_chooser_title)));
ちなみにこの Activity ですが、BaseExpandableListAdapter を継承した HistoryExpandableListAdapter なソレ (この Activity クラス内で定義) を取り扱ってて、子供の要素をクリックしたらダイアログボックスが表示される仕組みになっている模様です。
画面遷移について
HistoryActivity#onOptionsItemSelected メソドの中身によればオプションメニュからの遷移としては、
- SetupActivity
- HelpActivity
があり得る模様。てーコトはやっぱここが基点なんだな。あと面白いのが onCreateOptionsMenu で以下。
public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.history, menu); return true; }
res/menu/history.xml ってのが以下。
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/clear" android:icon="@android:drawable/ic_menu_close_clear_cancel" android:title="@string/clear_all"/> <item android:id="@+id/settings" android:icon="@android:drawable/ic_menu_preferences" android:title="@string/settings"/> <item android:id="@+id/help" android:icon="@android:drawable/ic_menu_help" android:title="@string/help"/> </menu>
これは知りませなんだ。楽ちんでいいなぁ。あと、onOptionsItemSelected の分岐も以下で済みますね。
public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.clear: {
C2DM なフロー
ええととりあえず Activity から REGISTRATION な Intent を投げるはずなんですがどこだろ。find|xargs grep なソレが以下。
$ find android/ |xargs grep C2DMessaging.register android//c2dm/com/google/android/c2dm/.svn/text-base/C2DMBaseReceiver.java.svn-base: C2DMessaging.register(context, senderId); android//c2dm/com/google/android/c2dm/C2DMBaseReceiver.java: C2DMessaging.register(context, senderId); android//src/com/google/android/apps/chrometophone/.svn/text-base/SetupActivity.java.svn-base: C2DMessaging.register(this, DeviceRegistrar.SENDER_ID); android//src/com/google/android/apps/chrometophone/.svn/text-base/SetupActivity.java.svn-base: C2DMessaging.register(this, DeviceRegistrar.SENDER_ID); android//src/com/google/android/apps/chrometophone/SetupActivity.java: C2DMessaging.register(this, DeviceRegistrar.SENDER_ID); android//src/com/google/android/apps/chrometophone/SetupActivity.java: C2DMessaging.register(this, DeviceRegistrar.SENDER_ID); $
SetupActivity から二つ。一つは onResume メソドからで、もう一つは何かのボタンをクリックした時だな。ちなみに C2DMBaseReceiver からのソレは RETRY な処理に伴うものです。
あら、onResume のソレは以下な記述になってるんですが
protected void onResume() { super.onResume(); if (mPendingAuth) { mPendingAuth = false; String regId = C2DMessaging.getRegistrationId(this); if (regId != null && !"".equals(regId)) { DeviceRegistrar.registerWithServer(this, regId); } else { C2DMessaging.register(this, DeviceRegistrar.SENDER_ID); } } }
mPendingAuth って何だ。定義が以下。
private boolean mPendingAuth = false;
デフォは偽。ちなみに真の状態で onResume 通過したら再度偽になる。真になるタイミングは mAuthPermissionReceiver な BroadcastReceiver の onReceive メソドの中。
Bundle extras = intent.getBundleExtra("AccountManagerBundle"); if (extras != null) { Intent authIntent = (Intent) extras.get(AccountManager.KEY_INTENT); if (authIntent != null) { mPendingAuth = true; startActivity(authIntent); } }
この BroadcastReceiver は一体何か、というと
registerReceiver(mAuthPermissionReceiver, new IntentFilter(AUTH_PERMISSION_ACTION));
で登録されてるんですが、AUTH_PERMISSION_ACTION って何だろ。
public static final String AUTH_PERMISSION_ACTION = "com.google.ctp.AUTH_PERMISSION";
ええと、これは AppEngineClient から sendBroadcast されてます。AccountManager 使って authToken が取得できなかった場合、という事で登録せよ、という BroadcastIntent なのか。
初回認証が必要な場合は
AccountManagerFuture<Bundle> future = accountManager.getAuthToken (account, AUTH_TOKEN_TYPE, false, null, null); Bundle bundle = future.getResult(); authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN); // User will be asked for "App Engine" permission. if (authToken == null) { // No auth token - will need to ask permission from user. Intent intent = new Intent(SetupActivity.AUTH_PERMISSION_ACTION); intent.putExtra("AccountManagerBundle", bundle);
でセットされる Bundle を
Bundle extras = intent.getBundleExtra("AccountManagerBundle");
で取り出して AccountManager.KEY_INTENT で取り出す、と。
Intent authIntent = (Intent) extras.get(AccountManager.KEY_INTENT); if (authIntent != null) { mPendingAuth = true; startActivity(authIntent);
で、startActivity すれば認証確認の画面が出る模様。あら? なんでこのあたりを穿ってたんだっけ。あ、onResume か。上記の認証画面表示処理をした場合のみ、mPendingAuth が真になります。
この時に SetupActivity が表示されたら REGISTRATION な Intent を投げるのか。
もう一箇所 register な手続きを呼び出してる所があるんですが、
- setSelectAccountScreenContent メソドでセットされているボタン
- R.id.next って id のボタンがクリックされた時に register されている
これ (setSelectAccountScreenContent メソド) って setScreenContent 手続きに R.layout.select_account な screenId の場合の分岐で呼び出される模様。
setScreenContent メソドって引数の screenId で setContentView して set* なメソド呼び出してるのか。一応、何かのボタンがクリックされたら REGISTRATION な Intent を投げるんだろうと思うのですが、あまりにも今の N1 に載ってる chrometophone と違いすぎるんだけどなぁ。
svn log で見た所、今見てるソレは
------------------------------------------------------------------------ r212 | burke.davey | 2010-11-08 07:09:23 +0900 (Mon, 08 Nov 2010) | 2 lines Improve ja translations
なリリースらしい。今導入されるソレは 1.0 らしい。code.google.com なナニは 1.7 になってるので、アプリを入れ直した方が良いかもしれないです。
ええい
訳が分からない。
今 N1 に導入されてる chrometophone は一旦削除してもっかい導入してみた方が良さげ。
とりあえず
今から SICP 方面に去ります。