CamTwistを使ってAndroidEmulatorのカメラソースをPC画面にする
バーコード読み取り機能を作る場合などにいちいち実機でバーコードをスキャンするのが面倒臭かったのでなんとかPCに表示した画像をエミュレータのカメラソースにできないか調べてみました
CamTwist
CamTwistはニコニコ生放送やTwitchなどで配信する時に、Webカメラの映像ではなく、PC画面を映像のソースとして配信するためのソフトです。エミュレータではWebカメラや内臓カメラをソースとして使えますが、同じようにCamTwistの映像も使うことができます
以下の方法はCamTwist以外にも同じ機能をもったソフトであれば有効だと思います
設定方法
CamTwist
CamTwistをダウンロードページからダウンロードしてインストールします
CamTwistの設定は、以下のようにします
- Desktop (範囲は任意)
- Rotation Translation(任意)
- Zoom(任意)
エミュレータで表示した時に画像が回転した状態で表示されていたらRotationを設定してみてください
AVD
- エミュレータの設定画面から
Show Advanced Settings
を押す - Cameraの設定をwebcam0にする
- 設定を保存
以上で設定は終了です
エミュレータ起動
エミュレータでカメラアプリを起動して確認してみます
以下のようにCamTwistで指定した範囲の映像が表示されていればOKです
おまけ webcam0について
Macではもともと内臓カメラがついている端末がほとんどだと思いますが、エミュレータの設定では内臓カメラやCamTwistなどの映像ソースが複数ある場合でもwebcam0しか選択することができません(AndroidStudioのエミュレータ設定ではカメラがあろうがなかろうがNone, Emulated, Webcam0の3つのみ選択できるようになっているようです)。
そのため、環境によっては内臓カメラの映像が自動的に選択されてしまうかもしれません。
emulatorコマンド Commonly used optionsを見た限りではemulatorコマンドからエミュレータを起動する際にどの映像ソースを使うかを選択できそうですが、カメラ一覧を取得してもwebcam0しか表示されず任意の映像ソースを選択する方法はわかりませんでした。
FCMを使ってAndroid端末へ通知を送るスクリプト
Firebase Cloud Messaging(FCM)を使ってAndroid端末へ通知を送るスクリプトを作りました(iOSは非対応です)
スクリプト内で送られているデータはcurlを使う場合を参照してください
作成したスクリプト
ソースコードは https://github.com/sckm/fcm-send にあがっています
インストール
あらかじめgoがインストールされている必要があります
$ go get github.com/sckm/fcm-send
使い方
以下のように、はじめにjsonのdataキーで送りたい内容をファイルに書いておきます
{ "message": "Hello World!", "title": "example title" }
その後、以下のコマンドを実行することで通知が送られます
$ token='registration token' $ server_key='your server key' $ fcm-send -t $token -s $server_key -p data.json
curlを使う場合
作成したスクリプトは以下のcurlコマンドと同等のリクエストを送っています
token='registration token' server_key='your server key' msg='{"message":"Hello World!", "title": "example title"}' curl \ --header "Authorization: key=${server_key}" \ --header Content-Type:"application/json" \ https://fcm.googleapis.com/fcm/send \ -d "{ \"to\" : \"${token}\", \"data\": $msg }"
FirebaseCrashReportingにmappingファイルをあげるスクリプトを作った
FirebaseCrashReportingにAndroidのマッピングファイルをあげる際に相対パスが使えなかったり、google-services.jsonがapp直下にない時にAppIdなどを指定するのが面倒くさかったのでgolangでスクリプトを作ってみました
ソースコードは https://github.com/sckm/fcr-upload-mapping
動作環境
- あらかじめgoがインストールされている必要があります
- Mac OS X El Capitan以外では動作を確認していないです
- 内部でfirebase-crashプラグインで生成されるコマンドを使っているのでプラグインを適用する必要があります(バージョン1.0.5以上)
Uploading ProGuard mapping files with Gradle
インストール
go get github.com/sckm/fcr-upload-mapping
使い方
cd [Androidプロジェクトのルートパス] fcr-upload-mapping \ -a [サービスアカウントキーファイルのパス] \ -c [アプリバージョンコード] \ -p [パッケージ名] \ -m [マッピングファイルのパス] \ -s [google-services.jsonのパス]
google-services.jsonがapp直下にある場合は省略可能です
その他
今はgradlewがあるディレクトリでしか動かないようになっていたり、引数の説明が足りないので修正したい
Golangに慣れていないのでコードが汚い・・・
RxJava2のSingle.zipのエラー処理ではまった話
問題
RxJavaでたまにonErrorReturnItem
などでエラー処理をしていてもたまにエラーがすり抜けてきてアプリが落ちてしまうことがあった
問題となっていそうな部分を簡単に表すと以下のようになっていた
Single.zip( Single Single ) .onErrorReturnItem
対処方法
RxJavaのissuesを調べてみると同じ問題があった
Rx2: Multiple errors in zip'ed observables throw exception
ここに書いてある対処方法は、
RxJavaPlugins.setErrorHandler()
でエラーハンドラーを設定する(issueのコメントではsetOnError
になっているが名前が変更になった?)- zipの中のSingleで
onErrorReturn
やonErrorResumeNext
などを呼び出す
いっけん良さそうに見えるので原因がわかりづらくてはまってしまった
実際にはどうしてそうなってしまうのかまだわかっていないのでRxJavaの実装を読んでいきたい
文字列リソースに複数の値を渡す
基本的な方法
複数の値を渡す際には%1$s
や%2$s
などを設定する。
1や2で何番目の引数を使うかを指定する
<string name="string_res1">1番目%1$s 2番目%2$s"</string>
getString(R.string.string_res1, "A", "B") 結果: 1番目A 2番目B
渡した値の一部を使わない場合
引数で複数の値を渡すが文字列リソースで使わない場合の挙動
<string name="string_res2">2番目のみ%2$s"</string>
getString(R.string.string_res2, "A", "B") 結果: 2番目のみB
特に問題なく文字列が取得できる
必要以上に値を渡した場合
1番目の引数のみ使う文字列リソースに2つの値を渡した場合
<string name="string_res3">1番目%1$s"</string>
getString(R.string.string_res3, "A", "B") 結果: 1番目A
実行時には問題なく文字列が取得できる
ただしlintでの警告がでる
values-ja/strings.xml
を作成して日本語の場合に2つの値を使うようにしても警告がでた
DataBindingでincludeしたレイアウトに値を渡す メモ
AndroidのDataBindingでincludeしたレイアウトに値を渡す時に少し悩んだのでメモ
変数の渡し方法
includeされるファイルが以下のような時
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:bind="http://schemas.android.com/apk/res-auto"> <data> <variable name="user1" type="com.example.User"/> </data> <merge> <include layout="@layout/name" bind:user="@{user1}"/> <include layout="@layout/contact" bind:user="@{user1}"/> </merge> </layout>
includeする側のレイアウトではbind:hoge
属性を使って変数を渡すことができる
hoge
の部分にはlayout
で指定したファイル内の変数名を指定する(今回の場合はuser1)
<data> <variable name="user2" type="com.example.User"/> </data> <LinearLayout ...> <include layout="@layout/name" bind:user1="@{user2}"/ </LinearLayout>
参考にした公式サイトの情報ではbind:user="@{user}"
となっていてすこしわかりづらいですね・・・
リソースファイルの値を渡す方法
もし、includeするlayoutにリソースファイルの値を渡したい時の例
例: Stringの値を受け取ることができるレイアウトファイル
"@{@string/app_name}"
のように指定すると良い
<data> <variable name="title" type="String"/> </data>
<include layout="@layout/layout_text" bind:title="@{@string/app_name}" />
Backgroundに設定した画像を拡大させない方法
AndroidのViewのbackgroundに画像を設定した場合にViewのサイズに合わせて画像も拡大されます
通常は特に問題ないのですがどうしても画像を拡大させたくない場合がある時の対処方法を紹介します
今回は24x24dpの以下のような画像を使いました (AndroidStudioのImageAssetで作りました)
画像サイズを維持するDrawableを作成する
以下のようなDrawableファイルを使うことで画像サイズを維持するDrawableを作成することが可能になります
<?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:gravity="center" android:src="@drawable/ic_weekend"/>
最低限必要なのはsrc
のみで表示したい画像を設定します
gravity
を設定することで表示位置を変更できます
実際の表示
以下のようなレイアウトを設定して表示を確認してみます
48x48dpと12x12dpの2通り
<View android:layout_width="48dp" android:layout_height="48dp" android:background="@drawable/ic_weekend" /> <View android:layout_width="48dp" android:layout_height="48dp" android:background="@drawable/no_scale_ic_weekend" /> <View android:layout_width="12dp" android:layout_height="12dp" android:background="@drawable/ic_weekend" /> <View android:layout_width="12dp" android:layout_height="12dp" android:background="@drawable/no_scale_ic_weekend" />
2,4番目が今回作った、サイズを維持するdrawableを表示した場合です
1番目は拡大されて表示していますが2番目では期待通り24x24dpの表示になっています
おまけですが12x12dpの場合も見てみました
ただの画像を表示した場合はサイズに合わせて縮小されていますが、今回つくってDrawableでは一部分のみしか表示されていませんでした
まとめ
固定画像のサイズをViewのBackgroundに設定する際にはbitmap要素のDrawableファイルを作成すると良いようです
画像サイズより大きいViewのbackgroundに画像を表示する場合は問題ないですが、
小さいViewに設定する際には一部分のみしか表示されないので注意する必要があります