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

日々精進

新しく学んだことを書き留めていきます

クラスのメンバとして定義されているEnumをKeepするproguardの設定など

proguard-project.txtの設定の一部。 # Enumをkeepする対応 -keep public class * extends java.lang.Enum # クラスのメンバとして定義されているEnumをKeepする対応 -keepattributes InnerClasses -keep public enum ParentClass$** { **[] $VALUES; public…

LinearLayoutの子Viewの順序を動的に入れ替える

一度removeしてから好きな位置にaddViewする。例は以下。 navigationBar.removeView(orderModeCheckbox); if (orderModeCheckbox.isChecked()) { navigationBar.addView(orderModeCheckbox, navigationBar.getChildCount()); // 一番最後に追加 } else { nav…

配列とArrayListではequalsの挙動が違い、配列をMapのKeyにしてはいけない

配列のequalsはObject.equalsをオーバーライドしないため、すべての同じIndexの要素が等価である場合のみtrueになる。 ArrayListはすべての同じIndexの要素のequalsメソッドの結果がtrueであればtrueになる。 MapのKeyに配列を使ってしまってハマった。。Arr…

画面の向きを現在の向きに固定する

現在の向きが縦でも横でも固定したいという場合。API Levelが18以上であれば、以下を実行するだけでいい。 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED); 17以下であれば以下のようにする。 switch (((WindowManager) getSystemService…

ビルドすると「Could not find com.google.android.gms:play-services」エラー

原因はGoogle Repository SDKがダウンロード出来ていないこと。 SDK managerからGoogle Repositoryの最新版をダウンロードすると直る。 参考: Gradle unable to resolve Play services dependency

Viewに枠線をつける

border.xmlのような名前で以下をXMLに定義する。 <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <solid android:color="#ffffff" /> <stroke android:width="1dip" android:color="#4fa5d5"/> </shape> あとはこれをbackgroundに設定すればよい。

TableLayoutの2つ以上の列をstretchした上で同じ幅にする

例えば、xmlでTableLayoutにandroid:stretchColumns="0,2"を設定すると1列目と3列目の幅をできる限り広くしてくれる。 が、セル内のTextView等の幅が変化すると1列目と3列目の幅が同じでなくなってしまう。 これは、android:layout_width="0dp"をすべてのstr…

チェックボックスをタップした時にチェックを付けさせない

チェックボックスをタップした時にチェックを付けさせないとか意味分からないと思うが、 バリデーションエラーになった場合などでタップしてもチェックを付けたくない場合がある。 そういう場合はonCheckedChangedイベントの中でsetChecked(false)を実行する…

リソースフォルダに修飾子を複数付けるときの注意

修飾子は順序が決まっているので、その順序で付けないといけない。 例えば、drawable-hdpi-landはだめでdrawable-land-hdpiとしないといけない。 参考: android providing different drawable resources for orientations http://developer.android.com/gui…

setBackgroundDrawableがAPI level 16以上でdeprecatedになっている

API level 15以下と16以上の両方をサポートする場合は以下のように分岐させないといけない。 Utilクラスにこのメソッドを定義しておくとよい。 public static void setBackground(View view, Drawable drawable) { if (Build.VERSION.SDK_INT >= Build.VERSI…

build.gradleにcompile 'com.google.android.gms:play-services:5.0.89'を追加すると「Attribute “theme” has already been defined」エラー

原因はplay-servicesでAttribute “theme”が定義されているため。 compile 'com.google.android.gms:play-services:5.0.89' を compile 'com.google.android.gms:play-services:6.1.+' に変更すると直る 参考: Lollipop AppCompat-v7 21 - Attribute "theme"…

compile 'com.android.support:appcompat-v7:20.+'をbuild.gradleに追加すると「This support library should not use a lower version」エラー

原因はcompileSdkVersionで指定しているバージョンより古いバージョン用のsupport libararyを使用していたため。 compile 'com.android.support:appcompat-v7:20.+' を compile 'com.android.support:appcompat-v7:21.+' に修正すると直った。 参考: Androi…

CookieをSerializeする/SerializableなObjectをStringに変換する

Cookieを永続化することになったので調べた。android-async-httpのPersistentCookieStoreを使うと簡単に永続化できそうだけど、そのためにライブラリをインストールするのはイヤだったので自作しました。 CookieクラスはSerializableを継承していないので、S…

ImageButtonにadjustViewBounds="true"を設定しても画像のサイズが変化しない

ImageButtonではなく、ImageViewを使わないといけない。これは罠だ。。 画像を縦横比を保ったまま、横幅を画面いっぱいまで拡大するには、以下の設定にしてandroid:srcかsetImageBitmapメソッドで画像を渡せばよい。

AndroidでButtonにBitmap画像を設定する

ImageButtonを使う。 ImageButton#setImageBitmapにBitmapオブジェクトを渡せば良い。 参考: How can I set a bitmap on button?

エミュレータからHTTPリクエストを送信すると「No address associated with hostname」

原因はエミュレータのWIFIがOFFになっていたことだった。しょぼい。。 機内モードにする時に間違ってWIFIをOFFにしてしまっていたっぽい。皆さんもお気を付けください。

screen orientationの設定値とその効果一覧

画面を時計回りに90度回転して横向きにすると画面が逆さまになる不具合が発生した。原因はmanifestで横画面のactivityにandroid:screenOrientation="landscape"を設定していることだった。 landscapeは反時計回りに90度回転して横向きにした向きのことで、時…

タッチイベントの座標を親View内での座標に変換する

motionEvent.getX()はタップされたViewの座標系での座標だが、これを親Viewの座標系での座標に変換したい場合は以下のように計算すれば良い。 view.getLeft() + motionEvent.getX() iOSではconvertPoint:toView:で任意のViewの座標系に変換出来るんだけど、A…

macでバイナリファイルを比較する

以下コマンドで比較できる。 cmp file1 file2 とりあえず同じファイルかどうかを確認するならこれで十分。 参考: Mac Terminal Command -【cmp】 2つのファイルの中身が同じかどうか

adb install -rでapkを上書きインストールしようとするとINSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATESエラー

原因はインストール済みのアプリと上書きインストール使用としているアプリの証明書が違うため。 証明書の確認をするために実機からapkを抜き出したり、apkの署名やKeystoreの情報を確認したそのときのコマンドは以下。 Android 実機から apk を探して取得す…

build.gradleのデバッグ実行(未解決)

Android Studioの右上にある「Gradle」のタブから、Gradleタスクを右クリックしてDebug実行するとbuild.gradleをDebug実行できるという情報があったが、build.gradleに貼ったBreakpointで止まらず。。なぜだ。 参考: AndroidStudioでgradleの実行時にDebugg…

buildTypeまたはproductFlavor毎に異なるsigningConfigを設定する

以下のようにbuildTypeのsigningConfigにsigningConfigsの設定のうち使用するものを渡せば良い。productFlavorの場合も同様。 signingConfigs { debug { storeFile file("conf/debug.keystore") storePassword "android" keyAlias "androiddebugkey" keyPass…

ScheduledExecutorService#scheduleAtFixedRateはsequentialにタスクを実行する

ScheduledExecutorService#scheduleAtFixedRateを短い間隔で何度も実行した場合、各タスクは並列に実行するのかを調べた。 結果、並列に実行はしないことがわかった。タスクはQueueに積んで一つずつ実行する。 参考: Does scheduleAtFixedRate call a diffe…

local.propertiesにsigningConfigsを格納する

build.gradleやgradle.propertiesはSCMにコミットするのでパスワード等は書きたくない。 なのでlocal.propertiesにsigningConfigsの情報を格納することにした。 コードは以下。 signingConfigs { // 署名情報はlocal.propertiesに記述すること。 Properties …

keystoreのkeyAliasを調べる方法

以下コマンドで調べられる。 keytool -list -keystore /android.keystore.path 出力される文字列のうち、どの部分がkeyAliasに当たるかは下記参照。 もしandroid.keysotreのkey aliasを忘れてしまったなら - Qiita

Androidでビルド時に「Configuration with name 'default' not found」エラー

原因はライブラリへの参照を、通常のjarを取ってくる形式のものからプロジェクト参照に変更した時に、参照先のパスを間違えていたため。 具体的にはsettings.gradleに以下を追記した。 include ':library' project(':library').projectDir = new File(settin…

org.apache.http.impl.client.DefaultHttpClientを使って通信している時にInterruptedIOExceptionが発生する

原因は以下。 ScheduledExecutorServiceを使ってポーリングしてて、ポーリングを一度止める場合にScheduledExecutorService#shutdownNowを実行していた。 shutdownNowを実行するとThread.interrupted()がtrueになる HttpClientのコードの中にループをぐるぐ…

Android4.1〜4.4でDatePickerDialogのボタンが「完了」のみになる

DatePickerDialogのボタンはOKとキャンセルの二つのはずなのに完了しか表示されない。。。と思ったらAndroidのバグらしい。4.1〜4.4で発生する。 このバグはIssueTrackerに登録されているが何年も放置されているので直ることはないだろう。 https://code.goo…

Androidの回転制御 端末の自動回転設定がOFFの場合は回転させない

端末を回転させたら画面も回転させる場合、以下を実行していたがSCREEN_ORIENTATION_SENSORだと端末の自動回転設定をOFFにしても回転してしまう。 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); SCREEN_ORIENTATION_UNSPECIFIEDだと自…

UI Automator ViewerでViewの構造を調べる

Hierarchy ViewerでViewの構造を調べようとすると、以下のエラーメッセージが出て調べられなかった。 [2015-06-10 14:29:03 - ViewServerDevice]Unable to debug device: ... [2015-06-10 14:29:04 - hierarchyviewer]Missing forwarded port for ... [2015-…

実機からログを取り出す

テスターが実機でアプリを動かしていたらアプリが落ちたといって実機を開発者のところに持ってきた場合。 アプリのログは/dev/log/mainに吐かれるのでこれを参照すれば良い。 参考: Google グループ

Androidで同時タップを禁止する

iOSでは各ボタンにexclusiveTouchを設定していくところだが、Androidは 一箇所Styleを設定するだけでOKっぽい。 以下のように設定する。 <style name="MyTheme" parent="@android:style/Theme.Holo.Light"> <item name="android:windowEnableSplitTouch">false</item> <item name="android:splitMotionEvents">false</item> </style>

ZipInputStream#readで読み込んだデータが途中で切れる

1KB程度以上のファイルをZipInputStream#readで読み込むと途中で切れてしまった。 原因はZipInputStream#readはファイルの最後までデータを読み込むことを保証していないため。 BufferedInputStreamを使うと最後まで読み込める。 コード例は以下。 ZipInputS…

AQUOS PHONE 104SHでFile.createTempFileを実行するとアクセス権が無くエラーになる

このようなコードではエラーが出た。 File tempFile = File.createTempFile("tempfile", ".zip"); 以下のように直すと直った。 File tempFile = File.createTempFile("tempfile", ".zip", context.getFilesDir()); やっぱAndroidは機種毎に挙動が違って大変…

Viewのwidth, heightをコードから変更する

カスタムViewGroupの子Viewのwidth, heightをコードから変更する場合、 setLayoutParamsを使えばいい。ただ、これを実行するタイミングはonMeasure実行以前でないといけない。 例えば、onLayoutはonMeasureの後で呼ばれるのでonLayoutの中でsetLayoutParams…

デシリアライズした時にtransientなフィールドを初期化する

transientなフィールドがデシリアライズした時にnullになるのを避けるには、readObjectメソッドの中でフィールドを初期化すればいい。 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject()…

build variant毎にアプリ名を変更する

manifestPlaceholdersを使ってbuild variant毎に異なる値をManifestに埋め込む。 build.gradleで以下のようにmanifestPlaceholdersを定義しておく。 productFlavors { staging { manifestPlaceholders = [appName:"@string/app_name_staging"] } } Manifest…

ビルドすると「Manifest merger failed : Attribute application@label value...」エラー

エラーメッセージにも書いてあるけど、「tools:replace="label"」属性を追加すると直った。 この属性を追加するとmanifestをマージするときに、属性がコンフリクトした場合どちらを採用するかを指定できるっぽい。 参考: Android Studio 6.0 merger fail

AndroidManifest.xmlのandroid:labelがapplicationとactivityの両方にある理由

以下引用。なるほどー。 <application>タグのandroid:label、android:icon 「Settting」‐「Applications」‐「Manage Applications」で表示されるアプリ一覧に表示される <activity>タグのandroid:label、android:icon Androidデスクトップに表示されるアイコンに表示される 参考: A</activity></application>…

Android標準のアイコンを使う

android:background=に続けて@android:drawable/と打って、後は自分が使いたいアイコンに含まれていそうなキーワードを入力すると候補が出てくる。 もしくは↓を使った方が探しやすいかも知れない(自分は使ってません) konifar/android-material-design-ico…

View Hierarchy上で、あるViewより下のViewにTouchEventを送らないようにする

Androidではデフォルトでは複数のViewが重なっている場合、下の方のViewにもTouchEventが送られるようだ。iOSはデフォルトで一番上のViewにしかTouchEventが送られない。 あるView以降TouchEvnetをBlockしたい場合はカスタムViewクラスを作って、以下を実装…

ScrollViewのheightをmatch_parentにしても、高さがcontentと同じになる

ScrollViewのheightを親と同じ高さにしたい場合は android:fillViewport="true" とすればいい。 参考: 【Android】ScrollViewで高さいっぱいに表示(fillViewport)|俺メモ Web時々アプリ | OREMEMO

CharlesでAndroidのSSL通信の中身を確認する

以下手順でSSL通信の中身を見られるようになる。 CharlesのメニューのProxy>SSL Proxy Settings...を選択する Enable SSL Proxyingにチェックをつける addボタンをクリックし、SSL通信するドメインを追加する Charles便利っすわー。 参考: Legacy SSL Proxy…

Android Studio 1.2 beta3でBuild VariantsがずっとLoading...のままになる不具合

原因はAndroid Studio Unit Testプラグインで、これをdisableにすると直った。 でも、これがないと単体テスト実行できないんだよな。。 早く不具合直ったバージョンが出て欲しい。。 参考: https://code.google.com/p/android/issues/detail?id=163314

potatotips#16発表資料(CustomViewTips)

potatotips#16に参加してきました。 発表資料は↓ http://hosokawa0825.github.io/slides/CustomViewTips/#/

build.gradleに「options.encoding = 'UTF-8'」を定義してもWindowsで文字化けする

build.gradleに以下を書いて文字コードをUTF8にしていたが、Robolectricでテスト実行時にテキストファイルを読み込むと文字化けするという現象が起きた。これはWindowsでのみ発生しMacでは文字化けしない。 tasks.withType(JavaCompile) { options.encoding …

Android Studioからビルドすると「Error:Android Gradle Build Target: org.gradle.tooling.GradleConnectionException: Could not execute build using Gradle installation」エラーはclean projectで直る

以下の記事でこのエラーは~/.gradleを削除すると直ると書いたが、メニューのBuild>Clean Projectを実行すると直るっぽい。 2015-03-10 - 日々精進 こっちの方が手間が少なくていいな。

一つのlayout xmlを複数includeした時にViewへの参照を取得する方法

parent.xmlにchild.xmlを複数回includeした場合、同じidのViewが複数できるがそれらへの参照をどうやって取得するか。例は以下。 parent.xml <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> </scrollview>

BundleのValueをすべて見る

デバッグ中にBundleの中身を見たい・・・という場合があるが デバッグウィンドウでbundle#mMapを見てもなぜか例外が発生して見れない。 BundleのkeyはBundle#keySet()で一覧を取得できる。 valueはBundle#getから取得するしかないっぽい。 見づらいけどBundl…

Bundle経由でFragmentにオブジェクトを渡すと参照渡しになる

FragmentAからFragmentBインスタンスを生成するときにBundleにオブジェクトを詰めて渡した場合、一旦SerializeされてFragmentB側でインスタンスが生成されるものだと思っていたが違うらしい。実際は参照が渡されるだけ。 ただし、OSにprocessをkillされた後…