プロジェクタを買いました。

エプソンのホームプロジェクタ、EH-TW5350を買いました。

といってもプロジェクタを買うのは初めてではなく二代目。 これまでは2008年に購入したソニーVPL-AW15という機種を使っていました。 さすがに最新のプロジェクタと比べると微妙なスペックですが、これまで使ってきた愛着もあり、年末年始もこいつで映画を見まくるぞ!と思っていたのです。

昼間から遮光カーテンを締め切り、スクリーンを立ち上げ、いざ!と思ってプロジェクタを起動するとジジジ…とノイズ音がするだけで映像が出ません。 プロジェクタの宿命、ランプ切れでした。

ほとんどのプロジェクタは光源として水銀ランプを使用していて、およそ1500〜2000時間ほど利用すると寿命が来ます。 交換用ランプは機種ごとに価格が異なりますが、VPL-AW15の場合は安い互換ランプで15,000円、純正で20,000円くらいでしょうか。 大体2,3年に一度くらいの頻度でこのランプ交換が必要になる上、電気代もTVよりかかるのでプロジェクタのランニングコストは最悪ですね。

ランプ切れを起こしたVPL-AW15は僕が北九州で新卒社員をだったときに少ない給料から毎月少しずつ積み立ててやっと買ったもので、とても愛着がありました。 (当時スクリーンまでは買えなかったので)壁に60インチくらいで映画を投写できたときの喜び。 気休めに買ったペーパースクリーンで壁とは比べ物にならないくらい綺麗に映った時の喜び。 その後ちゃんとしたスクリーンを買ってさらに画質があがったときの喜び。 そういった感動がVPL-AW15のスペック以上に僕を楽しませてくれていたと思います。

2年半前にランプが切れた時は愛着(と当時のフルHDプロジェクタの価格)から買い換えることができませんでしたが、 さすがに2015年になってハーフHDでHDMI端子1個という制限は辛く、フルHDのプロジェクタの低価格化もあって今回は買い換えることなりました。 VPL-AW15への愛着が〜といいながら新機種チェックは怠らなかったので、買い替えの候補はエントリー機として評判の良かったEH-TW5200かその後継機、EH-TW5350の二択。 店舗で実機の映像を見たところ、EH-TW5350から搭載されたフレーム補間機能が気持ち悪いくらいヌルヌル動いて見えるのでEH-TW5350に即決してそのまま購入しました。 その後自宅で色々設定をいじってるうちにフレーム補間はOFFにしましたが、欲しいときにONにできるということが大事なのであったほうが良いです。

自宅でEH-TW5350を設置してまず驚いたのはその明るさです。 スペックでVPL-AW15の2倍の明るさがあることはわかっていましたが、実際に体験すると完全に別物でした。 VPL-AW15が部屋を暗室にして蛍光灯も消さなければほぼスクリーンが見えないのに対して、EH-TW5350は明るさを落とせば蛍光灯がついていてもスクリーンが見えます。 解像度もやっとフルHDになって、80インチのスクリーン本来の性能を活かせるのが嬉しいです。 このスペックのプロジェクタが10万ちょっとで手に入るようになったのは本当に、本当に素晴らしいです。 VPL-AW15も大体同じくらいの価格で買ったので、技術の進歩に驚きました。

もちろん良くなったところだけではなく、レンズシフトがないことからくる設置制限の辛さもあります。 特に打ち上げ角の違いは大きく、同じ場所に置くためには角度を付けて設置する必要がありました。 (プロジェクタに角度をつけて設置すると映像が台形になるため補正作業が必要になり画質が低下するのです) また、投写距離自体は短くなったもののVPL-AW15より調整幅が狭く、いままでよりスクリーンとプロジェクタを近づける必要もありました。

EH-TW5350は高画質の大画面を最短距離で投写することに全力を注いでいて、その思い切りの良さがコスパに繋がっているのだなと感じました。 使い勝手の良かったVPL-AW15とは少し方向性の違うプロジェクタですが、どうにかやっていけそうです。 財布には大ダメージでしたが年末年始の楽しみが増えました。

ランプ切れのVPL-AW15ですが、どうにも捨てることができないので実家に送りつけて保管してもらおうと思っています。 僕の父もCABINのスライドプロジェクタを後生大事に仕舞い込んでいるような人なので、きっとわかってくれるでしょう。 父がスライドプロジェクタで写真を壁に映して見せてくれた時のような感動を、僕もいつかビデオプロジェクタで自分の子供に伝えたいなと思っています。

今年発売されたAndroid端末のdp解像度をまとめた記事を書きました。

「最近は320dpの端末も少なくなっているので…」という話を自分でしながら本当に少なくなっているのかイマイチ確証がなかったので今年も調べて書きました。

ソフトバンクの開発者向けサイトに情報が全然なかったり一部の端末のdpiを調べようとググっても「dpiを変更したら快適になった!」という話しか出てこなかったり心が濁るようなこともあったけど320dp端末は元気です。対応は必須でした。

Android Nで画面分割が来たら300dp対応もしないといけないのかな…。 もうレイアウトをまるごとswXXXdpで分ける時代じゃなくてStaggeredGridLayoutManager#setSpanCount()とかで吸収していく時代なんだなーと思いました。

来年はシームレスに多端末対応していく術も学んでいきたい。

qiita.com

Androidソースコードレビューで指摘する事が多い項目まとめ2

去年Androidソースコードレビューで指摘する事が多い項目まとめという記事を書いた時はアプリ全体を一度に見るような機会が多かったため、内容も大きめのものばかり書いていましたが、最近はプルリクエスト単位でレビューする機会が増えたので細かい項目についてまとめてみようと思います。

ミリ秒で時間を指定する時に自前で計算している

1000L * 60L * 60L * 24Lのようなコード。

TimeUnitを使いましょう。

24時間の場合は以下のように書けます。

TimeUnit.DAYS.toMillis(1L)

ある文字列がhttp/httpsで始まるかチェック

URLUtil.isNetworkUrl()を使いましょう。

ただしequalsIgnoreCaseで判定してます。

ベースURLにパラメータを付与していってURLを生成したい

StringBuilder#append("&key=").append(value);のようなコードをいっぱい書いているようなところ。

Uri.Builderを使って以下のように書けます。

Uri.Builder#appendQueryParameter("key", value);

?&=を意識しなくてよくなり見やすくなります。

LayoutInflater#inflate()のrootがnull

LayoutInflater#inflate()rootを指定しないと適当なLayoutParamsを用意されて見た目が変わる可能性があるので指定しましょう。

nullにすると警告が出るのですぐわかると思います。

ListViewのHeader/FooterのLayoutInflater#inflate()

Header/FooterはItemのViewと同じようにHeaderViewListAdapter#getViewで返されてListViewに追加されるのでListViewをrootとして渡せばOKです。

Viewの間隔を調整するために透明なViewを使っている

できるだけmarginやpaddingで調整しましょう。

どうしてもViewを置いて調整したいときはSpaceを使いましょう。 このViewは描画処理で何もしないので背景色などが指定出来ない代わりに低負荷です。

ListViewの上下端の要素にだけmarginを入れている

大抵はListViewにpaddingTop/paddingBottomを設定してclipToPaddingをfalseにすると解決します。

文字列のベタ書き

文字列リソースにできるものは文字列リソースにしましょう。

ただし、以下に当てはまるものは文字列リソースに向かないのでベタ書きで良いと思っています。

  • ローカライズしてはいけない文字列
    • ログや成果計上に使う文字列など
  • レイアウトファイルのtools:textなどアプリ内では使われない文字列
  • private static final Stringな文字列

AndroidTVでDeployGateを使う

2015/12/18 14:23 追記:

DeployGateからダウンロードできるAPKLEANBACK_LAUNCHERに対応したので以下の内容は不要になりました!


AndroidTVでDeployGate使うためのアプリ作りました。

nein37/deploygate-android-tv · GitHub

AndroidTVでDeployGateアプリが利用できない理由は2つあります。

  1. Playストアのフィルタに引っかかっている
  2. DeployGateアプリがLEANBACK_LAUNCHERに対応するActivityを実装していない

今回作ったアプリではDeployGateが公開しているAPKダウンロードURLから直接APKをダウンロードしてインストールすることで1.を回避し、このアプリが起動された時にDeployGateのLAUNCHERActivityを呼ぶことで2.を回避しています。 その後は全てDeployGateアプリでの動作となりますが、試した限りではD-Padでもほぼ問題ありませんでした。

以上です。

最近Android TVアプリの開発で困ったこと

雑にメモ

Android TVを正確に判定するのが難しい

Android DevelopersのAndroid TV実装ガイドにはTV端末をチェックするという項目があり、 UI_MODE_TYPE_TELEVISIONで判定すればいいよと書いてある。 しかし実際にはUI_MODE_TYPE_TELEVISIONなのにAndroid TVではない端末いくつかあり、自称AndroidTV端末としてチェックをすり抜けてしまう。 特にOSが4.x系でUI_MODE_TYPE_TELEVISIONな端末が曲者で、Android TVだけを想定してコードを書いていると4.x系では存在しないAPIにアクセスしてクラッシュすることがあって非常に辛い。 手元にないので試せていないが、おそらくHDMIスティック系の端末にも自称TV端末があるのではなかろうか。 TV判定のロジックにAPIレベルのチェックを追加するか、TV向けの部分であってもminSdkVersionで動くようにしておいたほうが良さそう。

結局、Android TVってUI_MODE_TYPE_TELEVISIONができたAPI level 13からサポート対象なのか、leanbackライブラリのv17からサポート対象なのか、Android TVそのものができたLollipopからサポート対象なのかよくわからない。

音声検索のマイク権限は外せる

AndroidTVで検索画面を実装する場合、通常はleanbackライブラリのSearchFragment/SearchSupportFragmentを利用する。 このクラスは普通に実装するとRECORD_AUDIO権限が必要だが、SpeechRecognitionCallbackを設定して音声検索をACTION_RECOGNIZE_SPEECHに任せれば権限不要となる。 Android Developers Blogにも書いてあったので多分間違いない。

TVでRuntime permissionsに対応するのはしんどいので、どんどん権限を外していきたい。

Leanbackライブラリの更新で死ぬ

leanback-v17ライブラリを23系にあげたときに、HorizontalGridViewlayout_heightwrap_contentにしているとjava.lang.IllegalStateException: Must specify rowHeight or view heightみたいなエラーを吐いてクラッシュする。 おそらくVerticalGridViewlayout_widthでも似たようなエラーが発生してクラッシュしそう。 メッセージの通り高さ/幅を指定すればクラッシュしなくなる。

最近気になっているGoogle Play Servicesの機能

Google Play Services7.5、7.8で素敵な新機能がいっぱい追加されたけど全然追いつけていないのでメモだけ…。

Nearby

Nearbyは近くにあるAndroid/iOS端末同士でやりとりすることができる機能です。 メールやSMS、QRコードなどを介することなく接続できるので、アカウントを知る必要も別にアプリを入れる必要もなくやりとりすることができます。

Trelloというタスク管理アプリではNearbyを使って簡単にボード(タスクリストのようなもの)が共有できるようになってました。

以下はTrelloでNearby接続を開始した時に表示される確認ダイアログです。 耳に聞こえないペア設定コードと表現されていますが、端末によってはわりと大きめの音でジジジジ…と鳴り不快でした…。

f:id:nein37:20150901150332p:plain:w300

Smart Lock for Passwords on Android

Smart Lock for PasswordsはChromeでWebサイトにログインしたときにIDやパスワードを保存し、再ログイン時に入力補完してくれる機能です。 Google Play Services 7.5からAndroidアプリでも同じ機能が使えるようになりました

Smart Lock(略)を使ってアプリでのログイン時に認証情報をGoogleサーバーに保存しておくことで、次回のログイン時に自動ログインや入力補完させることができます。 また、Chrome側の認証情報管理と同じ仕組みで動いているため、アプリとWebサービスの紐付けをしておけばどちらか一方で保存した認証情報を他方で利用することもできるようになります。

NetflixAndroidアプリが完全対応していて、前もってWebで認証情報を保存しておくとアプリをインストールして起動した直後に自動的にログインという最高のユーザー体験!という感じでした。

サンプルアプリで認証情報を保存するときの確認ダイアログ

f:id:nein37:20150901151526p:plain:w300

認証情報を取得したときの表示(下部の青い帯。右端のgマークは消せない…)

f:id:nein37:20150901151550p:plain:w300

App Invites(Beta)

App Invitesはメールアプリなどを経由せずに直接アプリの中で送信先を選んで招待メッセージを送信することができる機能です。 招待メッセージを開くとアプリの説明とInstallボタンがあり、このボタンを押下すると対象アプリを未インストールの場合はPlayストア( iTunes App Store)に遷移、インストール済みの場合は対象アプリが起動します。 招待メッセージにディープリンクを埋め込むことができるので、「指定したページでアプリを起動」という挙動もできます。

Yummlyという海外のレシピアプリが導入していたので、動作確認しました。

レシピ詳細で共有先から「Share via Yummly」を選ぶとメッセージの送信先選択画面が表示されます。 タイトル部分は編集可能、複数の宛先が選択可能なようでした。

f:id:nein37:20150901150432p:plain

そのまま送信すると、相手にはこんな感じでアプリの紹介メッセージが届きます。 「Install」を押すとPlayストアへ遷移、またはアプリが起動して共有されたレシピを表示します。

f:id:nein37:20150901150439p:plain