2014年1月31日金曜日

ワイドだろぉ~?

世の中には「物理キー」と「ソフトキー」と呼ばれるものがあります。
「物理キー」は普通のボタンだと思ってください。押してへこんだら作動する昔ながらのスタイル。 指先の感覚で押したことがハッキリわかること、液晶が付いていない状態でも押せること、などがメリット。 故障しやすい、防水が難しくなる、生産コストが高くなる、などがデメリット。
「ソフトキー」は液晶上に表示されるタッチ操作に反応するキーですね。 android 端末では「ホームキー」「バックキー」「メニューキー」が標準的ですね。 メリット・デメリットは「物理キー」の真逆であるといえましょう。
iPhone は「物理キー」ですね。 iPhone のパクリだと言われた GalaxySC-02B なんかも「物理キー」ですね。 2012年以降の android 端末は「ソフトキー」が多いですね。 Google さんは「ソフトキー」を推奨していますね。
以上の予備知識をふまえたうえで下記をお読みください。

普通さあ、800x480 (10:6)と1280x720 (10:5.625 = 16:9)を比べたら、後者の方が横長だと思うじゃないですか。 パソコンや液晶テレビなら文句なく、後者の方が横長のディスプレイなのですが、 ことスマホの世界においては「当たり前が通用しない」。

上の画像は Eclipse のDDMS によるスクリーンショット。800x480。

上の画像は Eclipse のDDMS によるスクリーンショット。1280x720。

上の画像は Eclipse のDDMS によるスクリーンショット。2560x1600(タブレット)。

ちょ、ちょっと待てよ、10:6 のメイン画面の横にソフトキーを配置して、そりゃもちろんソフトキーも液晶の一部だから、 それに異論はないが「ディスプレイのアスペクト比 16:9」ってマジで言ってんのかい。 実質、絵が描画されているエリアは 10:6 じゃないか??? 、 最近の動画はワイド画面の 16:9 が多いのでそれに対応したディスプレイですっ、って嘘言いなさいっ、と思ったら You Tube で LandScape(横向き)にしたらソフトキーの部分も消えて横マックスで絵が表示され、 正真正銘の 16:9 となりました。なるほどぉ

勉強不足でよくわかりませんが、と、いうことはソフトキーを消し去って フル描画させることも可能なのかもしれません。 しかし、そんなことをしたらユーザー様から「ホームキー」「バックキー」「メニューキー」を押すことができなくなるので、 不便きわまりないクソ仕様だと文句の一つも言われることでしょう。

まあソフトキーはいざってときに自らの姿を消すこともできる忍者みたいなやつですよ。 器用ですね、未来的ですね。 その代わり、押しにくい、押しにくい、押しにくい、と世界中でブツブツ文句を言われているみたいです。 どっちがいいとかそういう話ではなく、アプリ製作者としては(知識として、デザインの要素として) 押さえておかなければならない重要なポイントでした、ね?

2014年1月26日日曜日

音の迷宮事件 Xperia と SoundPool

1月冒頭の記事(これの2つ前)で、ディスプレイのアスペクト比が変わったらどうのこうの… と心配していましたが、実機で確認した結果は問題なしでした。
SC-02B(4.0 inch)(800x480 比率1.67倍)
SO-02F(4.3 inch)(1280x720 比率1.78倍)
F-02F(10.1 inch)(2560x1600 比率1.6倍)

LC-20DZ3(20 inch)(1366x768 比率1.78倍)<シャープの液晶LED/TV>
PSP(4.3 inch)(480x272 比率1.76倍)<ポータブルゲーム機>

参考までに家にあったスマートフォン以外のディスプレイも調べてみました。 Xperia は20インチテレビとほぼ同等の解像度。 Arrows のタブレットは余裕で20インチテレビをぶっちぎっています。 まあ、そんなことより重要なのは縦横比が 1.6~1.78倍という限られた範囲で推移しているということです。 android でアプリを作る場合は様々な機種に対応するように配慮しなければなりませんが、 かといって 1200x600 みたいな存在しないケースは無視してしまって構わない。 あくまで実勢の範囲内で適合させていく努力が必要ということです。 まあ、私はまったくやったことありませんが iPhone でのアプリ開発の方がその点では楽勝ですね。

で、機種毎による違いというものはディスプレイ関係だけではすまない。 実際に実機でテストしてみると「はぁ!?」という事態がときどき起こり得ます。 今回は音の問題です。

SoundPool というものを使って効果音をだしていました。 10秒未満な短い音を同時多発的に出していく場合に有効な手段です。 で、去年まではデバッグ用実機としてギャラクシーしかありませんでしたから、それで音が鳴れば「よっしゃよっしゃ」と開発を進めていた次第です。 で、今回 Xperia と Arrows で実機テストを行った際、Arrows では問題なく音が鳴りましたが、 Xperia だと音がちっちゃい。「えっ?」って思いますよね。

そもそも SoundPool で鳴らされる音量はどうやって決まるのか?

streamID = sp.play( seID[1], volLevel, volLevel, 1, 0, 1.2F);

たしかに↑でいうところの volLevel には 0.1~1.0 の変数を入れ込みます。 これによって音量が変わる仕様です。 で、0.1~1.0 まで数値を変えたら出力されるボリュームが段階的に変わるのか? といったら、う~ん、という感じです。 まあ、これはちょっと置いておいて、ベースの音量というものがあります。

sp = new SoundPool( 8, AudioManager.STREAM_MUSIC, 0 );

↑みたいな初期設定を onCreate() あたりで行いますが、STREAM_MUSIC、要するに音楽やゲームで使われる音量がベースとなります。

sp = new SoundPool( 8, AudioManager.STREAM_ALARM, 0 );

↑みたいにすれば、STREAM_ALARM、アラームの音量がベースとなります。 いずれにせよ SoundPool を利用する際は何らかの音源(他には電話音量 STREAM_RING なども)を拠り所にしています。

とりあえず Xperia で音が小さかったので音を大きくしてやろう。 いろいろ試した結果、 play の前に

AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
int max_volume = am.getStreamMaxVolume(AudioManager.STREAM_ALARM);
am.setStreamVolume(AudioManager.STREAM_ALARM, max_volume, 0);

このようにすればアラームの最大音量を取得しセット、それを play に適用しますから大きな音で SoundPool が鳴ります。 なぜ、STREAM_MUSIC ではなく STREAM_ALARM にするかというと、 bgm をメディアプレイヤーで鳴らしており、それの音量が STREAM_MUSIC に由来しているからです。 つまり、STREAM_MUSIC を下手にいじれば bgm に干渉してしまう、だから、STREAM_ALARM を使ってみました。 勝手に(ユーザー端末の)アラーム音量をいじるわけですから、用が済んだら元のアラーム音量に戻しておくのはマナーとして忘れずに。 とにかく、このやり方だと Xperia でも音が大きく鳴りました (最終的にはMAX音量から -1 した値で音量セットするようにしました)。 しかし、Galaxy や Arrows で試したらばかでっかい音が鳴ってしまう。うるせぇ!

本当にいろいろ試しました。試行錯誤といやつでしょうか? まず考えた大筋はユーザーに効果音量を設定させて、 その設定を保存しておく、というものでした。 なにせ、3機種でしか実機テストを行っていませんので、他の端末ではどうなるのかは分かりません。 だから、ユーザー側で任意に調整できるようにしておくのが親切かつフレキシブルだろうと判断しました。 できたら、1~5段階くらいの効果音設定をしたかったのですが、いろいろ試した挙句、
極小<<<<<適音(やや小さめ)<適音<適音(やや大きめ)<<<<<爆音
みたいな感じにしかできなかったので、「強・弱」の2段階設定に落ち着きました。 つまり初期設定は弱であり、Galaxy と Arrows だとこれで普通に効果音が聞こえます。下手に強にしてしまうと 爆音地獄になりますが、すぐにユーザーは元の弱設定に戻すことでしょう。 Xperia だと初期設定ではもろもろの効果音がとても小さく再生されます。 これを強に変えると適当な音量に落ち着きます。

        if(Otsu4Activity.seVolLevel==0) {
            sp = new SoundPool( 8, AudioManager.STREAM_MUSIC, 0 );
        } else {
            sp = new SoundPool( 8, AudioManager.STREAM_ALARM, 0 );
        }
↑こういう感じで強設定なら STREAM_ALARM でいき、弱設定なら STREAM_MUSIC でいきます。 弱設定の場合は道なりで行くので、SoundPool の音量は STREAM_MUSIC に比例します。 つまり、BGM の音量にリンクします。 しかし、STREAM_MUSIC のボリュームが 10以上になると爆音領域に突入するので STREAM_MUSIC のボリュームが 10以上の際はボリューム 9 という扱いにしています。

なかなか仕様書どおりにはいきませんねえ、という話でしたが、 Galaxy と Arrows ではまったく同じ挙動を示したので、 おろらく Xperia 以外の機種だったら弱設定でうまくいくのではなかろうか? と思います。 ググったら Xperia で SoundPool を処理させる場合に不具合がでやすいみたいな記事をいくつか見かけました。 真相は分かりませんが、こういった端末間における(予期せぬ)再現性の違いというものが Android につきものなのは 間違いなく、iPhone でのアプリ開発の方がその点では楽勝ですね。

2014年1月25日土曜日

大苦労、タブレットでUSBデバッグ

毎日毎日、通勤の通り道などで煽りのポスターを見続けたからでしょうか? 時間をかけてジワジワとすっかり洗脳された私は スマホの機種変&&タブレットの新規契約もしてしまいました。 旧機種もシムカードは抜かれるものの返してくれるので、なんと3台ものデバック用実機を持つことになったわけです。
Sumsung SC-02B (Galaxy)
Sony SO-02F (Xperia)
Fujitsu F-02F (Arrows Tab)

それにしても、電話・メール・インターネットという通信機能を失ったスマホは純粋な(?)ゲーム機として生まれ変わりますね。 私の場合は目覚まし時計として旧機種がなお活躍しています。 いや、カメラだってあるし意外と多機能モバイルマシーンな感じですね、シムカードを失っても…。

ちょっと余談ですが、私がSC-02Bを買った3年前は「サムスンの機種が圧倒的に優秀」 「アイフォンと戦えるのはギャラクシーしかいない」という評価であり、 エクスペリア(とその他大勢の日本勢)はもっと頑張れ、という風潮でした。 しかし、最近はソニーエリクソンからソニー直下に開発を移行して、国内のみならず海外でも高い評価を受けているようです、 Xperia が! 実際、性能がそんなに変わらないのなら、防水・防塵ありでメタルボディーの Xperia の方が、 プラスティックボデーの Galaxy よりもいい感じです。

旧が Galaxy SC-02B(Android 2.2)だったのですが、更新した5インチと10インチの新機種たちはともにバージョン 4.2.2 です。 で、USBデバッグの手続きをするのが実に3年ぶりくらいだったので、かなり手こずりました。

まずは携帯電話の Xperia の方からやりましたが、 覚えているのは携帯端末の方で「正体不明のアプリをインストールする」「USBデバッグを行う」の2つを有効にしておくこと。 ただし、どーもデバイスドライバ(PCの方にインストールさせる制御用ソフトウェア)をダウンロードさせないといけないみたいです。 この辺はソニーの機種の場合は、USBでスマホとPCをつないだら勝手にやってくれましたが、 なんかインストール成功?失敗?、よくわからん…という状態が続いてなんかよくわからん(2時間くらい迷った)うちに Eclipse側からの run ができるようになりました。

日をおいて今度は10インチのタブレットの方に挑戦。富士通の Arrows ですね。 で、こっちはいきなりバグった。 と、いうのも「USBデバッグを行う」の項目がいくら探してもでてこない。 ググって調べているうちに Android 4.2 以降? は仕様で初期状態では「開発者オプション」が表示されないみたい。 で、その解除の仕方が「設定」>「タブレット情報」と押していって「ビルド番号」のうえを7回アタタタタタタタッ!と叩いてやると 反応するという嘘のような本当の話。 不思議で仕方ないのが、Xperia のときは最初から「開発者オプション」が表示されていた、ということ。 携帯屋さんの担当者が押したんかな? それともソニーではそうなのか? 謎です。

で、今度はUSBをつないだだけじゃデバイスドライバのインストールがダメっぽい。 なので、ググってみたら富士通のサイトで機種別デバイスドライバ一覧みたいなところへ到達したので、それをPCへダウンロードさせました。 ここまでけっこう時間がかかったので、やっとやっと成功か? と思いきや今度は Eclipse で端末は認識するものの、 unknown offline みたいな困った表示をしてくる始末。 どうも、どうも…、eclipse にインストールしているアンドロイドの情報が古い、っちゅーことみたいですので SDK を更新してみました。 これも素直に成功せず、とりあえず Android 4.2.2(API 17)だけでいいから更新…という方針でやるもうまくいかず、 ものすごい中途半端な更新となりましたが、これによって run が成功しました。

…これでうまくいった。 はずが、どうもおかしい。 いくら eclipse上で内容を更新して上書きしてもスマホ(タブレット)側で内容が更新されない。 一回USB経由でもぐらせたアプリをアンインストールして、再度 eclipse から launch しても内容が前のまま。???

なんかいろいろバグってるなあ、と思って eclipse をいじくったりしているうちに 今度はソース上に問題がないのに、run すると「エラーがあるからダメです」状態に。 そこから tool とかなんとか インストールとかしてみますが、徐々にわけのわからない深みの状態に陥っていき、いらいら!イライラ!!
「そうだ、eclipse を交換しよう」と思い至ってその日は寝ました。

今はなんと、アンドロイドデベロッパー向けパックみたいなやつがあるんですね。
Android SDKとEclipseのインストール Tech Fun これはなんかいいぞ、SDK もセットになっているから、おろらく今後最新版の android に更新しても不具合が生じないはず。 正味、ダウンロードはコミコミなので一発、zip の解凍は時間がかかりましたが、そこから最新版の API なんかをインストするだけ。 最後に古いほうのワークスペースからプロジェクトをインポートして、文字化けあったので、コードを UTF-8 に変えた、 くらいですけども万事解決っぽい。

2014年1月4日土曜日

アンドロイド アスペクト比に悩む

正月が終わってしまう…
正月が…
いまだにギャラクシーの android2.2 のやつを使っているんですが、 これはアスペクト比が 5:3 なんですよね。 で、最近のスマートフォンの主流は 16:9 ということで、私の機種より若干横長になっているという…。 まあ、画面の大きいタブレットに関しては 5:3 より 4:3 に近いものが主流なんですけどね。 基本的に画面のインチ数が大きくなるほど 4:3 に近付いていく風潮のようです。

実機としてさっさと 16:9 のやつに買い変えたらいいのですが、 ちょっと名案を思いついたので、試してみました。 要するに一台のスマホで、異なるアスペクト比での画面表示を確認する方法です。

簡単な話で、Activity で行っている
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
あたりを削除してやればいいんですよね、 // を付けて。 これで、今まで消えていたタイトルバーとステータスバーが画面上部に出現するので、 おのずと表示領域の縦幅が狭くなり、横長のアスペクト比に変化するというわけです。

それで、試してみると案の定、あちこちおかしな画面表示になってしまっています。

上の図のレイアウトは中央部分をとにかく正方形になるように作図して、その余りで四隅の配置を行っています。 この方法だと、アスペクト比が変わっても中央部分はさすがに正方形のままですが、四隅の方は破綻してきます(潰れてしまう)。 ただし、一番下の画像(タイトルバーとステータスバー有)でもギリギリ耐えているのでまあよしとしましょう。

今度のパターンはやばいです。タイトルバーとステータスバー有のバージョンだと右下のステータス表示の一部が見えなくなっています。 私はよく横幅の1/20、みたいな形でフォントサイズを指定しているのですが、文字は横書きなのでレイアウトしやすいわけです。 しかし、このやりかただとアスペクト比によって縦に何行書くことができるか? というところで差異がでてくるわけです。 当然のことながら横長の画面であるほど縦に書ける行数は減ってしまいます。 今ならそう、冷静に分析することができますが作っているときはスッパリ意識していませんでした。 画面レイアウト事態を考え直さないといけない、ようです。

上記以外にもまずいところが複数見つかったので、随時訂正しました。致命傷みたいなのがなかったのは、サスガ今回が処女作じゃないだけの ことはありますが、それにしても android はメンドクサイっすねえ。