2011年5月18日

富士通の「Windows 7」携帯 LOOX F-07C に欲しかった3つの機能

こんな変わった携帯がドコモから発表されたらしい。
「超ちっこい7搭載PC(ケータイ機能もあるよ)」というところがいいですよ:LOOX Uを超えたケータイサイズの新LOOX──“PC”として写真と動画で見る「Windows 7ケータイ F-07C」 (1/2) - ITmedia +D PC USER
これは面白い。ほとんどネットブックに匹敵するスペックで、Windows Phone 7ではなく通常のWindows 7 Home Premiumが動くとの事。

正直言って僕の理想の「超小型PC携帯」に近付いている。もし機会があったら実際に手に取って触ってみたい。

この発表に触発されて、僕が思う「理想の超小型PC携帯」とは何だろうかと考えてみた。とりあえず思いつくのはこんな感じだろうか。

  • 外部モニター、マウス、キーボードが接続可能
    (これは F-07C で可能らしい。)

  • 重さは170グラム程度かそれ以下
    (F-07Cは約218グラム)

多少の重量オーバーには目をつぶるとしても、欲しかったのは次の3つだ。

  • 外部モニター接続時の解像度は1,680 x 1,050以上
    (F-07Cは1280×720ドット)
  • 10Mbps以上の高速で安定したネット接続
  • Wifiテザリングが可能



もしこんな端末があれば、会社と自宅の両方にクレードル+外部モニター+キーボード+マウスのセットを用意しておいて、会社に着いたら携帯をクレードルにセットして仕事、家ではベッドに寝転がってネット閲覧、大きな画面で見たくなったらクレードルにカチャッ、と言う使い方が出来るのに。


クレードル部分は妻や子供の携帯と共用で使える用になっていればなお嬉しい。その上でネットワークの速度が10Mbps以上あれば自宅のケーブルインターネットは要らなくなる。Wifiテザリングが出来ればiPodやiPadからのネット接続も問題無しだ。

でも考えてみると、僕の使い方だと職場のPCにリモート接続する事がメインの用途になりそうだ。そうだとすると、端末自体のOSは何であっても大した違いは無い様な気がして来た。結局の所、必要なのは携帯機能が付いたシンクライアントという事か。

さて、この流れで行くと数年後にはどんなスペックの端末が出て来るのだろうか、楽しみだ。PCはみんなポケットに入れて持ち歩くのが当たり前になるのだろうか。究極的には腕時計サイズになれば嬉しいのだけれど。(笑)







.

2011年5月10日

AndroidでURLを開く度に自作のアプリを起動する (2) メール送信機能と設定画面の追加



前回はURLを開くインテントを受け取ってListViewに追加した後、標準ブラウザで開くという大まかな流れを作成した。

今回は、ListViewに保持しているURL履歴の一覧をメールで送信するという部分と、その為に必要な設定画面を実装したい。

全ソースがダウンロード出来るリンクを最後に付けておいたので、興味のある方はぜひダウンロードしてあれこれ試してもらえればと思う。




メールを送る


「メールを送る」とは言っても、アプリから直接メールサーバーに接続してデータを送るのは大変だ。やろうと思えばその為のライブラリもある事はあるらしい。
Android: マルチスレッドでJava Mail
Downloads - javamail-android - JavaMail port for the android plateform - Google Project Hosting

が、今回は単純にデフォルトのメーラーを起動する為のインテントを発行するだけにしようと思う。

メーラーを起動する為のインテントは、次の方法で発行出来る。
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:" + to_addr));
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_TEXT, message );
startActivity(intent);

メニューボタンから「メール送信」を選ぶとListViewの内容をメールで一括送信する様にした。


本当は startActivity の代わりに startActivityForResult を使って実際に送信ボタンが押されたのか、キャンセルされたのかも取得したかったのだが、どうも上手く結果が返って来なかったのでこれは断念した。



設定画面を作る


とりあえず3つの項目を設定出来る様にしておいた。


設定画面の作り方はこちらが参考になった。(特に設定された内容をサマリーに表示する部分)
Y.A.M の 雑記帳: Android 設定画面を作成する
Y.A.M の 雑記帳: Android Preference の summary を動的に変更



ListViewで項目がタップされた時の処理


ListViewで項目がタップ(クリック)された時の処理は、AdapterView.OnItemClickListenerクラスのインスタンスをsetOnItemClickListenerメソッドでListViewにセットすれば記述出来る。

例えばこんな感じになる。
//リストの項目がタップされた時の処理
list.setOnItemClickListener(
    new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView parent, View view, int position, long id) {
            ListView listview = (ListView)parent;
            selected_url = (String)listview.getItemAtPosition(position);
            dialog.show();
        }
    }
);

今回は項目がタップされたら処理を選択するダイアログを表示する様にしてみた。


この処理は1回だけ実行すれば良いのでActivityのonCreateで行う様にする。
//リストの項目がタップされた時に開くダイアログを準備。
String[] str_items = { getString(R.string.mnu_browser) , 
                       getString(R.string.mnu_send), 
                       getString(R.string.mnu_delete)};
final AlertDialog.Builder dialog = new AlertDialog.Builder(this)
        .setIcon(R.drawable.icon)
        .setTitle(getString(R.string.mnu_select))
        .setItems(str_items, 
            new DialogInterface.OnClickListener(){
                //ダイアログの項目が選択された時の処理。
                public void onClick(DialogInterface dialog, int which) {
                    switch (which){
                        case 0:
                            openBrowser(selected_url);
                            break;
                        case 1:
                            sendEmail(selected_url);
                            break;
                        case 2:
                            deleteUrl(selected_url);
                            break;
                        default:
                            break;
                     }
                  }
              }
        );

参考にしたサイト: 色々なダイアログの例があるので便利。
八角研究所 : Android で再開する Java プログラミング(14) - ダイアログを制するものがAndroidを制する!



今の所の問題点


ここまでで一応URLの履歴をメールで送信出来る様にはなった。

ただ、ちょっと気になる点がある。それはブラウザでリダイレクトが発生する度に新たに「ブラウザで開く」インテントが発生するという事だ。結果として履歴の一覧にはリダイレクト前と後のURLがそれぞれ残る事になる。

例えば、bit.lyなどの短縮URLサービスを使った場合や、スマートフォンからのアクセスを自動的に専用のURLに誘導する様になっているサイトなどでこの現象が起きる。

実質的に同じページを指しているのに履歴一覧に複数行表示されるのは、ちょっと都合が悪い。リダイレクト後のインテントを受け取った時にそれが「リダイレクトされたものである」という事が認識出来ればリストに追加しない様に出来るのだが、今の所その方法を見つけられていない。



今回の全ソース


mikehibm/android-browser-intent02 - GitHub

次回はいよいよSQLiteを使ってローカルデータベースにURLの履歴を保存する様に変更してみたい。

ちなみに、現在大活躍中の参考書はこちら。まだAndroidの世界で右も左も分からない自分には必携の書になっている。
AndroidSDK開発のレシピ―104個のレシピで学ぶAndroidアプリ開発の極意


AndroidでURLを開く度に自作のアプリを起動する






.

2011年5月3日

AndroidでURLを開く度に自作のアプリを起動する (1) インテントを受け取る



最近、ようやく少しずつAndroidのプログラムを作り始めている。

とりあえず必要に迫られて試して見たのが、

「ブラウザで開く」というインテントを受け取ってURLの履歴を保存し、再度そのURLをブラウザで開く

というアプリ。
単純なアプリだが、実際に作って見るとインテントの面白さを実感出来る。



動作の概要


例えば「はてなブックマーク」のアプリからリストの項目をタップすると「ブラウザで開く」インテントが発行される。(もちろんアプリはURLからブラウザを開く事が出来るものであれば何でも良い。)

インテントに対応出来るアプリが複数ある場合は選択ダイアログが表示される。

自作アプリ「intent01」を選択すると、標準ブラウザーが開く。

「戻る」ボタンでブラウザを閉じると自作アプリに戻る。開いたURLの履歴が表示されている。



インテントを受け取る


Androidのインテントには、起動するコンポーネントを指定して発行される明示的インテントと、特に指定しない暗黙的インテントがある。面白いのは暗黙的インテントの場合だ。

暗黙的インテントが発行された場合は、システムがそれを処理出来るアプリを自動的に見つけて起動してくれる。候補となるアプリが複数見つかった場合は、選択する為のダイアログが表示され、ユーザーがどれを起動するか選択出来る仕組みになっている。

つまり自作のアプリを「"ブラウザでURLを開く"インテントの処理が可能です」と宣言しておけば、システムがそれを認識して該当の暗黙的インテントが発行された時に選択ダイアログに表示してくれる訳だ。

この宣言をするには、AndroidManifest.xmlファイルのactivityタグの下に次の記述を追加するだけで良い。

<intent-filter>
    <action android:name="android.intent.action.VIEW"  />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE"/>
    <data android:scheme="http" />
    <data android:scheme="https" />
</intent-filter>

アプリ内では、getIntent()でインテントを取得出来る。単にホーム画面のランチャーから起動されたのか、別のアプリで「URLをブラウザで開く」操作をされて暗黙的インテント経由で起動されたのかは、取得したIntentのgetAction()で判断可能だ。


if (Intent.ACTION_VIEW.equals(intent.getAction()) ){
    //暗黙的インテント経由で起動された時の処理
} else {
    //ランチャーから起動された時の処理
}



ListViewに表示する


インテントに詰め込まれたURLは、
String url = intent.getDataString();

で取得出来る。

ここまで来れば、後はListViewにURLの文字列を追加する部分さえ作れば履歴の表示が出来る。

注意が必要だったのは、ListViewに表示するArrayAdapterをstaticで宣言する事。でないと起動される度に毎回newされてしまい、リストには最後の1件しか表示されなくなってしまう。



標準ブラウザでURLを開く


ListViewに追加した後、標準ブラウザでこのURLを開く為には、明示的にブラウザを指定して同じインテントを発行し直せば良い。
intent.setClassName("com.android.browser", "com.android.browser.BrowserActivity");
startActivity(intent);

setClassNameの1つ目の引数はパッケージ名、2つ目はクラス名なので、これらを変えればもちろんFireFoxなど他のブラウザを呼び出す事も可能だ。(オプションで設定可能にしたら便利かも知れない。)

ブラウザからハードウェアのバックボタンで自作アプリの画面に戻るとちゃんとListViewにURLが追加されている。素晴らしい。(笑)

もちろんこのままだとリストの内容はstatic変数で保持しているだけなので、アプリのプロセスが終了した時点できれいさっぱり失われてしまう。本来ならローカルデータベースに保存するなどの処理を追加する必要がある。(それは次回以降のネタとして取って置きたい。)



結局何がしたかったのか


で、実は何がしたかったかと言うと、この履歴一覧の内容をPCに送りたいのだった。

最近寝る前に携帯で気になるニュースやブログ記事をピックアップしておいて、翌日の空き時間にPCでじっくり読むというスタイルが定着して来たので、出来るだけ簡単にURLの一覧をPCに送信する方法はないかと考えていて思いついた方法がこれだ。

もちろん「Read It Later」やその類のアプリもちょっと試しては見たけれども、いちいちユーザーアカウントを作るのも面倒だし、そもそも送信元のアプリから「共有」もしくは「送る」という操作をしないといけないのが面倒に感じていたのだ。例えば、「Google Reader」からだと一覧の記事を長押ししてもそこには「送る」メニューは無く、記事の詳細を開いた上でメニューボタンを押して、「その他」から「Send」を選んで、それからようやく送り先のアプリを選べる事になる。

記事のタイトルだけチェックしてさくさくとPCに送りたいと思うと、いちいち「送る」メニューを選ぶのはどうも使い辛い。

今回の自作アプリだと、一度デフォルトブラウザとして選択しておけば、後はリンクをタップして行くだけで裏で履歴を取ってくれるのでかなり時間が短縮出来そうな気がする。

という事で、次回からメール送信やローカルデータベースへの保存の部分を作ってみたい。

ちなみにここまでのプロジェクト全体のソースはこちらからダウンロード可能になっている。(初めてGitHubに上げて見た。^^)
https://github.com/mikehibm/android-browser-intent01

設定ファイルを除いた本体のソース(Intent01Activity.java)は68行しかないので興味がある方はぜひどうぞ。






追記: 標準ブラウザが格納している履歴を取得する方法

こちらに標準ブラウザが保存している履歴をコンテントプロバイダー経由で取得する例を見つけた。機会があればこの方法も試して見たい。
furafura times: 標準ブラウザのコンテントプロバイダから履歴を取得
WebView逆引き - でこちく備忘録



AndroidでURLを開く度に自作のアプリを起動する









.