December 5, 2012

NFCでワンタッチ接続できるスピーカー

NFCでワンタッチ接続できるBluetoothスピーカー、ヘッドホン系をまとめてみました。

NFCを搭載しているAndroid端末であればSONY系の端末だけでなく、NFCを使ってワンタッチするだけでBluetoothの接続が完了します。いままでのように初回だけとはいえBluetoothのペアリングがワンタッチするだけで接続できるのは簡単かつ便利です。Bluetooth機器をみんなで使い回したい場合でもちゅうちょしなくなります。

NFC + Bluetoothヘッドホン



NFC + Bluetoothスピーカー



ワンタッチ接続対応するにはアプリをインストールする必要があります。

NFC簡単接続
Sony Corporation


BACKキーで確認画面を表示する

BACKキーを押すと通常はそのActivityを終了して前のActivityに戻るといった動作をしますが、例えば、データ入力をするActivityでBACKキーを押されたとき、ポップアップを表示して入力をキャンセルして本当に前の画面に戻るかどうか促す、というUIにしたいときがあります。こういう処理をしたいときは、BACKキーのイベントをオーバーライドすることで自由に制御を変更して対応することができます。

例:BACKキーをおされたときにポップアップを表示してキャンセルか続行か促す




まずは、バックキーのイベントを取得して、ポップアップダイアログを表示します。ダイアログの結果を受け取って、キャンセルならfinish()でActivityを終了します。そうでなければ何もしません。

    @Override
    public boolean onKeyDown (int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            showAlert(mContext, new OnMyAlert() {
                @Override
                public void onResult(boolean isYes) {
                    if (isYes) {
                        finish();
                    }
                }
            });
        }
        return false;
    }

ポップアップダイアログを表示するメソッドです。Yes/Noの2つのボタンを表示して、結果を返します。

    private void showAlert(Context context, final OnMyAlert onMyAlert) {
        // Build
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(R.string.warning);
        builder.setMessage(R.string.mes_warn_cancel);
        // Left button
        builder.setPositiveButton(R.string.answer_no, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                onMyAlert.onResult(false);
            }
        });
        // Right button
        builder.setNegativeButton(R.string.answer_yes, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                onMyAlert.onResult(true);
            }
        });
        // Show
        builder.create().show();
    }

結果を渡すためのインターフェースです。

public interface OnMyAlert {
    public abstract void onResult(boolean isYes);
}

December 3, 2012

Intentにオブジェクトを付加して送信する

Intentを送るとき、さまざまな情報(intやStringなど)を付加することができますが、自分で作ったクラスのオブジェクトそのものを付加することもできます。

ただし、どんなクラスでも付加できるわけではなく、条件としてそのクラスがSerializableインターフェースを実装している必要があります。もちろんクラス内部のメンバー変数もすべてSerializableを実装したクラス、またはintなどのプリミティブである必要があります。

Serializableへの対応は特殊な使い方をしない限り、特に必須で実装するものはありません。通常は"implements Serializable"をクラスに追加し、serialVersionUIDを定義するだけです(eclipseで自動生成できます)。このUIDの値も気にする必要はありません。

例:クラスの定義
public class SampleClass implements Serializable {
    private static final long serialVersionUID = 1L;

例:intentを送る
public class SampleClass implements Serializable {
    SampleClass sample = new SampleClass();
    Intent intent = new Intent(getApplicationContext(), MyActivity.class);
    intent.putExtra("Foo", sample);
    startActivity(intent);

例:intentを受ける
    SampleClass sample = (SampleClass) getIntent().getSerializableExtra("Foo");

オブジェクトを送ることができると書きましたが、送り側と受け手側で同じ中身のオブジェクトが受け取れるという意味で、インスタンスは異なります。

参考:Android Developers:Serializable
参考:Android Developers:Intent

CharSequenceとStringの関係

コードの中で文字列の定義は通常Stringを使うと思いますが、UI系のメソッドをみると、文字列の受け取り側は大抵はStringでなくCharSequenceだったりします。が、Stringをそのまま渡すことができるので、その関係を整理してみました。

CharSequenceはインターフェースです。メソッドを見ると文字列を制御するための最小限のみ定義されています。Android Developersで確認すると多くのクラスがこれを実装しているのがわかります。


StringもCharSequenceを実装しているクラスなので、そのまま渡せるというわけです。


参考:Android Developers:CharSequence
参考:Android Developers:String

stringリソースからString文字列を取得する

文字列は通常はstringリソースファイルに記述します。このときリソースidであれば、R.string.XXXで直接取得できますが、文字列を取得する場合は、ContextにあるgetString(int resId)を使って取得します。

例:
getString(R.string.sample)

参考:Android Developers:Content - getString

November 28, 2012

スクリーンのON/OFFイベントを検出する


スクリーン(LCD)のON/OFFイベントを検出する方法です。

スクリーンのON/OFFはシステムからBroadcast intentで飛んできますので、それを取得することで対応できます。受信するにはIntentFilterに取得したいIntent(この場合はACTION_SCREEN_OFF)を指定してBroadcast receiverを登録します。例ではOFFの1つだけですが、複数登録することももちろんできます。Activityが有効な間受信したい場合はonCreateで登録し、onDestroyで解除します。受信するとBroadcastReceiverのonReceiveがコールされます。

例)ActivityでスクリーンOFFを検出します

public class SampleAppActivity extends Activity {
    private BroadcastReceiver screenStatusReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // Receive screen off
            if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                // OFF
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Register a receiver to receive screen status updates
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        registerReceiver(screenStatusReceiver, filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Unregister a receiver
        unregisterReceiver(screenStatusReceiver);
    }
}

参考:Android Developers:BroadcastReceiver

November 27, 2012

LTE速度でソフトバンク“独り勝ち”???

ちょっと気になったので。

SankeiBiz(産経新聞のサイト)でこんな見出しの記事(2012.11.26)をみました。
「LTE速度でソフトバンク“独り勝ち” ドコモは一度つながれば安定感抜群」

え??本当に??
なんとなく世間の評判的にはLTEはauが一番速そうな感じだけど...
と思って記事をよく読んでみました。

調査したところはICT総研で、元ネタは
「2012年11月6日 全国200地点 スマートフォンLTE通信速度実測調査」
のよう。

しかし調査内容を見ると、ドコモのGalaxy SIII、auのiPhone5、ソフトバンクのiPhone5のわずか3機種でしか調査してない!しかもauはiPhone5って・・・

スマートフォンLTE調査とうたっておきながら、auは2GHz帯のiPhone5のみで、androidが対応している(そしてauが一番力をいれていると思われる)800MHz帯や1.5GHz帯は一切計測していない・・・

ソフトバンクもiPhoneの4G LTEだけでなく4Gもあるのですが、そちらも計測なし。

つまり日本のキャリアの対応しているLTEの周波数帯をまったくカバーできていない調査結果。auのLTE対応androidとソフトバンクの4G対応のスマホもいれて、せめて計5機種でやらないとスマホのLTEの調査とはいえないのでは・・・これを堂々とスマホのLTE速度調査と銘打って公表するってのはどうかと・・・

auとソフトバンクのiPhone5 LTE速度調査、xiは参考までに、みたいな調査だったらこれでも良いですけどね。

こんないい加減な内容でソフトバンクが1番だとかいってると、まるで実際に計測したらソフトバンクが1番でしたみたいな結果をだしたい意図があるのではと勘ぐりたくなってしまう・・・

MMD研究所が調査した結果のほうが公平かつ現実に近い気がします。
【2012年秋冬最新Android端末】4G/LTEのスピード、つながり易さともにau

November 20, 2012

Xperia VLでBluetoothを使う

Xperia VLでBluetoothを使ってみました。

iPhoneで愛用していたREUDOの折りたたみ式BTキーボード(US)RBK-2200BTiと、Sony EricssonのヘッドフォンMW600で同時接続。どっちもマルチペアリング対応なので兼用できます。


キーボードはiPhoneとAndroidで接続の仕方が異なっているのに気づかず苦労しました。メーカーのページを見るとファームウェアのバージョンによって変わると解説があり、それに従えば簡単に接続できました。もちろんHIDプロファイルで接続。詳しくはここを参照
iPhoneより大きいので台座が安定しているかと気になりましたが、特に問題なし!

ただiPhone用に買ったものだったのでUS配列キーボード、そしてPOBoxはJIS配列のキーボードに対応していて記号の一部が刻印とあわない・・・キーボード設定もなさそうで・・・刻印気にしなければ平気だけどね。日本語と英語の切り替えもShift+チルダでBluetooth設定のキーと隣合わせなのでたまに押し間違えたりしてこのへん厳しい。
素直にJIS配列を買えば刻印どおり使えていいんだけどね。

November 18, 2012

Xperia VLのベンチマーク結果

Xpeira VLで有名そうな(雑誌系で使われていた)ベンチマークで測定してみました。

Xperia VLのスペック
- QualcommのMSM8960
- CPU : デュアルコア 1.5GHz
- GPU : Adreno 225、OpenGL ES 2.0
- Memory : LP-DDR2 デュアルチャンネル、クロック不明(チップ的最大は500MHzらしいが)

★Quadrant Standard

Quadrant Standard Edition
Aurora Softworks




Tegra3のクアッドコアを搭載したHTC One X(1.5GHz)やAsus TF201(1.3GHz)と比較するとCPUの計算は負けるが、メモリの転送速度はかなり速い、また雑誌で計測していた同スペックのドコモのGalaxy SIII(SC-06D)よりも高い数値がでました。デュアルとクアッドでそんなに差がでていないのは、Tegra3はクアッドコアだけどCPUアーキテクチャがCortex-A9、MSM8960はデュアルコアだけどCortex-A15相当のKraitなので、そのへんの差がでている気がします。


★AnTuTu 安兎兎ベンチマーク





デュアルとクアッドで顕著な差がでた結果。ただし同じデュアルの機種の中ではかなり高い数値のようです。Galaxy SIII(SC-06D)の結果はこちら


★NenaMark2

NenaMark2
Nena Innovation AB




GPUの速度計算。60fpsに達しておりベンチマークの負荷がもはや軽すぎて上限に達してしまっている気が・・・


★Vellamo

Vellamo Mobile Benchmark
Qualcomm iSkoot, Inc.




Qualcomm製のHTML5のベンチマーク。クアッドコアとの差がでていないのは、あまり性能が生かせないってことなんだろうか。


なんとなく総評。過去の雑誌のベンチマーク記事を見ると、デュアルコア機ではほぼ最高の数値が出ている気がします。

- クアッドコアスマホARROWSの最新実機でベンチマークテスト12本実施
第4回 ベンチマークスコアが高い/メモリ容量が大きい機種は?――冬春モデル(2011)

最新クアッドコアとの比較。Optimus Gは、MSM8960の後継APQ8064でクアッドコアの1.5GHz、GPUはAdreno320を搭載しており、チップ自体は大幅に高速になっているはずです。

- Optimus Gベンチ緊急実施:全部入りクアッドコアは国内最速だ!
最新クアッドコアCPU搭載スマホ「Optimus G」を使ってみた!

が、結果を見るとすべてのベンチマークで速くなっているわけではなく、クアッドコアが生きるようにロジックを組んでいるベンチマークだけ速い感じに思えます。実際のアプリでもそんな生かせるようなコードを作れる人がどこまででてくるかはちょっと疑問かな・・・。シングルスレッドでただ計算するだけのベンチマークではデュアルもクアッドもないので純粋にCPUアーキテクチャとクロックだけの性能におちついてしまう気が・・・そしてGPUの性能がまったくあがっていない結果にもベンチマークの処理に疑問が・・・PCの世界と同じように所詮はベンチマークであり、あまり実践的な結果ではないかなと・・・

クアッドコアとかコア数が増えるよりも瞬間的なクロックブーストとかCPUのアーキテクチャ改善、メモリ高速化のほうがほとんどのアプリには実は効果がありそうと思う今日このごろ。

November 17, 2012

auスマートパス解約

キャッシュバック1000円に釣られて加入してみたものの、やっぱり不要だなと思い2週間使用して解約。説明によると初月は無料、翌月から料金がかかるらしいが、初月に途中退会しても最低の400円はかかるらしい。ということで実質600円のキャッシュバック。全く加入しないよりも、1ヶ月だけ加入したほうが安いんだから、auスマートパス300万人突破とかいわれても・・・そりゃみんな加入するでしょ・・・

解約方法は簡単で、auスマートパスを起動、右下に「会員登録・退会」とあるので、そこからクリック進めていけば1分とかからず退会できます。


auスマートパスでダウンロードしたアプリは即アンインストールされました。ただショートカット状態(auマーケットからダウンロードしますか?と聞いてくるタイプ)のダウンロードしていないアプリは退会しても消えなかったので、手動で削除。関連するウィジェットも手動で削除。auスマートパスももはや不要なのだけど消せなかった・・・。うたパスは消せないが、ビデオパスは消せる、なんか不思議。auものは全部端によせてみました。


November 16, 2012

au LTEの通信速度と範囲

Xperia VLでau LTEの通信速度をよく使う都内近郊2カ所で計測してみました。



800MHz帯を使っているだけあって本当によくLTE電波入ります。SBでiPhoneのころはちょいちょい途切れていた電車での移動中でも継続して電波が良く入ります。人の多い駅でレスポンスガタ落ちだったところも、au LTEに変えたらレスポンスも転送速度も有線接続かと思うほど快適に!Xiは混雑して遅いし、SBは電波悪いし、でau LTEは現状最強環境だと思います。この状況ができるだけ長く続くことを願っています。幸いiPhone5が2GHz帯しか使えないので、しばらくは快適環境が継続すると期待中。

au LTEエリアマップを見るとかなり広範囲ですね。

November 11, 2012

Xperia VLの液晶が黄色がかっている

購入したXperia VLですが、液晶が黄色がかっていました。正常に発色しているLCDディスプレイと比べると明らかに黄色いです。黄色というか緑かな。。。


Xperia Sで公式に不具合と認められたこともあり、様子を見ながら対応を考えようかなと。。。あまり真っ白な画面を見る機会はそんなにないので、通常はそこまで気にならないのですが、全白にしてしまうと、ちょっといただけないです。

この問題はiPhoneでも頻発してたようですね。「yellow tint」でググると海外からもザクザク問題が報告されています・・・

#追記
・・・と思っていたのですが、バックライトを明るくしたらかなり白くなりました。普段自分が使っているバックライト(60%+オート調整有り)が暗めだったので、70%にしたら、かなり良くなりました!これなら十分。

Xperia VLのWiFi速度

Xperia VLのWiFi速度を計測してみました。

環境はauひかり(100Mbps)、WiFiルーターはAterm WR8750N、300Mbpsの5GHz / 11nで接続、計測はRBB Todayスピードテストアプリを使用。




結果はこちら。


WiFi AnalyzerアプリでWiFi環境を測定するとひかり対応マンションもあって2.4GHz帯の使用率が激しい。実際、端末のアンテナもフラフラしてます。


ところが、5GHzにすると!自分のみ。アンテナもバッチリ安定!


ちなみに5GHzを使いたくて今回WiFiルーターを買い替えたのですが、それまで使っていたCoregaの54Mbpsの2.4GHz / 11g接続で同様に測定したら、こんな結果でした。


今回使用したWiFiルーター。5GHzと2.4GHz同時使用、アンテナレスですっきりしている。上位機種に450Mbpsもあるが、Android端末だけを考えるなら現状はオーバースペックなので、これで十分。端末を買い替えるであろう2年後にきっと11ac対応とかで600Mbpsオーバーへ買い替えると予想。

November 10, 2012

Xperia拡張機能の開発EDKのインストール

Xpeiraに搭載されているアプリの拡張機能を開発するためにEDKというものがSony Mobileからリリースされています。このEDKを使うことで、拡張機能のためのAPIを利用することができます。エミュレータもついています。

現在対応している拡張機能は下記になります。
- TimeScapeの拡張
- WALKMANのInfiniteボタン機能の拡張
- SmartWatch、Smart Wireless Headsetの開発

インストール方法です。すでにAndroid開発環境が整っている状態とします。

EclipseからAndroid SDK Managerを起動し、Android 2.3.3 (API10)にSony Xperia Extensions EDK 2.0がありますので、それをインストールします。


エミュレータをAVD Managerで作成します。TargetにEDK 2.0がありますので、それを使って作成します。


起動するとこんな感じです。



チュートリアルやサンプルコードは公式開発サイト(英語のみ)から取得できます。

Xperia VLのオーディオ技術

Xperia VLにはたくさんのSONYのオーディオ技術が入っているのでまとめてみました。音質を調整するときに役立てば。

★ClearAudio+(クリアオーディオプラス)
SONY最新のオーディオ技術です。これまで使われていたClearBase、ClearPhase、ClearStereo、xLoudに加えてS-Forceも追加し、それら全ての技術を使ってXperia VLにあわせてSONYが最適と思える音質にチューニングしたものです。デフォルトはOFFなので、SONYのオススメの音質で聞きたい人は迷わずONすべきものです!

★VPT
SONYのサラウンド技術です。ステレオでのみ有効な技術なので、ステレオヘッドフォン使用時のみ有効になります。OFF、スタジオ、クラブ、コンサートホールの4種類プリセットされています。はっきり音質が異なるタイプで実用的なものが用意されていて、うまくまとまってる感じです。サラウンドが好きな人はオススメです。

★ClearStreo(クリアステレオ)
ステレオの左右の音声が実はお互いに干渉して漏れてしまっている(LにはRが、RにはLが少し漏れて混ざっている)音を、信号処理で打ち消して本来の左右独立したステレオサウンドを再生する技術です。ONにしない選択肢はないと思います。ちなみに有線での技術なのでBluetooth接続では効果はないはず...

★ClearPhase(クリアフェーズ)
音響特性を変化させる技術です。スピーカーが持っている固有の周波数特性を理想的な特性に変化させるのに使います。Xperia VLでは内蔵スピーカーにあわせてチューニングされていますので、内蔵スピーカーの時のみ有効になります。

★ClearBass(クリアベース)
重低音を調整する技術です。

★xLOUD(エックスラウド)
スピーカーの再生音レベルを強調する技術です。迫力のある大きな音に変化します。

★イコライザー
周波数帯ごとに音の強弱を設定する技術です。強調したければ+方向へ、逆ならー方向へ。周波数が低い方が低音、高い方が高音です。プリセットもロック、ポップス、ジャズなど8種類登録されています。

★ダイナミックノーマライザー
曲同士での音量レベルを揃えます。曲ごとに音量レベルが異なるとき、音が大きくなったり、小さくなったりすることがなくなります。録音時にきちんと調整しているなら不要です。

デフォルトで音楽プレイヤーアプリはWALKMANとLISMO Playerの2つありますが、音質設定が共通化されていません。。。イコライザーの設定は独立になっていたり、ClearAudio+はWALKMANでしか設定できなかったり、とかチグハグな感じです。少なくとも音質だけはWALKMANで設定して、他のプレイヤーでは設定しない、という使い方が良さそうです。

November 7, 2012

au Cloudへ写真のアップロード

au Cloudへ写真をアップロードする方法です。

使うにはauスマートパスに加入している必要があります。月額390円で50GBのストレージも提供されるので、iCloudと比較するとだいぶお値打ち感を感じます。50GBだとざっくり1万枚以上は保存できそうです。追加は10GB / 105円。

写真のアップロードはごく簡単で、au Marketからau Cloudアプリをダウンロードして実行するだけでOKです。後は写真をとれば自動でau Cloudにアップロードされます。ただしアップロードはWiFiに接続されたときだけに制限されています。自宅のWiFiだけといった設定も可能で、外出先のWiFiで突然アップロードが始まることもなく、なかなか使い勝手は良いです。

au Cloudはau IDで管理されていてアップロードされた写真はandroidアプリでもPCのブラウザからでもアクセスできます。ブラウザからアクセスするとこんな感じ。


ダウンロード、アルバム、スライドショーなど一通りの機能もそろっています。

au Cloudに対応したアプリ(Viewerとか)もいろいろリリースされており、au Marketからメニュー、au Cloud、連携アプリと選択すると、対応アプリ一覧が見れます。


au Cloudにアップロードされた写真を使いたいとき、au Cloudに対応していないアプリの場合は直接参照できないため、Photo Albumなど対応しているアプリから他のアプリに送信する形になります。無改造でどのアプリからでも参照できる作りになっていたらもっと便利なんですけどね。

November 5, 2012

Xperia VLの初期状態

Xperia VLの初期状態です。参考までに。

Androidのバージョン


RAM(プロセス)の使用状況。だいたい360MBの空き。


ROM(アプリ)の使用状況


ROM(ストレージ)の使用状況


ホームスクリーン


アプリケーション


November 4, 2012

Androidにオリジナル着信音、アラーム音、通知音を作成して設定

Androidにオリジナル着信音、アラーム音、通知音を作成して設定する方法です。
(ここではAndroidはXperia VLを使っています。それ以外の端末でうまくいくかは知りません。)

オリジナル音の作成は、iTunesライブラリにある曲からMacのGarageBandを使って作成します。作り方はiPhoneの着信音の作り方とほぼ同じです。

1. GarageBandを起動し、新規作成でiPhone着信音 - Example Ringtoneを選択


2. iTunesから曲をドラッグドロップしてトラックを追加する(曲を右クリックしてFinderで表示を選択し、Finderからドラッグドロップする)

3. もとからあったサンプルのトラック1は不要なので削除する

4. 一番上の黄色い帯をループさせたい範囲に配置する。iPhoneと違って曲の長さに制限がない。

5. マスター音量を表示させ、フェードイン、フェードアウトを設定する


6. 「共有 - 曲をディスクに書き出し」を実行し、圧縮方法にMP3を選択して保存する

7. Androidのルートフォルダに着信音なら"Ringtones"、アラーム音なら"Alarms"、通知音なら"Notifications"フォルダに作成したMP3ファイルをおく

8. Androidから音設定をするとき、サウンドピッカーを選択すると、作成したMP3ファイルが見えるので、そこで設定すれば完了!



ちなみにiPhone用に作成した着信音もフォーマットは.m4rですがwindows7でandroidのフォルダにおくときMP3へフォーマット変換するかダイアログが表示されるので、単純にm4rをドラッグドロップしてMP3に変換して置けば再利用できます。

MacとXperiaでUSBファイル転送

MacとXperia VLをUSBでつないでファイル転送する方法です。

WindowsであればそのままUSBドライブとして見れるのですが、Macの場合はドライブがでてきません。なぜならデフォルトのUSB接続モードはMTP(Media Transfer Protocol)になっており、Macはこのプロトコルをサポートしていないからです。そのため、いくつか対応方法があります。

★対策その1

Android端末のUSB接続モードをMSC(Mass Storage Class)に変更する。

Xperia VLの設定アプリからXperiaを選択し、接続設定でMSCに変更します。



Xperia VLは内蔵ROMとSDカードと2ドライブあるのですが、このモードにするとSDカードしか扱えない、USB接続中は端末からアクセスできない欠点があります。

★対策その2

MacでAndroid File Transferアプリを利用する。

Googleから提供されているフリーのソフトです(Connecting to a Macintosh computer via USBを参照)。


専用アプリになるだけで、内蔵ROMもSDカードもアクセスできて機能的には問題ありません。見た目もファインダーっぽいので違和感なく使えます。

★対策その3

MacでSony Bridge for Macアプリを利用する。

Sony Mobile(UK)が配布しているアプリですが、日本語にも対応しています。
Bridge for Mac softwareを参照)

音楽に力をいれているのか、ただのファイル転送だけでなくiTunesとの同期機能もあり、iTunesで音楽管理していた人にはかなり便利です。


普通にグローバルに配布してくれてもいいのに・・・なぜUK独自?
あと、開発元が不明?らしく、Lionでセキュリティの実行許可を「すべてのアプリケーションを許可」にしないと実行できないのはいかがなものかと・・・

★対策その4

VMWare FusionなどWindowsエミュレータを使う。

PC Companionも使えるし、エクスプローラーも使えます。Macからシームレスにアクセスできるし、結局これが一番賢い方法かもしれません。。。お金はかかりますが。


November 3, 2012

iPhoneからAndroidへアドレス帳の移行

iPhoneからAndroidへアドレス帳の移行方法です。

1) iPhoneをMacと同期させて、iPhoneのアドレス帳をすべて連絡先アプリから見れるようにする。今時はiCloudで同期させておくと自動で同期してくれるので手間がいらない。

2) 連絡先アプリからアドレスを全選択して、「ファイル-->書き出し-->vCardを書き出す」して、vCardファイルにおとす

3)ブラウザでgoogleコンタクトを開き、インポートを選択して、さきほどのvCardファイルを読み込む

4)Androidの設定アプリから「アカウントと同期」を選択し、googleアカウントを選択して連絡先を同期すれば完了!

単にvCardファイル経由で手動で渡しているだけなので、エレガントさのかけらもない。工夫すればうまくiPhoneとAndroidでアドレス帳を共有(同期)できそうだけど、アドレス帳はAndroidだけにあれば十分なので一発移行だけで・・・

Xperia VL購入


Xperia VLをMNPで発売当日に購入しました。


一週間前から予約していたので、余裕で購入。ただし、他機種も同時発売とあり、平日のAM10:00に開店ダッシュしたにもかかわらず契約コーナーは大行列で1時間30分も待ちましたが・・・

ながらくiPhoneシリーズを使っていたのですが、iPhone4以降買い替えるほどの魅力を見いだせず、欲しい機能がまったく進歩しないままiOS6まで達し、ついに見切りをつけました。個人情報満載の携帯電話でセキュリティ的に不安を感じるAndroidはおいそれと手を出す気はしなかったのですが、めきめき新機能を搭載していくAndroid、魅力的な端末Xperia VLがAUからでるとあり、乗り換えることにしました。

XperiaVLのいいところ
- デザインがかっこいい!さすがソニーモバイル!
- 片手で快適操作できる範囲で最大サイズ!画面は大きい方がいいが、片手で操作しづらいサイズは勘弁。5インチとかもうタブレットでしょ・・・両手じゃないと操作できないし。
- 液晶が超奇麗!Sensor-on-lensで表面から液晶面までの距離が短いのもグッド。太陽光下でもぜんぜん見える。iPhone4のときはまったく見えなくて日陰を探したもんですが...
- カメラ最強!起動が速い、使いやすい、高画質!
- 音がいい!xLOUDでスピーカーの音が最高!
- 防水!大雨でカバンに入れてたiPhoneが水没した経験があるので、外で使うデバイスは防水じゃないとね
- NFCとFeliCaの両対応!ガラケー以来久しぶりにお財布機能復活
- 急速充電!10分充電で1時間通話できる
- LTE対応!ユーザーが増えるまでは爆速でないかと。

OSとしてもハードとしても非常に成熟したバランスのとれた端末だと思います。


少しだけ要望点も。すでにヌルサクなのでクアッドコアとかはっきりいってどうでもいいのですが、できればRAMは2GB欲しかったかな。1GBでも不足しないかもしれないが、気持ちの問題か。フロントカメラが30万画素もどうかと・・・ビデオチャットとかを考えると130万画素欲しかったな・・・

付属品は、卓上ホルダ(DK25)、ACアダプタ(EP880)、USBケーブル、ワンセグケーブル、イヤホン。microSDは付属していない。

さて契約のお話。

ソフトバンクからAUへMNPなので、ソフトバンクでMNP番号を取得。WEBでやれば待ち時間もなくて良いんですが、暗証番号を覚えてなかったので、ソフトバンクショップで人間対応。転出手数料で2100円。AUへの契約でも手数料とかで3150円支出。

端末は2年も分割払いとか嫌いなので一括購入。端末代金75600円。どうせ支払い総額はかわらないしね。月々の金額(ランニングコスト)が安くあがってる方が精神的にホッとするので。2年以内に乗り換えた時、端末代の月賦が加算で高く感じるしね。そうそう、ヨドバシで買ったので、ポイント10%ゲット。

AU初のLTEなので、聞き慣れない新しいプランへ。結論からいうとLTE端末は現状ほぼ選択肢はありません。通話料金を安くプランが少しあるぐらい。

料金プラン:LTEプラン
安心ケータイサポート:申し込み(だって1ヶ月後に解約するのが一番安いから...)
auスマートパス:申し込み(だって1ヶ月後に解約するのが、略...)
割引サービス:誰でも割
安心セキュリティパック:不要
インターネット接続サービス:LTE NET(ネットにつながないとかありえないし...)
パケット通信料割引サービス:LTEフラット(フラットはこれしかないし...)
テザリングオプション:申し込み(7GB制限あるから使わないけど、2年無料だからその間だけ...)
auスマートバリュー:申し込み(ひかり固定電話とかマジいらないけどね...)

auスマートバリューの申し込みには固定電話の番号があると手続きが早いので忘れずに。固定電話使う気ゼロ(契約だけで電話つながってないし...)なので番号がいくつかも知らなかったが、その場でauひかりに電話してくれて、契約番号から対応してもらった。危ない。

トータル割引料金は980円+1785円+1480円=4245円が毎月割引!(最初の2年)
月額料金はだいぶ安いんじゃないかなー。

契約にかかった時間30分以上、契約終わったら即引き取りかと思ったら、そこから作業に1時間30分かかるといわれ、一時撤退。夜ひきとってようやく終了しました。

明日からがんばっていろいろ設定します。

July 13, 2012

JellyBean(4.1)のソースコードを取得する

JellyBean(4.1)のソースコードがリリースされましたので、取得方法です。

$ repo init -u https://android.googlesource.com/platform/manifest -b android-4.1.1_r1
$ repo sync


今回はMacのターミナル上で実行しましたが、取得するにはrepoコマンドが必要です。
ホームフォルダにbinフォルダを作成して、そこにrepoコマンドをインストールしました。

$ mkdir bin
$ PATH=~/bin:$PATH
$ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
$ chmod a+x ~/bin/repo

これでインストール完了です。

July 12, 2012

対応すべきプラットフォーム

Androidにはさまざまなデバイス(端末)がありますが、現在市場にでまわっている状況が確認できます。AndroidのOS version、ディスプレイサイズ、Open GLのversionから製作するアプリがサポートすべき環境を想定すると良いと思います。

July 9, 2012

bindService()で始める、Binderクラスで作るService

Binderクラスを使って作る最も一般的なServiceの作成方法です。

bindService()を使ってServiceをBindし、Serviceで提供するユーザー関数を直接コールすることができます。Bindしている間Serviceは存在し、Unbindすると削除されます。複数のActivityからマルチでBindすることもできます。

bindService()を使ったServiceの作り方は3種類ありますが、今回紹介する方法が最も一般的です。なぜなら、アプリ内(正確にはServiceと同一プロセスで動くコンポーネントにServiceを提供する場合)でServiceを提供する場合はこの方法が最も適切かつ簡単なため、他のプロセスやアプリに機能を提供するなど特別なケースでない限り、他の方法を使う必要がないからです。

おおざっぱな流れは、Service側のクラスはBinderを拡張したユーザークラスを作成します。bindService()を実行するとonBind()がコールされるので、そのユーザーインスタンスを返します。呼び出し側のActivityではBindされるとServiceConnectionクラスのonServiceConnected()が呼ばれるので、ここでBinder経由でServiceインスタンスを取得します。あとはそのServiceインスタンスを使って、Service側でユーザー定義した関数を直接コールすることができます。

public class SampleService extends Service {
    private final static String TAB = "SampleService";
    private final IBinder mBinder = new LocalBinder();

    public class LocalBinder extends Binder {
        SampleService getService() {
            return SampleService.this;
        }
    }

    @Override
    public void onCreate() {
        Log.i(TAB,"onCreate");
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public void onDestroy() {
        Log.i(TAB,"onDestroy");
    }

    // Methods for client
    public void userFunction() {
        Log.i(TAB,"userFunction");
    }
}

public class SampleAppActivity extends Activity {
    private final static String TAB = "SampleAppActivity";
    private SampleService mSampleService;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAB,"onCreate");

        setContentView(R.layout.main);

        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mSampleService.userFunction();
            }
        });
    }
 
    @Override
    public void onStart() {
        Log.i(TAB,"onStart");
        super.onStart();
        // Bind
        Intent intent = new Intent(getApplicationContext(), SampleService.class);
        bindService(intent, mSampleServiceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    public void onStop() {
        Log.i(TAB,"onStop");
        super.onStop();
        // Unbind
        unbindService(mSampleServiceConnection);
    }

    private ServiceConnection mSampleServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            SampleService.LocalBinder binder = (SampleService.LocalBinder)service;
            mSampleService = binder.getService();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };
}

参考:Android Developers:Bound Services

July 6, 2012

startService()で始めるService

startService()で始めるServiceとは、intentを使ってServiceを起動し、バックグラウンドで指定された処理を実行するものです。

最も簡単に実装するには、Serviceクラスでなく、IntentServiceクラスを利用することです。その場合下記の例のようになります。ServiceクラスそのものはUIスレッドで動作するため、ブロックしないために通常はスレッドを作って、そちらで処理を実行しますが、IntentServiceはそのような面倒な処理がすべて実装されていて、コンストラクタとスレッドで実行する処理内容をonHandleIntent()をオーバーライドして実装するだけです。onHandleIntentはもちろん別スレッドで実行されます。

例:呼び出し側のstartService()

startService(new Intent(getApplicationContext(), SampleService.class));

例:受け取り側のService

public class SampleService extends IntentService {
    public SampleService() {
        super("SampleService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i(TAB,"onHandleIntent");
        // Execute something...
    }
}

あえてService()で実装しなければいけないケースは、マルチスレッドで同時実行したい特殊な例だけです。IntentServiceはシングルスレッドのため、実行中に次の要求(startService())がきた場合はキューイングされ、逐次実行になります。すべての処理がおわるとIntentServiceは終了します。

参考までにあえてIntentServiceと同じ動作をするものをServiceを使って作成すると下記のようになります。

public class SampleService extends Service {
    private ServiceHandler mServiceHandler;

    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            // Execute something...

            // Stop the service with start id
            stopSelf(msg.arg1);
        }
    }

    @Override
    public void onCreate() {
        // Create and start new thread and handler
        HandlerThread thread = new HandlerThread("SampleService", Process.THREAD_PRIORITY_BACKGROUND);
        thread.start();
        mServiceHandler = new ServiceHandler(thread.getLooper());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // Create message
        Message msg = mServiceHandler.obtainMessage();
        // Set start id
        msg.arg1 = startId;
        // Send message
        mServiceHandler.sendMessage(msg);
        
        return START_STICKY;
    }
    
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

簡単に説明するとonCreate()でThreadとHandlerを新規作成します。Handlerは継承したユーザークラスを作り、handleMessage()に処理を記述します。startService()するとonStartCommand()がコールされ、Handlerから生成したMessageをThreadに送信し、Thread上でそのMessageとともにhandlerMessage()が実行されます。

マルチスレッドにする場合はonCreate()ではなくonStartCommand()がくるたびにスレッドを生成するようにするなど工夫する必要があります。

参考:Android Developers:Services

July 5, 2012

プロセス情報を取得する

システム上で動作しているプロセス情報を取得する方法です。

デバッグなどでバックグラウンドで存在しているプロセスを調べるのに利用できます。

例)プロセス情報をすべて取得し、プロセスID、パッケージ名を表示します。

ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<RunningAppProcessInfo> appList = manager.getRunningAppProcesses();
Log.i(TAB, "Total apps:" + appList.size());
for (RunningAppProcessInfo info:appList) {
    Log.i(TAB,"PID:" + info.pid + " Name:" + info.processName);
}

プロセス情報を取得するにはパーミッションの設定が必要です。

<uses-permission android:name="android.permission.GET_TASKS"/>

実行すると下記のように表示されます。


ちなみにプロセスを停止させる場合は、ActivityManagerのkillBackgroundProcesses(パッケージ名)を使います。停止させる場合もパーミッションの設定が必要です。

<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>

参考:Android Developers:ActivityManager

onDestroy()してもプロセスは死なない

アプリはプロセスが割り当てられて動作しますが、ひとたび起動したアプリは、たとえ全てのActivityがonDestroy()してもプロセスは死にません。タスクはなくなってもプロセスは残ったままになります。アプリのActivityがonDestroy()まで到達し、タスクもなくなれば完全終了した気になりますが、実はプロセスとしてはまだ生きています。

例えば1つのActivityを持つアプリがあったとして、onCreate()で無限ループのThreadを起動したとします。Activityをバックキーで終了させ、onDestroy()までコールされるのですが、このThreadはだれも終了させることなく動作し続けます。Threadのdaemonフラグに関係なく生き残る仕様のようです。

設定アプリの「アプリケーションの管理」で表示されるアプリに「強制停止」ボタンがありますが、これはプロセスを殺す、ということをしています。プロセスがなくなって初めて起動していない元の状態に戻ります。

ここでなにが言いたいかというと、バックグラウンドで動作するThreadなどをうっかり終了し忘れると、生き残って動き続けてしまう、ということです。当然CPUには負荷がかかり、アプリを終わったのに端末の処理が重い、というのはこういう不具合で発生します。アプリでバックグラウンド処理を実行する場合は、きちんと終了できているか十分に確認することが必要です。

July 4, 2012

アプリケーションとLooperとHandlerの関係

アプリケーションとLooperとHandlerの関係についての説明です。Androidフレームワークの内部に踏み込んだお話です。

「スレッドからUIを操作する」で、UIスレッドで実行させるために他のスレッドからHandlerクラスを使って処理内容を送信すると説明しましたが、なぜnew Handler()としただけのインスタンスにpost()しただけでUIスレッドに送信されてしまうか?という疑問への回答です。

まずAndroidのアプリケーションは1つのプロセスが割り当てられて動作しています。別々のアプリは別々のプロセス(つまりメモリ空間が異なる)で動いています。

UIスレッドとはメインスレッドとも呼ばれ、内部ではActivityThreadクラスのことを指します。このクラスはStatic変数のLooperクラスを所持しており(つまり1プロセスに1つしかない)、メイン関数でLooperクラスのメインループを実行しています。Looperクラスの処理は単純で、メッセージキューに入ってきた処理があれば実行する、だけです。つまりどこかのスレッドからメッセージをLooperに送信すれば、ActivityThread(UIスレッド)で実行してくれるという仕組みになっています。その送信するのがHandlerクラスになります。Handlerクラスは引数なしでnewすると内部でStatic変数のLooperクラスを送信先とします。つまりActivityThreadが送信先になるということです。

ここでいうメッセージとは、内部ではMessageクラスを使っており、Handlerのインスタンスでpost()するときのRunnableインスタンスを渡しています。それがLooperのメイン関数で、渡されたRunnableのrun()を実行しています。

より詳細はAndroidのソースコードを読む必要があります。
  • android/os/Handler.java
  • android/os/Looper.java
  • android/os/Message.java
  • android/app/ActivityThread.java
ちなみに、このLooper、Handlerの仕組みは独自に他のスレッド同士で利用することも可能です。引数を指定することでUIスレッドとは無関係に、独自で作ったスレッド間で同じ仕組みを利用できます。

July 3, 2012

Android EmulatorでWebカメラを使う

Android EmulatorでWebカメラを使う方法です。

Front camera、Back camera個別に設定できます。

デフォルトのカメラはEmulatorになっていますが、AVDの設定を変更してWebカメラに設定することで利用できるようになります。

AVD ManagerからAVDの編集(Edit)をクリックし、HardwareのPropertyで"Configures camera facing back"を選択し、Valueを"webcam0"にします。これでBack cameraがwebcam0になります。Front cameraを設定したい場合は"Configure facing front"を修正します。


ちなみにどんなWebカメラデバイスが使えるかは、コマンドラインから確認できます。emulatorはandroid-sdks/toolsにあります。

$ emulator -avd JellyBeanPhone -webcam-list


webcam0が有効なことがわかります。

実行するとemulatorカメラでなくWebカメラの出力が表示されます。


Android SDKをJelly Bean(4.1) にアップデートする

Android SDKをJelly Bean (Android 4.1)にアップデートする方法です。MacのEclipseで作業した場合の例です。

最初にAndroid SDK Managerを起動し、Toolsをアップデートします。


続いて、Install New SoftwareでADT Pluginをアップデートします。


再度Android SDK Managerを起動すると、Android 4.1(API 16)がでてきますので、インストールします。


続いて、AVD Managerを起動し、JellyBeanのAVDを作成します。


以上で、完了です!