PhoneGap挙動メモ
自メモ)
PhoneGap自体が参考になりそうなサイト)
- MacOSX LionにPhoneGapをインストールしたときのメモ(2012-02-09時点) - iPhone/Android対応 at HouseTect, JavaScriptな情報をあなたに
つい最近数時間ハマったやつ><)
minSdkVersion書かないとActivityが誤動作するという話
2.9.0特記)
うわぁ。phonegap2.7.0からsuper.setIntegerProperty("loadUrlTimeoutValue", 60000);super.loadUrl(Config.getStartUrl()); と宣言逆なん? こういうのMLしか載ってないの詐欺w
appView.setWebChromeClient(new WebChromeClient(){=> appView.setWebChromeClient(new CordovaChromeClient(this){にしないとエラーが出るようになってた。これいつから?
これ結局ソースのアタッチしてわかったんだけど
- libs/cordova-2.9.0.jar.properties
#src=libs_src/cordova-android-master/framework/src src=../libs_src/cordova-android-master/framework/src #doc=
- libs_src/cordova-android-master/framework/src
の認識タイミングがわかんねー。
プロジェクト何回か開き直したり、eclipse再起動したりしてた。
面倒なら手動で
workspace/.metadeta/org.eclipse.jdt.core/.org.eclipse.jdt.core.external.folders/.project
のデータにパスエントリ追加したほうが速いみたい
addJavascriptInterface に関して)
- phoneGap
- appView.addJavascriptInterface(this,"irof"); でOK
- WebView
- 4.2以下 webview.addJavascriptInterface(this,"irof"); でOK
- 4.2以上 @JavascriptInterface でかけ
しかもLintでエラーにしよる‥‥‥死んで欲しいなー ADT22.0.5
- Android Application Project
FullScreenActivity で作成- BlankActivity で作成*1
- 余計なリソースを消す
- suport-v4.jar /values-v11/values-v14
- PhoneGap からSDKダウンロード
- 下記の記述をAndrodiManifest.xmlに追加
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="18" /> <supports-screens android:largeScreens="true" android:normalScreens ="true" android:smallScreens="true" android:resizeable="true" android:anyDensity="true"/> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:name="driven.hoge.HogeActivity"
- Activity => DroidGap 等に変更
//public class HogeActivity extends Activity { public class HogeActivity extends DroidGap { @Override //protected void onCreate(Bundle savedInstanceState) { //<=なぜかActivityで作るとprotected public void onCreate(Bundle savedInstanceState) { super.loadUrl("file:///android_asset/www/index.html"); }
備考)
- Android 1.6 では動かない*3
- ググるとPhoneGap2.0系だと Android1.6とかは動かないよう(1.0系以下なら動く?な記事もちらほら
- docを見るとサポートは2.1から
- ローカルのファイルを参照にするにも下記の権限は必要(libraryがネットワーク参照している)
- (権限なし表記の)オフラインアプリは厳しめ?
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
でもまあ、Android1.6でも一応AU認証等は動くんですが
WebView(組込Webkit)自体が JQuery(Mobile)自体をまともに再生できないらしい ので
まあ動作サポート外にはなるんだろうね(汗
で対応として
- PhoneGapで起動するActivityを別にしてIntent起動という方針をとるしか無い
- シェア的に少なくても受け入れ検証的にはチェックされるので
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //☆ //PhoneGapのサポートは2.1から if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.ECLAIR_MR1){ Intent i = new Intent(getApplicationContext(), HogeActivityPG.class); startActivity(i); finish(); return; } WebView mWebView = _findViewById(R.id.webView); if(mWebView==null) mWebView = new WebView(this); mWebView.loadUrl(url); //勿論 ☆ をコメントにしてWebViewをsetContentViewするのも可 //setContentView(mWebView); } @SuppressWarnings("unchecked") protected <T extends View> T _findViewById(final int id){ return (T)findViewById(id); }
- res/layout/activity_main.xml
- TextView => WebViewに変更
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".HogeActivity" > <!-- <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="@string/hello_world" /> --> <WebView android:id="@+id/webView" android:layout_width="match_parent" android:layout_height="match_parent"> </WebView> </RelativeLayout>
ドメインアクセス制限)
WebView版>
- AndroidManifest.xml
<!-- <data android:scheme="@string/scheme_name" android:host="@string/host_name" android:path="/" /> --> <data android:scheme="http" android:host="hogedriven.net" android:path="/" />
Android2.1の対応をするためには下記のベタ書きしかないイメージ
種別 | 元URL | 抽出箇所 |
---|---|---|
scheme | http://hogedriven.net | http |
host | http://hogedriven.net | hogedriven.net |
path | http://hogedriven.net | / |
参考)
Phonegap2.5.0>
<access origin="http://hogedriven.net" subdomains="false" />
ここにCROSSーDOMAINの登録
オレオレSSL証明書対応)
SSLErrorが出るので対応が必要(出るとみっともないという話があるので)
普通のView版>
ソース自体は
ANDROID_SDK/source/android-15 あたりから
- android/net/http/SSLError.java
- android/webkit/WebViewClient.java
- onReceivedClientCertRequest はコメントにした
コピって使うと。
(ただしADTがSDKの方を強く参照しようとするので デバック実行時に毎回cleanをしないとうまく認識しないかも)
public class MyWebViewClient extends WebViewClient { @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { // testing against getPrimaryError() or hasErrors() will fail on Honeycomb or older. // You might check for something different, such as specific info in the certificate, //if (error.getPrimaryError() == SslError.SSL_IDMISMATCH) { handler.proceed(); //} else { // super.onReceivedSslError(view, handler, error); //} } }
ちなみに
WebViewClient は android-16からかなり変わっているようなので
こっちから持ってくると芋蔓が大変なことに(汗
PhoneGap2.5.0版>
若干コードは変更した
@Override public void init(CordovaWebView webView, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient) { webViewClient = new MyWebViewClient(this); super.init(webView, webViewClient, webChromeClient); } @SuppressLint("NewApi") public class MyWebViewClient extends CordovaWebViewClient { public MyWebViewClient(DroidGap ctx) { super(ctx); } @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { // testing against getPrimaryError() or hasErrors() will fail on Honeycomb or older. // You might check for something different, such as specific info in the certificate, //if (error.getPrimaryError() == SslError.SSL_IDMISMATCH) { handler.proceed(); //} else { // super.onReceivedSslError(view, handler, error); //} } }
Cookie制御)
ログイン情報(cookie)が無ければ
ログイン画面に遷移させたい場合
WebView版>
CookieSyncManager.createInstance(this);//* CookieSyncManager.getInstance().startSync();//* CookieManager.getInstance().setAcceptCookie(true); CookieManager.getInstance().removeExpiredCookie();//期限切れ削除 CookieManager cMgr = CookieManager.getInstance(); String loginCookie = cMgr.getCookie(call_uri); if(loginCookie==null || "".equals(loginCookie.trim())){ mWebView.loadUrl(call_uri_login); } else{ mWebView.loadUrl(call_uri); } mWebView.requestFocus();
*)GalaxyTab等一部の端末で落ちるようなので追記
ちなみに
String[] cookies = loginCookie.split(";"); for (String keyValue : cookies) { keyValue = keyValue.trim(); String[] cookieSet = keyValue.split("="); }
でクッキー情報は取得可能
参考)
PhoneGap版>
CookieSyncManager.createInstance(this);//☆ CookieSyncManager.getInstance().startSync();//☆ CookieManager.getInstance().setAcceptCookie(true); CookieManager.getInstance().removeExpiredCookie();//期限切れ削除 CookieManager cMgr = CookieManager.getInstance(); String loginCookie = cMgr.getCookie(call_uri); if(loginCookie==null || "".equals(loginCookie.trim())){ super.loadUrl(call_uri_login); } else{ super.loadUrl(call_uri); } super.setIntegerProperty("loadUrlTimeoutValue", 60000); //タイムアウト対策
この☆の2つが重要!!
追記)
上記で動いてたわけなんだけど、最終的に全部httpsに仕様変更された
あとから見てもやっつけ感満載で
いやだな〜とか思うんだけど、時間期限が何か異常に短いので仕方ないよな。。
*5
スケジュール感が全然ないよな。
まあAndroidは儲からない から片手間感満載なのかも。。
企業的に儲かるところに力を入れるのは間違いではないのですけれど。。。
Andに関してはIOSとちょっとでもリリースずれるとリリースされないとか
平気であるし*6
>>備忘録として書いておく暫定対応*7
- クッキーが取得できない時の復元側
String BASE_URL="https://hogedriven.net"; //[注]これは仮のものです String BASE_DOMAIN="hogedriven.net"; //[注]これは仮のものです String ROOT_HOME="hogedriven"; String ROOT_KEY="irof"; CookieManager cMgr = CookieManager.getInstance(); String hogeCookie = cMgr.getCookie(BASE_URL); if(hogeCookie==null){ String value = getSharedPreferences(ROOT_HOME, 0).getString(ROOT_KEY,null); if(value!=null){ String[] arr = value.split(";"); for(String s:arr){ s += "; domain=" + BASE_DOMAIN; cMgr.setCookie(BASE_DOMAIN, s); CookieSyncManager.getInstance().sync(); } } } super.loadUrl(url);
- クッキーが取得できない時の保存側
public boolean urlCheck(String url){ if(url==null || "".equals(url.trim()))return false; int idx = url.lastIndexOf("."); int idxSep = url.lastIndexOf("/"); if(idx > idxSep)return false; return true; } @SuppressLint("NewApi") public class HogeWebViewClient extends CordovaWebViewClient { public void onPageFinished(WebView wv, String url){ if(urlCheck(url)){ CookieManager cMgr = CookieManager.getInstance(); String hogeCookie = cMgr.getCookie(BASE_URL); if(hogeCookie!=null && url.indexOf(BASE_DOMAIN)!=-1){ SharedPreferences.Editor editor = getSharedPreferences(ROOT_HOME, MODE_PRIVATE).edit(); editor.putString(ROOT_KEY, hogeCookie); editor.commit(); } hogeCookie = cMgr.getCookie(BASE_URL); }
Alertダイアログ等)
ゲーム作る場合は、ここらへんの標準ダイアログは出るとかっこ悪いので上書きしておく
WebView版>
//alert dialog対策 mWebView.setWebChromeClient(new WebChromeClient(){ @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result){ Log.v(TAG,"[onJsAlert](url,msg)"+ url +"," + message); return false; } @Override public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) { Log.v(TAG,"[onJsConfirm](url,msg)"+ url +"," + message); return true; } @Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) { if(debug_f) Log.v(TAG,"[onJsPrompt](url,msg)"+ url +"," + message); return true; } });
PhoeGap2.5.0版>
//[TODO]super.lodarURLの後でないと appViewは初期化されていないです。 //alert dialog対策 appView.setWebChromeClient(new WebChromeClient(){ @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result){ if(debug_f)Log.v(TAG,"[onJsAlert](url,msg)"+ url +"," + message); return false; } @Override public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) { if(debug_f) Log.v(TAG,"[onJsConfirm](url,msg)"+ url +"," + message); return true; } @Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) { if(debug_f) Log.v(TAG,"[onJsPrompt](url,msg)"+ url +"," + message); return true; } });
ココらへんも結局目視デバックできない
Toast.makeText(activity, message, Toast.LENGTH_SHORT).show();
で 表示することに・・。正直わけわからんわ。。><
使用可能な関数のまとめ)
WebViewでTwitterが見れない&横に変な隙間が。 - 素人のアンドロイドアプリ開発日記
WebViewClientで使える関数のまとめ - 素人のアンドロイドアプリ開発日記
WebChromeClientで使える関数のまとめ - 素人のアンドロイドアプリ開発日記
来世から本気出す: AndroidのWebViewのリファレンスを流し読み
中に表示するコンテンツのデバック用メモ)
Activity宣言関連メモ)
挙動が変で凄く悩んだのでメモ
- 普通のActivity&WebView
<activity android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:name="driven.hoge.HogeActivity"
- DroidGap
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:name="driven.hoge.HogeActivity"
android:theme 宣言があると頭50dipぐらいがちょんぎれるので注意
WebView設定関連>
- 普通のActivity&WebView
- getSetting() => loadUrl
- DroidGap
- super.loadUrl(uri); したあとに getSetting() 等を設定する
Backkey関連>
DroidGapは
- BackkeyがJSからいじる形でメインは殺されている
花水木のエトセトラ: 【JQueryMobileとPhoneGap】 Phone Gapを実装したActivityを終了させる編
見てると他のキー使え な記述がorz
でも結局のところIOSと同じく?やっぱりBackkey要らないなお話があり急遽封じることに*8
IOS至上主義死ね!とか何時も思ってたりしますが。。。
Tizenとか他のプラットホームが出ても同じだろうな。。
HTML5でスマホが作れるのが幸せって思えないorz
うーん。[/]つけなかったり[/]つけたり、コロコロ変える仕様やめて><URLチェックしてバックキー無効実装しろ とかorz (IOSは無いから対応いらないとか)あと言われてるURLとちょこちょこ違うのは何故?嘘仕様言われて=>遅い言われてもな。。
とりあえずDroidGap::init の段階で カスタムCordovaWebView噛ませばonKeyDown自体のフック上書きは可能なのは確認してるんだけどどうしてもHistoryBackが動いてしまう挙動が謎。。。
と思ってたけどIDEAで URLのコードを追いながら見てたらonKeyDownだけじゃなくて onKeyUpでもHistoryBackしている処理があり、そこも上書きしたらいけた。。。うーん。作り微妙。。
PhoneGap的には、JSだけで全部やれ な路線なんだけど
今回のオーダは Andはビューワのみでござる って話なので。
そりゃIOSは内部的にはSafari(標準ブラウザ)で動くから楽だろうさ。。。*9
これもアホな暫定対応。一応また有りそうなのでメモっておく
ついでに一応Menuも対応した
PhoeGap2.5.0版>
@SuppressLint("NewApi") public class HogeActivityPG extends DroidGap { @Override public void init(CordovaWebView webView, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient) { webView = new HogeCordovaWebView(this); //☆ 上書き webViewClient = new IrofWebViewClient(this); super.init(webView, webViewClient, webChromeClient); }
public class HogeCordovaWebView extends CordovaWebView { private boolean debug_f = false; private Resources m_r; public HogeCordovaWebView(Context context) { super(context); m_r = getResources(); debug_f = m_r.getBoolean(R.bool.debug_f); } @Override public boolean onKeyUp(int keyCode, KeyEvent event){ switch(keyCode){ case KeyEvent.KEYCODE_MENU: case KeyEvent.KEYCODE_BACK: return false; case KeyEvent.KEYCODE_HOME: default: break; } return super.onKeyUp(keyCode, event); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) case KeyEvent.KEYCODE_MENU: //対応処理 return false; case KeyEvent.KEYCODE_BACK: //対応処理 return false; case KeyEvent.KEYCODE_HOME: break; default: break; } return super.onKeyDown(keyCode, event); } }
Menu関連>
DroidGapは
- Menu表示が効かない
PhoneGap2.5.0の DroidGap が標準状態でMenuサポートしていないようなので別の方法を考える*10
を参照するとPluginを作って有効にしてね? と記載があるようですが初心者にはそこまではきつい。。><
追記>
これで対応できそうだけど、
- 鯖の仕様コロコロ変更=>情報共有なし って感じだから確認できず。。*11
今回は
throw Life - Androidアプリにサイドメニューを簡単に追加できるライブラリ
を使う方針で
- demoから 下記のファイルをコピー
mSlidingMenu = new SimpleSideDrawer(this); mSlidingMenu.setBehindContentView(R.layout.activity_behind_simple); mSlidingMenu.findViewById(R.id.behind_btn).setOnClickListener(new OnClickListener() { public void onClick(View header) { behindAction(); } }); //Android2系用 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch(keyCode){ case KeyEvent.KEYCODE_MENU: if(mSlidingMenu==null)break; mSlidingMenu.toggleDrawer(); return true; case KeyEvent.KEYCODE_HOME: break; // case KeyEvent.KEYCODE_BACK: // onDestroy(); // android.os.Process.killProcess(android.os.Process.myPid()); // return true; // break; default: break; } return super.onKeyDown(keyCode, event); } //Android3系以降だとこちらを有効にしないとトリガー無い(Homeキー) @Override public void onUserLeaveHint(){ behindAction(); } public void behindAction(){ if(mSlidingMenu==null)return; mSlidingMenu.toggleDrawer(); }
- res/layout/activity_behind_simple.xml を適宜拡張する
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" style="@style/behindMenuScroll" > <LinearLayout style="@style/behindMenuScrollContent" android:layout_marginTop="50dip" > <Button android:layout_marginTop="8dip" android:id="@+id/behind_btn" style="@style/behindMenuItemLabel" android:text="@string/menu_bhind" /> <TextView android:layout_marginTop="8dip" android:id="@+id/menu_reload" style="@style/behindMenuItemLabel" android:text="@string/menu_reload" android:clickable="true" /> <TextView android:layout_marginTop="8dip" android:id="@+id/menu_clear" style="@style/behindMenuItemLabel" android:text="@string/menu_clear" android:clickable="true" /> </LinearLayout> </ScrollView>
ラベルをクリックする場合は
を追加。infrate扱いなので、勿論 android:onClick 等でAction関連付けは不可
android:clickable="true"
横幅は微妙に調整できない(勝手に文字が折り返す)
追記2)
SimpleSideDrawer v1=>v2 移行
- libs
- SimpleSideDrawer0.0.1.jar => simple-side-drawer2.jar
- src
- setBehindContentView => setLeftBehindContentView
- toggleDrawer =>toggleLeftDrawer
- res/layout/activity_behind.xml => activity_behind_left.xml
- @style/behindMenuScroll => @style/leftBehindMenuScroll
- res/values/style.xml
- BehindMenuScroll => leftBehindMenuScroll / rightBehindMenuScroll
DroidGap の他にもおかしい挙動メモ)
- OnKeyDownの KeyEvent.KEYCODE_BACK 等を上書きすると終了しなくなるとかも有
- WebViewClient等をオーバライドした時
- onLoadResource/onPageFinished で
@Override public void onLoadResource(WebView wv,String url){ if(debug_f)Log.v(TAG,"onLoadResource:" + url); super.onLoadResource(wv,url);//☆ } @Override public void onPageFinished(WebView wv, String url){ if(debug_f)Log.v(TAG,"onPageFinished:" + url); super.onPageFinished(wv,url);//☆ }
のsuperの記述を追加しないとページローディングもできなくなる(必ずタイムアウト)
普通のWebView等ではおこらない(汗
Proguard問題)
これを試してみたけど駄目(初期ページのローディングの時点で失敗)
proguard.configを無効にすると動くイメージ。
- project.properties
# Project target. target=android-17 proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
#-dontwarn org.apache.commons.codec.binary.Base64 # PhoneGap proguard -keep public class * extends com.phonegap.api.Plugin -keep public class org.apache.cordova.** -dontwarn android.webkit.* -libraryjars ./libs/commons-codec-1.6.jar # 今回手動で追加したものをkeep classする -keep class android.webkit.WebViewClient -keep class android.net.http.SslError
参考資料)

Android/iPhone/Windows Phone対応 jQuery Mobileスマートフォンアプリ開発
- 作者: 岡本隆史,梶原直人,田中智文
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2012/06/20
- メディア: 大型本
- 購入: 1人 クリック: 62回
- この商品を含むブログ (5件) を見る

プロになるためのJavaScript入門 ~node.js、Backbone.js、HTML5、jQuery-Mobile (Software Design plus)
- 作者: 河村嘉之,川尻剛
- 出版社/メーカー: 技術評論社
- 発売日: 2012/12/07
- メディア: 大型本
- 購入: 4人 クリック: 1,144回
- この商品を含むブログ (8件) を見る

HTML5/JavaScriptとPhoneGapで作るiPhoneアプリ開発入門
- 作者: 富田宏昭
- 出版社/メーカー: マイナビ
- 発売日: 2012/08/31
- メディア: 単行本(ソフトカバー)
- 購入: 1人 クリック: 530回
- この商品を含むブログ (4件) を見る

Web技術者のためのHTML5+JavaScriptで作るAndroidアプリ
- 作者: 坂本俊之
- 出版社/メーカー: シーアンドアール研究所
- 発売日: 2011/06/24
- メディア: 単行本(ソフトカバー)
- クリック: 5回
- この商品を含むブログ (3件) を見る

HTML5/JavaScriptで作るAndroidアプリ開発ガイドブック
- 作者: クジラ飛行机
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2011/04/26
- メディア: 単行本(ソフトカバー)
- 購入: 2人 クリック: 59回
- この商品を含むブログ (5件) を見る
参考リンク系)
- HTML5によるハイブリッドアプリ開発に関する雑記 - id:anatooのブログ
- WebView逆引き - でこちく備忘録
- Day After Neet: AndroidのWebViewをできるだけ速く表示する(キャッシュ・先読み編)
追記)
WebView系は結構鬼門ぽいな。。
動的に android:windowSoftInputMode="stateAlwaysHidden" とか指定できるといいのにな。。(特定URLのみ)設定関数とか無いのだろうか‥‥
ようやく公開できそうなので、ちょっとだけ宣伝。もう少しでオライリーさんからAndroidのテスト本を出します。翻訳書ではなく単著で書き下ろしです。最初の章はAndroidに特化しておらず、全てのテスト技術者に知っておいて欲しい内容です。値段も発売日も未定ですが、必ず出しますので!
2013-03-06 19:03:56 via web
でもどちらかと言うと、最近のクロスプラットフォーム対応はJSベース(WebView)なので、WebViewのテストの話(jasmineの活用の仕方=>JUnitで書ける? 的な奴がほしいな。。。 この頃 @kerukerupappa さんが呟いでる内容は同じ事悩んでる>< RT
@kimukou2628 webview自体がブラックボックスだし、テストの仕方分からないから、タッチして反応見るしか無いので結構しんどいですよねー
*1:変なコードが沢山追加されているので作りなおしたorz
*2:アップグレードする場合は個々らへんを差し替えるイメージ
*3:VerificationError
*4:つうか知らない内に勝手に鯖仕様変えて動かないどうにかしろとか多い気がする
*5:とか思いつつも前回急いでapk作っても結局他のこと忙しくて or 気分がのらなくて 上がリリースしてない とか平気であるし
*6:バグ修正トリガーではリリースされないorz
*7:多分ベストではない
*8:つうか保留でよかった話が急遽リリースとかふざけんな!
*9:でAndroidはIOSに比べて糞って話を 上とIOS担当にdisられるなう。つうかそんなに嫌なら対応やめればいいのにとか思いつつ、立場弱いから無理だね。。<汗
*10:ActionBarが推奨されているからいらない路線?
*11:管理するなら茶庵として欲しいんだけどね。上の人