2011年12月30日金曜日

androidのtextviewの状態変化の注意点

androidのtextviewを使う場合、状態変化に応じて背景色を変化させるのが一般的です。
通常のアプリなら【通常】【押下】【フォーカス】の3つの状態の処理を設定すれば十分でしょう。
この処理は通常、drawable配下のxmlに処理を記述します。
そして、selectorを使ったタグを使い、【通常】【押下】【フォーカス】の状態の背景色を設定していきます。
このときxmlの記述で気をつけないといけないのは、textviewでフォーカス状態にするのは、 android:state_selectedの属性を利用しなくてはいけないことです。
android:state_focusedを設定すると状態変化しないので注意が必要です。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年12月23日金曜日

2011年度BEST音楽

さて、2011年ももうすぐ終了です。
というわけで今年のまとめです。
今日は、今年心に残った音楽のまとめです。
BEST3にしようと思ったのですが、絞り込めなかったのでBEST4にしました。

4位
B'z【C'mon】邦楽




感想
ブリティッシュROCKと日本ROCKの融合といったかんじの曲。
名曲。シングルで発売すればオリコンのTOP10園内に食い込んだでしょう。
でも、現代は配信時代だし、オリコンの記録なんて気にする時代じゃないってことですね。
震災後にエネルギーをもらえた曲です。

3位
Katy Perry【E.T】洋楽


感想
第一印象はあまり良くなかったのですが、聞いているうちに、
毎日ひたすらリピートするようになったスルメ曲。
Fireworkもとっても良い曲だったのですが、僕的にはこっちが良かった。
歌い方がとっても僕好みなのです。
チャート5週連続一位ってのも凄いですね。

2位
モーニング娘。【シルバーの腕時計】邦楽


感想
youtubeで発見。昭和の歌謡曲っぽい曲です。すごく良い曲です。
意外なことに、モーニング娘。って海外だと人気高いんですね。
日本じゃAKBがブームなので、全く話題にあがらないので、モーニング娘。のメンバーなんて全然わからない。
ただ、この歌を唱っている鞘師って子は、おそらく将来化けますね。
良い雰囲気をまとってます。今は全然無名だけど、成長すればブレイクすると思います。
残りのラップ歌っている新垣って子と、リボンの田中って子は微妙。

1位
Adele【Rolling in the deep】洋楽


感想
文句なしのぶっちぎりで今年のナンバー1SONG。別格。
日本以外の国で爆発的に売れた曲ですね。
グラミー賞も取れると思います。
個人的には、今一番バンドでやりたい曲です。
世界中でコピーバンドの映像がありますが、子供が歌う凄い映像もありますね。
なんで日本で売れなかったのか謎。今の日本の音楽状況は特殊すぎてよくわかりません。

以上。
2011年音楽BEST4でした。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年11月10日木曜日

androidのADT14からはswitch文が利用できなくなっている

androidのADT14からはswitch文が利用できなくなっています。コンパイルをしようとすると、コンパイルエラーで赤くなります。 なので以下のようなコードがある場合は、変更しないといけません。


       switch (item.getItemId()) {
         case R.id.menu_top:
          intent = new Intent(Constants.INTENT_ACTION_TOP);
          startActivity(intent);
             return true;
         case R.id.menu_help:
       intent = new Intent(Constants.INTENT_ACTION_HELP);
 
上記のコードは、メニューなどの分岐で頻繁に使われる文法ですが、以下のように修正が必要になります。

     int id = item.getItemId();
     if (id == R.id.menu_top) {
         intent = new Intent(Constants.INTENT_ACTION_TOP);
         startActivity(intent);
            return true;
     } else if (id == R.id.menu_help) {
         intent = new Intent(Constants.INTENT_ACTION_HELP);
 

この変更は、android4.0から仕様が変更されたのが原因のようです。自動生成されるRファイルの定数がfinalでなくなったためです。 Eclipseを使っている場合は、「command + 1」で自動的にリファクタリングで修正できます。

android4.0以降での挙動が怖いので、既存プロジェクトも修正したほうがよいかもしれないですね。なので、自動リファクタリングを使ってさっさと直してしまうのがベストだと思います。

参考サイト:http://tools.android.com/tips/non-constant-fields

(以上の記事は私が管理人をやっているfaceBookのページにも記述してあります。)

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年11月4日金曜日

半年ぶりにandroidアプリをリリース

半年ぶりにandroidアプリをリリースしました。

記憶の王様というアプリです。

この記憶の王様アプリは、記憶作業を効率的におこなえるようにする補助ツールアプリです。
このアプリでは、エビングハウスの忘却曲線をつかった日付計算が自動におこなわれます。
なので、無駄なく記憶作業に徹することができます。
科学的で効率的な記憶作業は、受験勉強、資格勉強、語学勉強等で大きな助けとなるはずです。

特に語学勉強の単語の暗記や、長期的な記憶が要求される難関試験でとても役立ちます。

以下のQRコードからアプリのダウンロード画面に直接遷移できます。

Android Marketへのリンクはこちらです。

このアプリでは、ActionBarSherlockやquickActionなどのツール、compativityのFragmentやFlick可能なPageAdapter等を使用しています。
androidのターゲットOSversionは2.1ですが、3.2相応の動きになっています。
今後、あらゆる端末がIceCreamに変わるまでは、こういった作り方が中心になる気がします。
実際、googleの純正アプリやシリコンバレー企業のアプリは、上記のツールで作られていると考えて間違いないです。
なので、技術的な解説も今後色々としていけたらと思っています。
さてさて、完全に夜があけたので寝ます。
おやすみなさいzzzzzz。

アプリ画像

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

Android Marketでapkファイルupdateエラー

Android Marketに作成したapkをアップしようとしたら、以下のようなエラーが発生しました。


The file is invalid: W/ResourceType( 1219): Failure getting entry
for 0x7f040000 (t=3 e=0) in package 0 (error -75) ERROR getting
'android:label' attribute: attribute is not a string value

ググって調べてみても、原因がいまいちはっきりしなかったのですが、これまでの開発経験からXMLに問題があることは予想がついたので調査しました。
で、突き詰めて調べたところ、原因が無事判明。

原因は、res/values/string.xmlに記述された属性データと、res/values-ja/string.xmlに記述された属性データが異なっていたからでした。

要は、日本語ファイルと英語ファイルで、属性の有無に差があったということです。
そもそもの原因は、アップデートするapkファイルのversionでは英語対応をするつもりはなく、英語版はstring.xmlファイルだけ用意しておこうと考えたことでした。
アプリで英語対応をするなら、日本語のstring.xmlと同じ属性を、英語のstring.xmlファイルにも全て記述しないといけません。
本来であれば、string.xmlが記述されていない箇所でアプリが落ちて終了。なのですが、AndroidManifest.xmlで指定してあるstring.xmlの属性データが一致していないと、AndroidMarketにupdate出来なくなる仕様にAndroid Marketはなっているようです。
気をつけてほしいのは、この場合、エミュレーターや端末では問題なく動いてしまうということです。

ネット上には、Rファイルを消してみろとか、genフォルダを消せとか、色々な意見がありましたが、全然とんちんかんな答えなので注意してください。

(以上の記事は私が管理人をやっているfaceBookのページにも記述してあります。)

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年10月30日日曜日

ActionBarSherlockでactionBarのheaderを変更する

androidアプリの開発に便利なユーティリティ「ActionBarSherlock
日本のアプリではあまり利用されていないようですが、凄く便利で良いツールなので、是非使ってみてください。私はとっても重宝してます。
そして、このActionBarSherlockを使ったheaderの背景画像を変えたい場合は、以下のようにします。

ActionBarSherlockのversionは3.1.3で確認しています。

style.xmlで以下のタグを探します。

    <style name="Theme.AndroidDevelopers" parent="Theme.Sherlock.Light">


中の属性に

    <item name="abBackground">@drawable/sample</item>

があるので、ここを以下のように変更します。

    <item name="abBackground">@drawable/header_bg</item>

画像を変更すると、文字の色やサイズも変更したくなると思います。
文字の変更は以下の属性を追加します。

    <item name="abTitleTextStyle">@style/as_header_title</item>
 
abTitleTextStyle属性の中でstyleを指定してあげればOKです。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年10月28日金曜日

logcat read: Invalid argumentの解決方法

androidの開発でeclipseをとおして端末のデバッグを行っていると

logcat read: Invalid argument

のエラーが発生することがあります。
上記のエラーが発生すると、コンソールにlogが表示されなくなってしまうので、とても不便です。
直す方法は以下のような手順を取ります。私の環境はmacですが、windowsでも同じだと思います。

  1. adb logcat -c
  2. Eclipseを再起動

以上で元に戻ります。

参考サイト
http://www.android-navi.com/archives/android_1/logcat/#more
http://d.hatena.ne.jp/yujimny/20110124/1295849267


(以上の記事は管理人をやっているfaceBookのページにも記述してあります。)

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年10月22日土曜日

Intentでメーラーの立ち上げ

アプリの中で絶対実装しておきたいの機能の一つが、ユーザーからフィードバックや意見(クレーム)を得るためのメール送信機能です。
Intentで動作させるには以下のように実装します。

            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_SENDTO);
            intent.setData(Uri.parse("mailto:masmasa@test.com"));
            intent.putExtra(Intent.EXTRA_SUBJECT, "【アプリ名】");
            intent.putExtra(Intent.EXTRA_TEXT, "ばぐじゃねーかこのやろう");
            startActivity(intent);

以上のように書くと、メーラー選択画面が立ち上がります。

ただ、注意して欲しいのは、このやり方だとメーラ自体にバグがあると正常に動作しません。ソフトバンクやAUのプリインメーラーでは、正常に動作しない端末があります。
なので、注意書きにGmailを使うように記述しておくのが一番良い方法だと思います。
もし、それが嫌なら、ブラウザを立ち上げてメールリンクをクリックするといいでしょう。この方法なら大抵動きます。
もし、それもいやならWebviewを使って色々とやってみるといいでしょう。
まあ、そんなことするのは「工数と金の無駄」ですけどね。

ソフトバンクやAUの技術力が低いのが悪い。
とはいえ、状況によっては実装せざるを得ない場合もあると思います。

その時は、ソフトバンクやAUなどのキャリアを思いっきり恨んでください。

(以上の記事は管理人をやっているfaceBookのページにも記述してあります。)

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

sqlite3の日付処理

  • 公開日:2011年10月22日
  • 最終更新日:2015年06月17日

記事概要


スマホアプリ開発で欠かせないsqlite3での日付の扱い方について説明します。
oracleやmysqlのBETWEEN句をsqlite3で利用したい人向けの記事です。

sqlite3の日付型について


sqlite3は日付の型をもちません。
なのでmysqlのようにyyyy/MM/ddの日付形式は利用できません。
sqlite3で日付を扱いたい場合は、以下の書式の文字列を日付を表す文字列【Time String】として扱います。

  • YYYY-MM-DD(年-月-日)
  • YYYY-MM-DD HH:MM:SS(年-月-日 時:分:秒)

その他に利用できる日付形式もありますが、一般的には上二つの形式で事足りると思います。
他の形式を利用したい場合は、このアドレスを参照してください。
また、カラムはtext型にする必要があります。

sqlite3の日付で範囲を絞り込む場合(BETWEEN)


日付で範囲を絞り込むデータ取得の時、oracleやmysqlのBETWEEN句のように、日付の範囲指定をする場合は以下のようにする必要があります。


datetime(カラム名称, 'localtime') < datetime('2011-10-22', 'localtime')

第二引数に'localtime'を指定しているのは、sqlite3の日付を表す文字列【Time String】は、デフォルトでUTC(協定世界時)を扱うためです。

基本的に、sqliteは日付の扱いは得意でないということを認識しておいてください。

以上

android開発のオススメ書籍


全くのandroid開発初心者には向かない本ですが、ある程度開発に慣れた人が目を通すのに、良い本だと思います。 android本の購入の際は、自分が対応するandroidのバージョンを確認するようにしましょう。

関連記事

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年10月13日木曜日

良いプログラマーになるためには、テストコードを書かないといけない

ソフトウェア業界で、プログラムを書く時はテストコードを書くべきという考えが生まれてから随分と経つ。もう7年くらいは経つだろう。
 幸い私はjavaをメイン言語として扱っている技術者なので、JUnitでテストコードを書く習慣が自然とついた。
 だから、他の言語を利用するときもunitテストを利用して、テストコードをなるべく書くようにしている。
 今メインでやっているnativeのiphoneアプリやandroidアプリでもテストコードは書いている。WEBでも当然書く。
 工数が足りないプロジェクトでも、共通部分や明らかに危険な香りがする部分はなるべく書くようにしている。
この業界に入ってから一度もプロジェクトを破綻させたことがないのは、周囲の人間に恵まれたこと、運が良かったこともあるが、危険を感じたらコードでテストを書く習慣も多いに関係があると思う。

しかし、周りを見ると、未だに多くのプログラマーがテストコードを書く習慣がないのに驚く。
 確かにテストコードを書くのは面倒だ。unitテストを書くためには、意外と勉強することが多いのだ。
 さらに、プロジェクトの多くはテストコードを書く工数など見積もられていない。与えられた期間では、機能を実装するのと、バグをつぶすので精一杯だ。だから、どうしてもテストコードを書かない。
 そして、テストコードを書かないことで、バグが頻繁に出る。そして、修正のたびにバグつぶしとテストに多くの時間を費やす。
 色々な会社を見てきたが、長時間勤務が常態化している開発現場はほぼ同じパターンになっている。そういう開発現場で働くプログラマーは上が開発をわかってないとみんな不満を持っている。
 日本の会社は経営陣が技術者でないことが多い。わかってないのが当たり前だし、わかるはずがない。
 なので、あなたがそういった会社で働くプログラマーなら、経営者にわかってもらおうと思ってはいけない。そんな不満を解決してくれる経営者は、faceBookのザッカーバーグやgoogleのエリック・シュミット等だけだ。

 しかし、あなたが良いプログラマーになりたいのなら、工数が足りなくても少しでもテストコードを書く習慣を身につけなければならない。
 テストコードを書くことはソフトウェアの完成度を高めるだけではない。あなたのプログラミングの腕も飛躍的に向上させる。
 テストコードを書きながらプログラミングを書く習慣を身につけると、可読性の高いコードを書くように気を配るようになる。すると、テストコードを書く時間が全くない場合でも、可読性の高いコードを書けるようになる。
 可読性の高いコードは自然とバグが少なくなる。あなたが現場を離れた後も、引き継いだ人のコードの理解を助け、負担を減らす。そして、機能別の細かな分割、設計、テストケースのパターン、デバッグといった思考パターンが身につく。いずれはシンプルで洗練されたコードが書けるようになる。
 こうなったらしめたものだ。次は技術だけでなく、インタフェースやデザインにも自然と目がいくようになる。そうすれば、プロジェクトの全体像を把握してシステムを見れるようになる。デタラメなシステムでもなんとか帳尻を合わせられるような技術も身に付いてるはずだ。

 良いプログラマーになれれば、あなたが取れる選択肢はグンと広がる。
 今後は特にそうだ。安価なクラウド、個人が世界で勝負できるスマートフォン。今後、開発者は会社でも個人でも自由な形態で働けるようになる。英語と中国語を身につければ、鬼にかなぼうだ。

ちょっと話が飛躍しすぎてしまったw
だが、テストコードを書く習慣を身につけることが大切なことはわかったはずだ。

さあ、さっそくテストコードを書こう。
プログラマーは言葉や背中でなく、コードで語るのだ。


この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年10月7日金曜日

[書評】どんな判断や!

[書評】どんな判断や!

ゲームクリエイター稲船敬二さんの思考法をまとめた本です。
本屋をうろうろしていて、面白そうだと思ったので購入しました。




僕は、稲船敬二さんについては、ロックマンの生みの親として知っているだけでした。
稲船さんは、バイオハザード等の色々なヒット作を手がけているようです。
とはいえ、この本の内容は稲船さんの手がけていたゲームを知らなくても楽しんで読むことができます。
ゲーム業界やIT業界を目指している人、または働いている人に、特によんでもらいたいです。

僕はプログラマーなのですが、稲森さんとは考え方が酷似していると思いました。
中でも、

1、スピード感ある、小回りのきく組織の必要性
2、成功にはリスクを冒す必要がある
3、目標をもつ
4、物事の本質を見抜く
5、世界に目を向ける

上記は全く同意です。
僕も上記の事柄をサラリーマンという立場で感じ、自分の所属する会社の限界を思い知って、独立を決めたからです。
特に1と5は重要で、この先10年くらいは気づける人と気づけない人で、大きな差ができてしまうのではないかと個人的に思っています。

稲船さんは日本のゲーム業界の先を嘆いていますが、私の属するIT業界も同じようなものです。
情けなくなってしまうほどに保守的です。というよりは、現実から目を背けて、過去やありえない未来に逃げている状況です。
だから、できる人からどんどん見切りをつけて、大企業を離れています。

政府や自分の会社の行い方を批判しても、結局何も変わりません。
変えなきゃいけないのは自分です。
現在の自分を認識し、自分に責任をもって、自己を高めていくことがこれからの日本人には必要だと思います。

自分の属する会社や組織に閉塞感を抱いているひとは、是非読んでみてください。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年10月4日火曜日

独立後の戦略

さてさて、独立して生きていくすべを一から学んでいこうと思っている僕ですが、しばらくは手探りの状態が続くことになりそうです。
とはいえ、ゴールと目標は明確なので、毎日全力で突っ走ろうと思います。
クラウドとSNSを活用して、新しい形の業務形態を構築したいと思います。
自分でも楽しみです。
ブログでも積極的に公開して、共有していきたいと思います。
でわでわ。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年10月3日月曜日

独立しました

久しぶりの更新です。

突然ですが、タイトル通りです。
私、会社を退職して、独立することにしました。
今日からは有給の消化に入ります。

というわけで、今日から本格的に動いていこうと思います。
この先は、私のように独立して働くという選択をするひともどんどん増えていくと思います。

なので、自分の行動のログをとるという意味もふくめて、このブログに色々と綴っていきたいと思います。

しばらくは更新頻度も高いと思うので、私の苦労するようすをお楽しみください。





この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年8月27日土曜日

android開発 ListViewのheaderとfooterの挙動

よく間違えるのでメモ

ListViewのヘッダ-やフッターを利用する場合は、setAdapterを呼び出す前に、addViewする必要があります。
その後、データ数や処理に応じてヘッダ-やフッターの表示・非表示を切り替える場合は、setAdapter後に処理を追加して、notifyDataSetChangedを呼び出すと変更されます

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年3月28日月曜日

android アプリ 節電しようぜ! リリース

金曜日の夜のことです。寝る前にネットに目を通すと、以下のような情報を見つけました。

-----東電が電気使用状況データをCSVで公開 「アプリ作ったら知らせて」と経産省
東京電力が電気使用状況データをCSV形式で公開したことを受け、経済産業省情報プロジェクト室は、そのデータを活用した外部サービスを作ったら知らせてほしいとTwitterで呼びかけている。
2011年03月24日 15時54分 更新

東京電力がこのほど電気使用状況データをCSV形式で公開したことを受け、経済産業省情報プロジェクト室(@openmeti)は3月24日、そのデータを活用したアプリを作ったら知らせてほしいとTwitterで呼びかけた。「優れたアプリは国でも取り上げていきたい」という。

東電が公開しているのは、当日と前日の電気使用量の速報値。電気使用状況はこれまで東電のグラフで確認できたが、23日からはデータをCSV形式でダウンロードできるようになり、外部の開発者がそのデータを使ったサービスを作りやすくなった。

経産省情報プロジェクト室は、東電の電気使用状況データを活用したアプリを作ったら「@openmetiに向かってつぶやいてください」とコメント。集まった情報はひとまず、民間のWikiページ「東北関東大震災(東北地方太平洋沖地震)@ウィキ」にまとめる方針で、「編集して情報を加えていっていただけると助かります」ともツイートしている。

東電の電気使用状況データを活用したサービスは、ヤフーが公開した「電力使用状況メーター」や、エヴァンゲリオン風デザインの「NERV専用監視装置」など続々と登場している。-----
http://www.itmedia.co.jp/promobile/articles/1103/24/news068.html

上記を読んで、東電も色々大変だと思い、土曜日にざっくりと「節電しようぜ!」というアプリを作成しました。


これはただ単にCSV形式ファイルをダウンロードして、最新の電気使用量を取得するアプリです。

yahooなどのWEBと表示できる機能は同じですが、アプリを立ち上げると最新情報を取得するできる点が異なっています。
また、WEBが繋がらない場合でも、内部に過去のデータをもっているので、データを見ることができます。

とりあえず急ぎでざっくりと作成したので、今は電力情報しか見ることができませんが、時間があるときに
バージョンUPして色々と機能を追加していけたらと思っています。
明日くらいには検索でもひっかかるようになると思います。アプリ名は「節電しようぜ!」です。



そんな感じの現状報告です。
自分からツイートする気はないので、ダウンロードしてくれた方が呟いてくれたら幸いです。

疲れた休日でした。では、お休みなさい。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年3月16日水曜日

Pythonはじめました

Pythonの勉強をはじめました。
理由はソーシャルサイトを作成しようと考えているからです。
そのための言語を色々と調査していたのですが、結局Pythonにすることにしました。
正直、最後はRubyとPythonのどちらにするか激しく迷ったのですが、Google App EngineとFaceBookで
の実績を評価することにしました。

というわけで、これからはPythonの情報も取り扱っていこうと思います。
なんか日本語の情報がやたら少ないですけど、日本じゃ人気ないんですね。
でも、英語圏では情報が多いのであまり気にする必要もなさそうです。
本格的に利用していくつもりなので、基本からがっつり勉強する為に
「初めてのpython」第3版
を購入しました。

まだ全部は読んでいませんが、良い本です。
Pythonはプログラミング経験のある人なら、「なんとなく」動くコードが書けてしまう言語です。
でも、本格的に利用しようと思うのなら、絶対にこの本を読んでおくことをおすすめします。
さらにいうなら、繰り返し読み込み、演習も覚えこむくらい何度も解いたほうがいいでしょう。
結局のところ、そういった無意識レベルの基礎力が最終的な作りこみの段階でいきてくるのですから。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年3月5日土曜日

Android Tips TextView内の文字列リンクから特定のActivtyを呼び出す ~ContentProviderとLinkifyの理解~

Linkifyのリンクからパラメーターを渡してActivityを呼び出す処理が必要になり、ググッたらContentProviderの理解が必要だとわかりました。 しかし、ContentProviderの情報は色々と分散していて理解しにくかったので、まとめます。

・ContentProviderとは?

ContentProviderを利用すると、異なるアプリケーション間でデータを共有できる。
COntentProviderを利用することで、特定のデータタイプを他のアプリケーションが利用できる。

例えば、Androidで利用されている正式なContentProviderには、電話帳がある。
電話帳には、名前、住所、電話番号がリストで表示されている。

content://contacts/people/

という特定のURIを利用することで、どのアプリケーションであってもこのデータにアクセスすることができる。
androidURIの構成は以下の通り。

スキームcontent://
オーソリティcontacts
パスpeople

WEBのURIとほぼ同じですね。オーソリティがホストにあたります。ということで、実装して試してみます。

開発用os(jar)は現在メインで開発している2.1、エミュレータは2.3で確認

1、まずはエミュレーターを立ち上げて電話帳にデータを投入


2、では、実装していきます。

2-1、

AndroidManifest.xmlに

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

を記述。

2-2、

Activityクラスを作成します。

以下ソースコードです。

public class ProviderTest extends ListActivity {

    public static final String TAG = "ProviderTest";
    
    private ArrayList<ContactPojo> list;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.provider);
    }
    
    @Override
    public void onStart() {
        super.onStart();
        Log.d(TAG, "onStart start ");
        
        ContentResolver resolver = this.getContentResolver();
        Cursor c = resolver.query(Contacts.CONTENT_URI, new String [] {Contacts.DISPLAY_NAME} , null, null, null);
        
        this.list = new ArrayList<ContactPojo>();
        while(c.moveToNext()) {
            
            ContactPojo contactPojo = new ContactPojo();
            
            contactPojo.display_name = c.getString(0);
            
            this.list.add(contactPojo);
        }
        
        if (c != null) {
            c.close();
        }
        
        Log.d(TAG, "onStart end ");
    }
    
    @Override
    public void onResume() {
        super.onResume();
        setListAdapter(new ProviderTestList(this, R.layout.provider_list, this.list));
    }
    

    class ProviderTestList extends ArrayAdapter<ArrayList<ContactPojo>> {
        private Context mContext;
        private ArrayList<ContactPojo> list;

        public ProviderTestList(Context context, int textViewResourceId, ArrayList<ContactPojo> list) {
            super(context, textViewResourceId);
            this.mContext = context;
            this.list = list;
        }
        
        @Override
        public int getCount() {
            return this.list.size();
        }

        @Override
        public long getItemId(int position) {
            return position;
        }
        
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            
            View row = convertView;
            ViewWapper viewWapper = null;
                
            if (row == null) {
                LayoutInflater inflater = getLayoutInflater(); 
                row = inflater.inflate(R.layout.provider_list, parent, false);
                viewWapper = new ViewWapper(row);
                row.setTag(viewWapper);
            } else {
                viewWapper = (ViewWapper)row.getTag();
            }
            
            
            ContactPojo contactPojo = (ContactPojo)this.list.get(position);
            
            viewWapper.getDispName().setText(contactPojo.display_name);
               
            contactPojo = null; // release
            
            return row;
            
        }
    }
        
    /**
     * ホルダーパターンView
     */
    class ViewWapper {
        
        View base;
        TextView disp_name;
        
        ViewWapper (View base) {
            this.base = base;
        }
        
        TextView getDispName() {
            if (disp_name == null) {
                disp_name = (TextView)base.findViewById(R.id.disp_name);
            }
            return disp_name;
        }
        
    }
    
}

一覧を表示するように、ListActivityで作成してます。

特に重要なのは
  • getContentResolverでContentResolverを取得していること。
  • Cursorオブジェクトを取得していること。
です。

続いて表示xmlのprovider.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
     <ListView 
         android:id="@id/android:list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
        
     <TextView 
        android:id="@id/android:empty" 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:text="データはありません"  />
        
</RelativeLayout>

加えて、リストxmlのprovider_list.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    
    <TextView 
        android:id="@+id/disp_name" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        />
        

</RelativeLayout>

上記のソースをビルドして実行します。

上記のような感じで出力されます。

ContentResolverのqueryで指定してる「Contacts.CONTENT_URI」が電話帳のデータにアクセスする為のURIです。Contacts.CONTENT_URIのURIの形式を取得してみましょう。以下が結果。
  • URIスキーム(Contacts.CONTENT_URI.getScheme()):content
  • ホスト名(Contacts.CONTENT_URI.getHost()):com.android.contacts
  • パス(Contacts.CONTENT_URI.getPath()):/contacts
となります。…というか、URI違うじゃん。調査したところ、androidのversionによって違うみたいです。
確認のために、自分でURIを作成してアクセスしてみます。

getContentResolverの後ろのコードに以下の処理を追加します。

ContentResolver resolver = this.getContentResolver();
    
    Uri.Builder builder = new Uri.Builder();
    builder.scheme("content");
    builder.authority("com.android.contacts");
    builder.path("contacts");
    
    //Cursor c = resolver.query(Contacts.CONTENT_URI, new String [] {Contacts.DISPLAY_NAME} , null, null, null);
    Cursor c = resolver.query(builder.build(), new String [] {Contacts.DISPLAY_NAME} , null, null, null);
        

ビルドして実行します。
同じ結果になりましたね。

以上の処理から理解できるのは、URIで電話帳にアクセスすることができ、結果をCursorオブジェクトで取得していることですね。

気になるのは、ContentProviderがCursorを返す仕組みになっていることです。
データベースを通さない処理の場合はどうするのでしょうか…。また、intentを利用する仕組みとどう関連があるのか…。

とにかく、ContentProviderは理解したのでLinkifyとintentを関連付けるサンプルを作成していきます。

3、Linkfyサンプルを十分に読み込んで実装していきます。

参照するのは

http://android-developers.blogspot.com/2008/03/wikinotes-for-android-routing-intents.html

です。

まずは文字列リンクを作成します。

getViewメソッドのContactPojoオブジェクトを取り出している下に、以下のコード処理を追加します。

ContactPojo contactPojo = (ContactPojo)this.list.get(position);
    
    // viewWapper.getDispName().setText(contactPojo.display_name);
    
    Pattern matcher = Pattern.compile("テスト");
    viewWapper.getDispName().setText(contactPojo.display_name);
    String viewURL =    "content://jp.co.sample.android.muzukashii/name/";
    Linkify.addLinks(viewWapper.getDispName(), matcher, viewURL);

ビルドして実行します。

おお、リンクが作成されましたね。

次はAndroidManifest.xmlに

<provider android:name="jp.co.sample.LinkTestProvider" android:authorities="jp.co.sample.android.muzukashii" />

を追記します。

  • android:authoritiesは、URIのホストと同じ意味です。URIのROOTとして扱われます。
  • android:nameはjavaクラスのフルパスを指定します。

では、呼び出されるLinkTestProviderクラスを作成していきましょう。このクラスでは、ContentProviderクラスを継承します。

注意すべき点は、updateやinsertをOverrideする必要があるということです。なんかずさんな抽象化ですね。DB使わない人もいるでしょうに。

気持ち悪いけどここは無視して作成します。で、作成したのが以下のコードです。

public class LinkTestProvider extends ContentProvider {
    
    public static final String TAG = "LinkTestProvider";
    
    public static final String AUTHORITY =
            "jp.co.sample.android.muzukashii";

    
    private static final int NOTE_NAME = 2;

    
    private static final UriMatcher URI_MATCHER;


    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }

    @Override
    public String getType(Uri uri) {
        switch (URI_MATCHER.match(uri)) {
          
        case NOTE_NAME:
            
            return "hatoyama.kan.owawa/minsyu.kiero";

        default:
            throw new IllegalArgumentException("Unknown URL " + uri);
        }
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        return null;
    }

    @Override
    public boolean onCreate() {
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        return null;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        return 0;
    }
    
    static {

        URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
        URI_MATCHER.addURI(AUTHORITY, "name/*",
                           NOTE_NAME);

    }

}

上記のコードで重要なのは、staticとgetTypeメソッドです。
  • staticでUriMatcherにURIを作成しています。
  • 投げるURIに応じたUriMatcherを全て作成します。
URIはProviderTestのgetViewメソッドに追加した以下のソースと対応しています。

Pattern matcher = Pattern.compile("テスト");
    viewWapper.getDispName().setText(contactPojo.display_name);
    String viewURL =    "content://jp.co.sample.android.muzukashii/name/";
    Linkify.addLinks(viewWapper.getDispName(), matcher, viewURL);

getTypeメソッドで、Uriを振り分ける処理を行っています。
色々なパターンで分岐可能なので、以下の公式サイトのソースを参考にしてみてください。

http://developer.android.com/reference/android/content/UriMatcher.html

上記のソースではcase NOTE_NAME:に処理が入り、「hatoyama.kan.owawa/minsyu.kiero」文字列が返却されます。

この文字列はMIMEタイプを表しています。なので、このMIMEタイプによって呼び出されるActivityクラスを作成するようにします。

作成したのが以下のクラスです。

public class GoalActivity extends Activity {
    
    private TextView sendparam;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.goal);
        
        this.sendparam = (TextView)findViewById(R.id.sendparam);
        
        Intent intent = getIntent();
        Uri uri = intent.getData();

        if (uri != null) {
            this.sendparam.setText(uri.getPath());
        }

    }
    
    @Override
    public void onStart() {
        super.onStart();
    }
    
    @Override
    public void onResume() {
        super.onResume();
    }
}

上記の処理では、URIのパスを取得して画面に表示しています。

続いて表示xmlのgoal.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    
    <TextView 
        android:id="@+id/sendparam" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        />
        
</LinearLayout>

最後にandroidManifest.xmlにGoalActivityのintentを設定します。

<activity android:name=".GoalActivity"
                  android:label="@string/app_name">
            <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:mimeType="hatoyama.kan.owawa/minsyu.kiero"/>
            </intent-filter>
        </activity>

intent-filterを設定します。android:mimeTypeは、LinkTestProviderクラスのgetTypeメソッドで返すMIMEタイプ文字列に対応します。

では、上記のソースをビルドして実行します。
続いて、リンク文字をタップします。

おお。見事にActvityが呼び出されて画面遷移できましたね。

URIのpathもきちんと取得できています。

上記の処理から理解できるのは、
  • 文字リンクのパターンを利用して特定のURIを作成することで、activityの呼び出しを制御できる。
  • Providerクラスで受けとったURIをgetTypeメソッドで分岐し、任意のactivityを呼び出すことが出来る。様々なパラメーターも付加出来る。
これまでやってきたことを応用することで、WEBのような処理を行うUIが色々作れそうですね。

かなり長くなってしまいましたが、これで終了です。お疲れ様でした。

android開発にそれなりに通じていないと、内容的に少し難しかったかもしれませんが、すごく役に立つパターンだと思うので、是非勉強してみてください。

みなさんが素晴らしいアプリを開発して、僕を唸らせてくれることを期待しています。

でわ。

追伸

URIの概念がよくわからないという人は以下の書籍がオススメです。WEB開発に携わるエンジニアは是非是非読んでもらいたい名著です。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

バラク・オバマどっとこむに学ぶWEB構成

Google app engineやAmazonのサーバーをはじめ、色々なクラウドが格安で利用できるので、ソーシャルサイトでも構築しようかと考えています。しかし、これまでにWEBサイトは構築してきましたが、あまりソーシャルサイトは利用したことがありません。
ということで色々と勉強していこうと思っています。
まずは、FaceBookの創業者でオバマのインターネット戦略担当を務めたクリス・ヒューズの手法を参考にするために、バラク・オバマどっとこむの研究とまとめ。

・ベースの色は青色
青色は、知性と精神に関する重要な色彩で、創造性、心のコントロール、頭の回転などを高める。演説が必要なときなどに大きな力を発揮したり、コミュニケーションを円滑にする効果があるとのこと。


http://homepage2.nifty.com/osiete/s590.htm

・言語はphp
まあ、ざっくりつくるのには適してますね。私はphp嫌いなのでパス。

・構成のメモ書き

------------------------------------------------------
header
------------------------------------------------------
navi
------------------------------------------------------
recommned comtents(4つ)                             | 寄付
(数秒ごと)                                                   |
------------------------------------------------------
main                                                           | aside bar
                                                                 |
                                                                 |
                                                                 |
                                                                 |
------------------------------------------------------
footer
------------------------------------------------------

・他に気がついたこと。
naviにstoreがあって収益にしているw。日本の政治家が同じようなことしたら叩かれるな。

・利用しているネットワークメディア
faceBook
twitter
Youtube
Flickr
MysSpace
Black Planet
MiGente
Linkedin

使いすぎ。普通の個人なら

faceBook
twitter
Youtube
Flickr

でいいんじゃないんでしょうか。

・Blogのshare
Digg
FaceBook
Newsvine
Stumble
del.icio.us

とりあえず、ブログ構成も色々と良いパターンをためしていくつもりです。
少しうっとうしく感じるかもしれませんが、より良い情報とUIご提供のためしばらくはご容赦ください。

でわ。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年2月26日土曜日

プログラマ(ITエンジニア)の勉強方法

プログラマは継続的な勉強が必要です。
もちろんプログラマに限らず、どの知的職(ホワイトカラー職)は同じことが言えるでしょう。
しかし、ここではあえてプログラマに焦点を絞ります。
プログラマはどのような勉強をすべきなのでしょうか。

例えば、私のようにソフトウェアの実装・設計・仕様策定を主な業務としているような人は自宅でも何かしらのアプリを作成するべきだと思います。アプリをスクラッチから設計・作成・リリースすることで、技術、管理、マーケティングの力がバランス良く身につきます。
 特にマーケティングやマネタイズ等は、プログラマが業務で関わる割合は低いのが一般的なので、自己で学んでいくべきです。

世の中には色々なタイプの人がいて、資格の勉強をする人、ただ単にサンプルプログラムを書いて勉強する人、何もしない人がいます。

何もしない人はそもそもプログラマという仕事に向いてないと思います。というよりはホワイトカラーに向いてない。

資格の勉強をする人は、真面目で定型的なサラリーマンという人が多い気がします。彼らを観察していると、基本的に彼らは仕事ができないというわけでもなく、特別有能というわけでもありません。常になにかしらの不満を抱えていて、他の会社への転職を考えています。だから勉強はそれなりにする。でも、転職しても、給料があがっても、不満は解消されなくて、常に不満たらたらな人達です。
ようは、自分に合ってない仕事に就いているけど、そこそこ仕事がこなせてしまうので、なんとなく続けてる。器用貧乏と言えるかもしれません。自分の能力、仕事、やりたいことの結合度が低いのです。

サンプルプログラムを書いて勉強する人は、仕事が好きなひとに多いです。仕事が出来る人が多いですが、できない人もいる。
一番扱いに困るのがこういったタイプで仕事の出来ない人です。利益を出すのがビジネスという意識が低く、アウトプットとインプットのバランスがめちゃくちゃなのです。
「無能な働き者は銃殺せよ」
という言葉がありますが、まさしくその通りです。
基本的に対処方法は無く、私の場合は、同じチームにならないようにただただ祈るだけです。

プログラマの勉強で大切なのは、自分がどういったキャリアを積んでいきたいかだと思います。
 私が何も勉強しない人が問題外だと思うのは、自分のキャリアを会社の業務内容に完全に委ねてしまうからです。
 これはあまりに危険です。今の日本の会社の仕組みでは、余程運がよくない限り社畜という生き物に変身するだけです。
どういうキャリアを歩みたいかが、勉強する内容を決めるというのは、考えてみれば当たり前のことですね。イチローになりたいのに、松井秀喜になる練習を重ねても効果は薄いでしょう。根底の基礎となる部分は同じでも、積み上げていく強みの部分は自分で意識していく必要があります。

結論は、一番重要な勉強は、自分を知る勉強ってことですね。
全然答えになってません。私も、日々悩んでいるのですw。
凡人はつらいです。「苦悩とは飛躍なんです」なんてイチローみたいにかっこよく言ってみたいです。

でわ。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年2月24日木曜日

当たり前度をあげていくということ

業務や技術のレベルがあがるほどに、基礎技術・基礎知識の重要さを感じている今日このごろです。この傾向は、今後の社会でさらに顕著になっていくでしょう。
なので、常に能力をあげていく必要があります。
向上させていきたい能力は沢山あります。しかし、全ての能力をあげることなど不可能です。
今後身につけたい能力は山ほどあるのが実情です。

そこで、今後は当たり前に出来ることを少しづつ増やしていこうと思っています。
つまり基礎の習得と積み上げ。あとは反復です。

もちろん今年力を入れている
android、iphone、google app Engine等の勉強は引き続き行っています。

しかし、そのほかに最近は基礎を積みあげる時間を多めに取るようにしました。
今は3D数学、英語、中国語の基礎を積み上げています。
取り組み方としては、ひたすら同じ参考書を反復・暗記(計算)しています。体に覚えこませるまで反復しようと思っています。
体力を維持するトレーニングもかなり基礎的な動作から毎日トレーニングを行っています。

当たり前度を高くしておかないと、今後色々と世の中に振り回されるようになる。
そんな気がしているこの頃であります。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年2月19日土曜日

Android Tips Activityの挙動

Activity, GroupActivity, SeacrhBarを複合させたアプリ作成時に、挙動で色々とはまったので今後のためにメモ。
はまった時に基本に立ち返るのはやっぱ重要ですね。もっと基礎を固めないと…

osは現在メインで開発している2.1、エミュレータは2.3で確認

1、まずは基本。

1.1、画面表示までに呼び出しが行われるメソッドの流れ

onCreate

onStart

onResume

画面表示

1.2、onNewIntent()メソッドの使い方。

search barで使用するときにちょっと挙動にとまどいました。
このメソッドは一度目のActivityの起動では呼び出されません。二度目以降に呼び出されます。

つまり、


上記のような遷移の場合、画面Aから画面Bに遷移する時には、onNewIntent()は呼ばれません。それがたとえ、

Intent intent = new Intent(this, 画面B.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);


のように画面Aのコード内でFLAG_ACTIVITY_SINGLE_TOPを指定してもです。
onNewIntent()が呼ばれるのは、画面Bから画面Bにアクションを行う場合のみです。
この時、FLAG_ACTIVITY_SINGLE_TOPを指定します。

public void onClickButton(View view) {
Intent intent = new Intent(this, 画面B.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
}

この時画面BのActivityで呼び出されるメソッドは
onNewIntent

onResume
の順序となります。

覚えておいて欲しいことは、stackには遷移前の画面Bは積まれないということです。
デバイスの戻るを押した場合には、画面Aに戻ります。
ちなみに、コード内でIntent.FLAG_ACTIVITY_SINGLE_TOPを指定しなくても、android:launchMode="singleTop" をAndroidManifest.xmlに指定すれば同じことです。
むしろ、こちらのほうが可読性が良いのでオススメします。

1.3、Intent.FLAG_ACTIVITY_CLEAR_TOPを使ったActivityの挙動を理解する

activityはstackの形式で蓄積されます。例えば、以下のような画面遷移があるとします。

上記のような画面遷移を行うと、stackにはA, B, C, D, Bの順でactivityが積みあげられます。なので、画面Bでデバイスの戻るを押すと、

D→C→B→A

の順番で画面が戻っていきます。
しかし、このデフォルトのactivityの仕様だと非常に困るときがあります。
 例えば、画面Bが通常画面、画面Cがユーザデータの入力画面、画面Dがユーザ入力項目の確認画面と仮定しましょう。
画面Dでボタン押下後にデータベースに登録して画面Bに戻る処理を行います。この時、画面Bに戻った後にデバイスの戻るを押されると、画面Dに戻ってしまいます。そこでユーザが登録ボタンを再び押せば、二重登録処理となってしまいます。バリデーションが実装されていてもこれは問題でしょう。このケースの場合、画面Dから画面Bに遷移する場合は、画面Cと画面Dのactivityはstackから消えていなければいけません。

こういった場合に使うのが、Intent.FLAG_ACTIVITY_CLEAR_TOPです。この例の場合だと、画面Dから画面Bに遷移する場合に以下のようにコードを記述する

public void onClickButton(View view) {
Intent intent = new Intent(this, 画面B.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}

こうすることで、画面Bに遷移したときstackの中身はA, Bになります。CとDがstackから削除されます。これなら、デバイスの戻るを押されても、画面Aに戻るだけです。

色々な使い道があるので、googleのマニュアルにも目を通しておくといいでしょう
http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP

疲れたので、今回はとりあえずこんな所です。
でわ

android開発オススメ書籍

Effective Javaのような本だと思って購入する面食らうと思います。 この本はTIPS集です。複数のandroid案件を抱えているなら、側に置いておくと役に立つと思います。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年2月14日月曜日

Android,iphone スマートフォンのビジネスモデル

Androidとiphoneの普及により、日本でもスマートフォンの普及が広がっています。
そして、ユーザ数の増加に比例して、スマートフォンをプラットフォームに据えたビジネスに取り組む企業や人が増えてきています。

しかし、気になることもあります。
その殆どが「日本のみをターゲット」にしたビジネスモデルなのです。
そして安定して利益を出している仕組みは、ほとんどが「月額課金」のモデルです。
ソーシャルゲーム、携帯アプリ。最近ではブログで有名になった人のメルマガの発行が目立ちます。

月額課金の強みは、デッドユーザが存在することです。つまり、すでにサービスを利用していないのにお金を払い続けている人が一定以上存在することです。

私は別にこのビジネスモデルを批判する気はありません。新聞購読、NHK料金、携帯料金、全て同じ仕組みです。貨幣社会の現在では、お金が継続的に流れる仕組みは絶対に必要です。お金の流れが止まれば、社会が停滞してしまいます。
私が気になるのは前者。つまり、「日本のみをターゲット」にしたビジネスモデルです。

不況とはいえ、日本にはまだまだ大量のお金が溢れています。
一億人を超える日本語のみのマーケットは十分に大きく、海外でのビジネス展開は考えにくいのが現状です。
ですが、これは小さなパイの潰しあいで、これ以上の市場の成長が見込めません。
日本のIT技術者の待遇が悪いのは、日本の労働システムの問題もありますが、生産性の悪さと、市場が広がらないことにも原因があると思います。
車産業と同じように、ITビジネスも海外を見据えたビジネスに転換していくべきですし、スマートフォンの普及はちょうどいい機会だと思います。
とはいえ、現在の日本のIT企業に海外展開を望むのは無茶でしょう。特に大手ではまず不可能。かといって、メディアも保守的で期待できません。アルファブロガー達も完全に日本市場メインです。
やはり海外市場への進出は、技術力の高い個人やベンチャーが少しずつ市場を切り開いていくしかないと思います。

今後私は、海外展開を含めたビジネスモデルもいくつか試していきたいと考えています。
今はクラウド化が進み、ほぼ無料で、サラリーマンをやりながら誰でもビジネスを展開できる世の中です。
それなりの技術レベルがあれば、いつでも開始できるでしょう。
我々技術者は、もうちょっと貪欲に海外にちょっかいをだしていくべきだと考えています。

そんな感じの現状報告でした。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年2月11日金曜日

Android市場の拡大 スマートフォンビジネスモデルの考察

Androidの市場が拡大してきました。
来年くらいには、Androidでも利益を見込めるようなビジネスもちょこちょことでてくるのではないでしょうか。

私も技術の勉強と平行して、マーケティングの本を読み始めました。
こういったマーケティングみたいな勉強はあまり好きではないのですが、会社の一構成員としてはそうもいってられません。
マーケットを海外に全部取られて、中国とかに出稼ぎにいくようになるのはさすがに嫌なので。

個人アプリは趣味なので、たいして利益が出なくても構わないのですけどね。(新しい個人アプリに取りかかりましたよ~)

というわけで、これからは技術の情報だけでなくWEBのビジネスについても扱っていきたいと思います。
主に、スマートフォンやSNS関連になると思います。

新たなビジネスモデルの実験も色々と行っていきたいと思います。

というわけで今回は
iphone版産経新聞アプリの情報です。

http://www.sankei-digital.co.jp/advertising/pdf/iphone_userdate/110203.pdf

ユーザの平均年収が高いですね。
個人的には、ソーシャルゲームみたいな搾取システムより、こっちのほうが好みです。
ソーシャルゲームほどは稼げませんが、ビジネスアプリは安定しているのが特徴です。
スマートフォンアプリの開発者・開発を考えている人は、是非目を通してみてください。

でわ。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年1月28日金曜日

Facebook Creditという仮想通貨 ~錬金術は銀行からエンジニアへ~

最近、FaceBookの動きが活発です。
今年は本格的にFacebook Creditを導入する計画らしく、個人的にとても注目しています。

お金の価値は、金額ではなく信頼性にあります。
5億人を超えるユーザーがいるFacebook Creditという仮想通貨の信頼性が高まれば、そこらへんの新興国の通貨より価値が出てくる可能性もあります。

今後は、各社のスマートフォンにNFCが対応していきます。それは、Facebook Creditとスマートフォンが連携し、現実の通貨として利用できる時代の到来を予感させます。
 
 日本では、FaceBookはあまり使われていないのが現状です。私もユーザ登録はしていますが、周囲の人が使ってないので、やはり利用頻度は低いです。
 しかし、これがFacebook Creditの導入により、コンビニやスーパーの決済で利用できるようになったら、話は別です。
 Facebook CreditがスマートフォンのNFCにより管理が可能となり、現実世界で利用できるようになれば、FaceBookはあっというまにSNSのNo1プラットフォームに躍り出るでしょう。
これは十分にありえる話です。セブンイ○ブンとか普通にやりそうですw。
 もしそういう動きが起これば、私はすぐにFaceBookのアプリを作ります。サービスの課金は当然Facebook Credit。財政破綻が予想される日本円は使いません。リスク分散としても申し分ないです。税金は…かかるのかな??この場合どう計算するのでしょうかね。

 そのうちに、日本円で三千万の家が、二千万FaceBook Creditで売り出されるような時代がくるのかもしれません。(私は法律には疎いのでこれが法に違反しているかどうかはわかりません)。そうなればちょっとした世界通貨ですね。paypalはお役ご免です。
 
上記の事柄が現実になった世界では、エンジニアの目指すキャリアの最終目標も変わってきます。これまでは作成したサービスを浸透させて、巨万のお金を「得る」のが普通でした。しかしこれからは、サービスを浸透させて、お金を「作る」という時代が到来です。

こうなれば現在の銀行による世界支配の時代を終わりにできるかもしれません。
銀行のビジネスモデルは、みなさんが既に理解している通り、お金を貸して利子や手数料を稼ぐというものです。
 これはものすごく洗練されたビジネスモデルです。
 利子は100万円を110万や、時には150万円へと増やします。しかも、元手の100万円は、お客から集めたお金です。
 つまり銀行とは、お客のお金をお客に貸し出し、利子や手数料で稼ぐというビジネスです。よくITを実態のない虚業といって批判する人がいますが、銀行に比べたら全然です。
 銀行は借金という負債を、人の金で生み出す究極の虚業です。

 色々とよくない話もあるFacebookですが、世の中を大きく変えてくれるんじゃないかという期待があります。
Facebook Creditのような仮想通貨が広まれば、私たちの働き方・企業のあり方も大きく変わるでしょう。特に、WEBは若い世代の利用が中心で、既得権だらけの老年層や政治家の理解が浅いというのは大きな利点です。彼らが理解できないうちに、世の中のルールを変更してしまうことが可能だからです。

新興国の急速な発展で世の中の構造が変わってきていますが、こういった場でも徐々に世の中は変わってきています。
「英語の社内公用語化は失敗する」「ほとんどの人は英語が必要ない」
とかいっている日本は平和というか暢気ですよね。
間違いなく、世界は新しい方向へと向かっています。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年1月26日水曜日

Android Tips keyboardの挙動メモ

keyboardの特定ボタンを押した場合に、特定のアプリを呼び出すという実装を試しました。
キーボードアプリとして、Googleのサンプルキーボードアプリを実装しました。
その際、調査のため色々といじくりまわしたので後学のためにメモを残します。
今後役に立つかは微妙ですが…私はキーボードアプリを作る気ゼロなので。

・Keyクラス

キーボードのキーの文字とポジションを描写するクラスである

qwerty.xml

<Row>
<Key android:codes="99" android:keyLabel="c"/>
<Key android:codes="118" android:keyLabel="v"/
</Row>


というqwerty.xmlがあるとすると、
キーボードの「c」を押下した場合、

KeyboardViewListenerを実装したクラスの
public void onKey(int primaryCode, int[] keyCodes) メソッドの
primaryCodeで

99

が取得できる。

また、
public boolean onKeyDown(int keyCode, KeyEvent event) メソッドの
keyCodeは

31(KeyEvent.KEYCODE_C)

が取得できる。

EditText上にカーソルがある状態でキーボードを押下すると、

onKey()

が呼ばれるようだ。

エミュレーターのキーボードを押すと
onKeyDown()

translateKeyDown()

onKey()
の順番で呼び出される。

onKey()以降でメイン処理が行われているようだ。

スペースキーを押すと、
onKey()

sendKey()
と呼び出される。

onKey()の中では、isWordSeparator()がtrueになる。
isWordSeparatorはstrings.xmlのword_separators属性で指定している。
InputConnectionクラスのcommitTextメソッドで、word_separators属性で指定した文字を設定している。

以降は、自分のやりたかった処理。
キーボードの「a」が押された場合に、他アプリのHelloWorldを呼びだす(aの文字はテキストエリアに挿入しない)。

onKeyメソッドに以下の処理を追加した。


public void onKey(int primaryCode, int[] keyCodes) {

if (primaryCode == 97) {
// a押下
String clazz = "co.hoge.sample.Test";
Intent intent = new Intent(Intent.ACTION_MAIN);

int idx = clazz.lastIndexOf('.');
String pkg = clazz.substring(0, idx);

intent.setClassName(pkg, clazz);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

startActivity(intent);
} else if () {
// 以降変更なし
}

}


とすると、co.hoge.sample.Testが起動する。
加えて、co.hoge.sample側のアプリのAndroidManifest.xmlファイルのIntentFilterに
android:schemeとandroid:hostを指定してやると、なお良い。

以上。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

今後プログラマーに求められそうな能力 

前回の言語編に続いて、今回は能力編です。
とはいえ今日取り上げる能力は、プログラマーも他の職業も、そんなに変わらないのではないかと思います。

・コミュニケーション力

当然ですね。人は、一人では生きていけません。
今後はリアルな周囲の人間環境だけでなく、ネットを介した繋がりも重要になり、ソーシャルメディアを活用するのが当たり前になるのではないでしょうか。

・会計(簿記)

ざっくりとしたお金の流れは知っておく必要があると思います。
簿記の資格をとるとか、公認会計士の勉強をするとかいう意味じゃありませんよ。
BS、PL、CFくらいは読めるようにしておきましょうということです。
結構見かけるのは「簿記2級まで取得したけど、内容はもう忘れた」みたいな人。これでは全く意味がないと思います。
おすすめなのは、ちょっとした金額で投資をはじめて、財務諸表に目を通すことです。基本的なことだけ勉強すればいいと思います。

・プレゼン力

自分を売り込む力を鍛えましょう。
日本と違い、グローバル社会では、謙譲の心は美徳じゃないですからね。
とことん攻めるべきです。

・マネジメント

既存の日本の会社の管理職のような、いい加減なマネジメントではありません。
きっちりとした体系だったマネジメントスキルを身につけましょう。

・数学・統計分析

これは今後エンジニアに要求され、なおかつ高給に繋がる能力だと思います。
当たり前ですが、受験勉強の数学ではありません。
3Dで扱うベクトルや行列、ビジネスに有効なデータを抽出する統計分析の力等です。


こんなところでしょうか。
色々ありすぎですね。もちろん全部身につけるなんて無理に決まっています。
時代の流れを読んで、自分の強みに合った能力を身につけるべきです。
ネットの発達と技術の進化で効率的に学ぶことが出来るようになったのに比例して、人に期待される能力はあがる一方になっています。
この傾向はしばらく続くでしょう。
20年を超える先の時代の社会は想像すらつかないので、生涯続けられるスキルを臨機応変に身につけることが必要になってきます。

さてさて、どんな未来が待っているのでしょうか。
でも、必死でくらいついていけば、きっとワクワクで素敵な未来が待っている。そんな気がします。

でわん

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年1月24日月曜日

今後プログラマー(ITw技術者)に求められそうな言語

社会の流れが速すぎるこの頃。
今日は、今後プログラマーに求められる言語についてぼんやりと考えてました。
以下が結論。

・Java

これは必須ですね。すでにCと並ぶ基本言語ですね。

・Objective-C, C、C++等のC系

Objective-CはMac・iphone・ipad次第ですね。ただ、固定ファンが多く、お金が流れる市場がきちんと確立しているので、
趣味のソフトウェアでお金を稼ぐなら、Objective-C,やCに力をいれるほうがいいでしょう。
趣味プログラマーは絶対こっちがおすすめ。

・python

ダークホース。海外のフリーソフトをいじくりまわす人は必要だと思います。

・HTML5, css3, javaScript

多分5年後には、javaを抜いてメイン言語になりますね。まず間違いないでしょう。
javaやCはあくまで、HTML5, css3, javaScriptで出来ないことを実装するための補助的な言語になるでしょうね。
プログラマー的にはあまり想像したくない未来です…。でも、多分間違いないです。

・英語

すでに英語は必須ですね。
そもそも今でもandroid、objective-C、Html5を勉強するには、ある程度できないと話にならないです。
プログラマーうんぬんではなく社会人として必須になるでしょうね。
新卒のTOEICでの足切も本格的に始まるんじゃないでしょうか。

・中国語

職場でも中国の人がだいぶ増えてきました。
今は日本語を話せる中国の方が来てくれていますが、いずれ中国語が必要になるのはもう明らかな状況です。
ネット上の情報も飛躍的に増えてきてるので、中国語の習得は避けられないでしょう。
今の共産中国バブルが崩壊しても、シンガポール、香港、台湾は力を増大させ続けるでしょうから。
ただ、企業が就職要件として必須にするまでは10年くらいは猶予があると思います。
みなさんもちょこっとづつはじめましょう。ピンインからがっつりと。

・スペイン語

20年後先を見るならスペイン語も必要でしょう。
世界の三大言語は、英語・中国語・スペイン語になるのはほぼ決定的です。
ただ、スペイン語は日本語と相性が良いので、英語程習得に時間がかからないのではないでしょうか。
基本文法しかやったことないからわかりませんがw

と言語に関してはこんな感じではないかと。
つーか、もっと頑張れ日本。できれば、日本で快適に住み続けられる世の中を望みます。
でも、実際はかなり厳しそうですからね。
政府が法人税とかの前に、老人の負担を若者に被せる今の仕組みを変えないとダメでしょうね。
政治家が老人な時点で絶望的かと。

小泉Jrの奇跡に期待するか…。

次回は、言語でなく能力について書いてみようかと思ってます。
でわん。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年1月23日日曜日

Android Tips

今後も再利用しそうな実装の簡単なメモ書き

アンドロイド機種端末の取得

String model = android.os.Build.MODEL;

とすると、model変数に端末名が設定される。

ListViewでグループ分けをする

isEnabledメソッドを利用する


class SampleActivity extends ListView {

// ListViewの処理

class SampleList extends ArrayAdapter<ArrayList<String>> {

private Context mContext;
private ArrayList<ContentsCategoryBean> list;

public ContentsCategoryList(Context context, int textViewResourceId,
ArrayList<ContentsCategoryBean> list) {
super(context, textViewResourceId);
this.mContext = context;
this.list = list;
}

@Override
public int getCount() {
return this.list.size();
}

@Override
public long getItemId(int position) {
return Long.valueOf(this.list.get(position).id);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

if (!isEnabled(position)) {
// 処理false
} else {
// 処理true
}

return row;
}

@Override
public boolean isEnabled(int position) {

// 処理
// trueとfalseに分岐して返す

return true;
}
}
}


isEnabledメソッドの中で、列のデータによるグルーピングを行うのがポイント。

TABを画面下に設定する

AndroidのTABを画面下に設定するやり方です。
layoutの構築は、ここではRelativeLayoutを使います。LinerLayoutでも可能ですが、私は使わないのでここでは記述しません。



<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:layout_above="@android:id/tabs" />

<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />

</RelativeLayout>
</TabHost>



ポイント
・FrameLayoutタグはコンテンツの位置なので、TabWidgetの上に配置する
・Tabを画面下に配置するのだから、TabWidgetタグは当然FrameLayoutの下になる。

以上で~す。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年1月19日水曜日

Androd Tutorial iphone風の画面作成 その4

前回は背景や画像の調整を行いました。
今回は文字の調整を行います。

最初は表示タイトルを表示するTextViewのitme_titleから変更しましょう。

文字の調整はstyles.xmlを利用するべきです。layoutのxmlファイルに記述するのは、効率が悪い上に可読性も損なわれるので避けましょう。

styles.xmlはvaluesフォルダ内に作成します。記述内容は以下の通りになります。


<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="itme_title_style">
<item name="android:textSize">20sp</item>
<item name="android:textColor">#000000</item>
<item name="android:typeface">monospace</item>
<item name="android:textStyle">normal|bold</item>
</style>

<style name="itme_explain_style">
<item name="android:textSize">14sp</item>
<item name="android:textColor">#ff0000</item>
<item name="android:typeface">monospace</item>
<item name="android:textStyle">normal</item>
</style>

</resources>


以下に属性の説明を記述します。
android:textSizeはテキストのサイズを指定します。単位はpxでなく、spを使ってください。 spを使うことで、ユーザーが指定したフォントサイズが自動で拡大縮小されます。
スクリーンの解像度と指定したフォントのサイズを端末側でうまく調整してくれるのです。

もっと詳しく知りたい方はhttp://developer.android.com/guide/topics/resources/more-resources.html#Dimension を熟読してください。

android:textColorはテキストの色です。16進数で指定します。

android:typefaceはテキストの書体を指定します。
日本語の場合はmonospaceを指定し、英語はsansを指定するのが一般的です。好みの問題もありますが、これらが一般的には読みやすいとされています。
腕の良いデザイナーさんが近くにいる場合は、その辺をレクチャーしてもらうといいと思います。私はgimpやinkscapeを使って画像の作成もよく行うのですが、周りのデザイナーさんの影響は凄く大きいです。デザインの勉強は、プログラミングにも絶対プラスになります。って話がずれましたね。

android:textStyleはテキストのスタイルを指定します。
boldは太字です。他にはにitalic(斜体)も指定できます。

続いて、このstyles.xmlで指定した文字情報をhome_list.xmlに反映させましょう。以下のように指定します。


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff"
>

<ImageView android:id="@+id/image"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:adjustViewBounds="true" />

<TextView
android:id="@+id/itme_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/image"
style="@style/itme_title_style" />

<TextView
android:id="@+id/item_explain"
android:layout_width="190dip"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/image"
android:layout_below="@id/itme_title"
style="@style/itme_explain_style" />

<ImageView android:id="@+id/arrow_image"
android:layout_width="35dip"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:src="@drawable/arrow_button" />

</RelativeLayout>


赤の部分が変更した箇所です。style="@style/ + 属性名"で設定します。
さて、ビルドして、androidエミュレーターを起動しましょう。

Good!!
うまいこと表示されましたね。

次はヘッダーを追加しましょう。アプリケーションのタイトルバーも不要なので削除します。


public class HomeActivity extends ListActivity {

private File sdcardDir = Environment.getExternalStorageDirectory();

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.home);
}

// 以降変更なし

requestWindowFeature(Window.FEATURE_NO_TITLE);が追加されています。
これでアプリケーションのタイトルバーが消えます。
続いてheaderを追加します。画像を用意します。gimpで作成します。

だいぶ色が濃くなってしまいましたね。まあ、ご愛嬌ということでw。
ではheaderをリストの上に配置しましょう。


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/bg_home"
>


<TextView
android:id="@+id/header"
android:layout_width="fill_parent"
android:layout_height="40dip"
android:text="@string/header_home"
android:background="@drawable/header_home"
style="@style/header_home_style" />


<ListView
android:id="@+id/android:list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_below="@id/header" />

<TextView
android:id="@+id/android:empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/nodata"
android:layout_below="@id/header" />


</RelativeLayout>


注意して欲しいのは、ImageViewでなくTextViewを利用していることです。
画像に直接文字を記述したheader画像を用意するより、文字のない画像を用意したほうが汎用性があるのでお勧めです。

style="@style/header_home_style"で文字の調整指定を行っているので、styles.xmlに追加が必要です。


<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="itme_title_style">
<item name="android:textSize">20sp</item>
<item name="android:textColor">#000000</item>
<item name="android:typeface">monospace</item>
<item name="android:textStyle">normal|bold</item>
</style>

<style name="itme_explain_style">
<item name="android:textSize">14sp</item>
<item name="android:textColor">#ff0000</item>
<item name="android:typeface">monospace</item>
<item name="android:textStyle">normal</item>
</style>


<style name="header_home_style">
<item name="android:textSize">25sp</item>
<item name="android:textColor">#ffffff</item>
<item name="android:typeface">monospace</item>
<item name="android:textStyle">normal|bold</item>
<item name="android:gravity">center</item>
</style>


</resources>


赤の部分が変更した箇所です。
さて、ビルドして、androidエミュレーターを起動しましょう。

Good!!
うまいこと表示されましたね。
ただこうしてみると、header画像の背景に透過処理は不要ですね。今回は面倒なので、このままにしときますw。実際に作る場合は気をつけましょう。

あとは、個人的に分割線が気になるので、分割線を変更します。


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/bg_home"
>

<TextView
android:id="@+id/header"
android:layout_width="fill_parent"
android:layout_height="40dip"
android:text="@string/header_home"
android:background="@drawable/header_home"
style="@style/header_home_style" />

<ListView
android:id="@+id/android:list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_below="@id/header"
android:divider="#696969"
android:dividerHeight="2sp"
/>

<TextView
android:id="@+id/android:empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/nodata"
android:layout_below="@id/header" />

</RelativeLayout>


赤の部分が変更した箇所です。
android:dividerで分割線の色を指定、android:dividerHeightで高さを指定しています。
さて、ビルドして、androidエミュレーターを起動しましょう。

Great!!
色が濃い灰色に変更され、高さも変わりました。
とはいうものの、あまり違いがわからなくなってきたかもしれませんね。
これ以上はキリがないので、これでtutorialは終了です。
というわけで、長いチュートリアルをここまでつきあってくださったみなさん、大変お疲れさまでした。

今回私がこのチュートリアルを作成したのは、普段海外のチュートリアルに色々助けられていて、なにか自分にもできることがないかなと考えたのが発端です。
日本だと、tipsのようなちょっとした情報はたくさんあっても、チュートリアルのような作成に手間がかかる説明は少ないのが現状です。これは日本のエンジニアが置かれている無駄に長い労働環境が影響しているのかもしれません。
ただ、せっかく世界標準のandroidなのだから、こういった文化も世界標準にしていきたいです。

次は番外編でgimpを使ったandroid用画像の作り方なんかできたらなと思います。ちょっとした画像が作成できると、プログラマーは重宝すると思います。 gimpはフリーソフトだし、是非覚えておくといいと思います。

では、このへんで。みなさん素敵なandroid Lifeを。
See you next time.
Bye!

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年1月13日木曜日

Androd Tutorial iphone風の画面作成 その3

さて、今回は前回作成した画面をブラッシュアップさせていきます。

まずは背景を変更することからはじめましょう。
黒だとiphoneっぽくないですもんね。
ということで背景画像を作成します。ソフトはフリーソフトのgimpを使います。
android開発者なら、photoshopでなく、やはりフリーのgimpでしょう(お金かからないですからね)。
作成した画像は以下のファイルです。



gimpを使った画像ファイルの作成の仕方もそのうちtutorialにする予定ですが、今回は上記のファイルをそのままDLして利用してください。もしくは、他の画像を使って代用するなどしてください。

さて、これをhome.xmlの背景に設定しましょう。ファイルはdrawableフォルダに配置します。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/bg_home"
>

<ListView
android:id="@+id/android:list"
android:layout_height="fill_parent"
android:layout_width="fill_parent" />

<TextView
android:id="@+id/android:empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/nodata" />

</RelativeLayout>

android:background="@drawable/bg_home"で背景の設定を行っています。

レイアウトの変更なので、こまめに確認していきましょう。ビルドして、androidエミュレーターを起動させてみます。

Oh Yeah!!
しかし、リストの中の背景まで変わってしましましたね。
これだと見づらいので、リストの中の背景は白に変更しましょう。
リストの中の背景はhome_list.xmlに設定します。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff"
>

<ImageView android:id="@+id/image"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:adjustViewBounds="true" />

<TextView
android:id="@+id/itme_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/image" />

<TextView
android:id="@+id/item_explain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/image"
android:layout_below="@id/itme_title" />

</RelativeLayout>

android:background="#ffffff"を追加しました。
ビルドして、androidエミュレーターを起動します。

Oh Yeah!!
白になりましたね。

だいぶiphoneっぽくなりましたが、まだまだです。
iphoneはリスト列に矢印画像がありますよね。というわけで矢印画像も追加してみましょう。
背景と同じようにgimpで作成します。以下のような画像を作成してみました。

これをリスト画面で表示されるようにhome_list.xmlに追加します。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff"
>

<ImageView android:id="@+id/image"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:adjustViewBounds="true" />

<TextView
android:id="@+id/itme_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/image" />

<TextView
android:id="@+id/item_explain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/image"
android:layout_below="@id/itme_title" />


<ImageView android:id="@+id/arrow_image"
android:layout_width="35dip"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:src="@drawable/arrow_button" />


</RelativeLayout>

android:id="@+id/arrow_image"を追加しました。画像なのでImageViewです。
ビルドして、androidエミュレーターを起動します。

Oh Yeah Great!!
うまいこと表示されましたね。
さて、ここでは色々な属性を使ったので、重要な属性の説明をしておきましょう。

注意して欲しいのが

android:layout_centerVertical="true"

です。
これを

android:scaleType="center"

としてしまわないようにしましょう。
こうしてしまうと、画像は中央に配置されません。
android:scaleType="center"はあくまで、ImageViewオブジェクト内での配置の位置を決定します。layoutの位置を決定するわけではありません。
一方でandroid:layout_centerVertical="true"はlayoutの中での相対的な位置を示しています。ここでやりたいことはlayoutの中央に配置することなので android:layout_centerVerticalを設定するのです。
慣れないうちは、はまってしまうことが良くあるので注意しましょう。

さて、中央の説明文の文字が画像とかぶっているのが気になりますね。これも修正しておきましょう。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff"
>

<ImageView android:id="@+id/image"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:adjustViewBounds="true" />

<TextView
android:id="@+id/itme_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/image" />

<TextView
android:id="@+id/item_explain"
android:layout_width="190dip"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/image"
android:layout_below="@id/itme_title" />

<ImageView android:id="@+id/arrow_image"
android:layout_width="35dip"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:src="@drawable/arrow_button" />

</RelativeLayout>

android:layout_width="190dip"に変更しました。
ビルドして、androidエミュレーターを起動します。

ポイントはandroid:layout_width="190dip"ですね。この辺の値の感覚は慣れが必要です。
単位はspでもうまく動くのですが、layoutにはdipを使用するのが正式です。
このあたりのことは、次回の文字の調整で説明します。

というわけでまだまだ続きます。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年1月12日水曜日

Androd Tutorial iphone風の画面作成 その2

今回は、リスト画面を作成していきます。

まず、画面リストに表示するデータのクラスを作成します。 DataObjectクラスという名前で作成します。画面に表示するサンプルデータを5件返すgetDataObjectListメソッドも用意します。

public class DataObject {

public String id;
public String imagePath;
public String itme_title;
public String item_explain;

public DataObject() {
id = null;
imagePath = null;
itme_title = null;
item_explain = null;
}

public ArrayList getDataObjectList() {

ArrayList list = new ArrayList();

DataObject obj1 = new DataObject();
obj1.id = "1";
obj1.imagePath = "cat.jpg";
obj1.itme_title = "猫";
obj1.item_explain = "かわいい猫ですね";

list.add(obj1);

DataObject obj2 = new DataObject();
obj2.id = "2";
obj2.imagePath = "hinaningyo.jpg";
obj2.itme_title = "ひな人形";
obj2.item_explain = "明かりをつけましょぼんぼりに";

list.add(obj2);

DataObject obj3 = new DataObject();
obj3.id = "3";
obj3.imagePath = "kurisumasu.jpg";
obj3.itme_title = "クリスマス";
obj3.item_explain = "まっかなお鼻の。トナカイさんは";

list.add(obj3);

DataObject obj4 = new DataObject();
obj4.id = "4";
obj4.imagePath = "same.jpg";
obj4.itme_title = "鮫";
obj4.item_explain = "海の王者やね";

list.add(obj4);

DataObject obj5 = new DataObject();
obj5.id = "5";
obj5.imagePath = "sentouki.jpg";
obj5.itme_title = "戦闘機";
obj5.item_explain = "ばんばんばんばん";

list.add(obj5);

return list;
}

}

DataObjectクラスに用意した各フィールドに値を格納してリストとして返しています。内容は、

id:一意なキー
imagePath:画像のファイル名
itme_title:表示タイトル
item_explain:表示画像・タイトルの説明

となります。

表示する画像は、/sdcard直下に配置することにします。
EclipseのDDMでsdcardフォルダにドラッグするか、adbコマンドで格納しましょう。
(sampleコードを打ち込む場合は、適当な画像ファイルを上記のファイル名に変えて格納してみましょう)



配置すると上記のようになるはずです。

この時注意して欲しいのは、eclipseに画像をドラッグすると、日本語のファイル名だと失敗します。 adbコマンドだと日本語でもOKなのですが、基本的にファイル名に日本語を利用するのは避けるべきです。

次にリスト行のレイアウトファイルを作成します。 home_list.xmlという名前で作成します。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>

<ImageView android:id="@+id/image"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:adjustViewBounds="true" />

<TextView
android:id="@+id/itme_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/image" />

<TextView
android:id="@+id/item_explain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/image"
android:layout_below="@id/itme_title" />

</RelativeLayout>

ここでは、大まかにタグを配置します。細かい調整は後々行っていきます。
一応RelativeLayoutのタグの説明もしておきましょう。

id/itme_titleで設定しているandroid:layout_toRightOf="@id/image"は imageの右横に配置するという意味です。
id/item_explainで設定しているandroid:layout_toRightOf="@id/image"はimageの右横、 android:layout_below="@id/itme_title"はitme_titleの下。つまり、画像の右横かつ、タイトルの下に配置しています。 あとは、この作成したhome_list.xmlをHomeActivityクラスで呼び出すようにします。

public class HomeActivity extends ListActivity {

private File sdcardDir = Environment.getExternalStorageDirectory();

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
}


@Override
public void onStart() {
super.onStart();
}

@Override
public void onResume() {
super.onResume();
DataObject dataObject = new DataObject();
ArrayList list = dataObject.getDataObjectList();
dataObject = null; // release
setListAdapter(
new HomeListAdapter(this, R.layout.home_list, list));
}

class HomeListAdapter extends ArrayAdapter {
private Context m_context;
private ArrayList list;
private ExecutorService ex;

public HomeListAdapter(Context context, int textViewResourceId,
ArrayList objects) {

super(context, textViewResourceId, objects);
this.m_context = context;
this.list = objects;
}

@Override
public int getCount() {
return this.list.size();
}

@Override
public long getItemId(int arg0) {
return Long.valueOf(this.list.get(arg0).id);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
// 受け取ったビューがnullなら新しくビューを生成
LayoutInflater inflater = getLayoutInflater();

view = inflater.inflate(R.layout.home_list, parent, false);
}

// 表示すべきデータの取得
DataObject item = (DataObject)list.get(position);

ImageView image = (ImageView)view.findViewById(R.id.image);
Log.d("log", sdcardDir.getPath());
image.setImageBitmap(BitmapFactory.decodeFile(
sdcardDir.getPath() + "/" + item.imagePath));

TextView itme_title = (TextView)view.findViewById(R.id.itme_title);
itme_title.setText(item.itme_title);

TextView item_explain = (TextView)view.findViewById(R.id.item_explain);
item_explain.setText(item.item_explain);

return view;
}
}

}

赤字の部分が今回追加したソースコードです。
長いように思うかもしれませんが、やっていることは

ただ単にDataObjectクラスからリストデータを取ってきてhome_list.xmlのオブジェクトに設定している

だけです。
よく利用するパターンなので、何回か写経して覚えておくと良いと思います。

では、ここまでやったことが上手くいっているか、確認してみましょう。ビルドして、androidエミュレーターを起動させてみましょう。すると以下のような画面が表示されるはずです。

Oh Yeah Great Job!!
リストデータがきちんと表示されましたね。

次は画面の細かい調整を行っていきたいと思います。



というわけで、また次回。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2011年1月11日火曜日

Androd Tutorial iphone風の画面作成 その1

androidの開発をしていて、よく言われるのが、

「見た目をiphoneっぽくしたい」

という要求です。
androidなんだから、android推奨のインターフェース (http://dl.google.com/googleio/2010/android-android-ui-design-patterns.pdf) にするべきだと思うのですが、 iphoneのインターフェースが好きなんだという人はかなり多いです。
確かにiphoneのインターフェースは良い出来ですから、気持ちはわからなくもないです。

というわけで、iphoneっぽい画面の作り方を記載しておこうと思います。
これは本当に要求度が高いので、自分でも再利用できるように詳しい記述にしていこうと思っています。多分、結構長くなると思いますが、おつきあいをよろしくお願いします。

では、さっそくはじめましょう。

まずは、プロジェクトを作成しましょう。 androidのversionは1.6以上なら大丈夫ですが、もう2.1以上でもいいと思います。

立ち上げ時に起動する画面を作成します。HomeActivityクラスという名前で作成します。

public class HomeActivity extends ListActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
}
}

ListActivityクラスを継承していることに注意してください。

次にlayoutのxmlファイルをhome.xmlとして作成します。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>

<ListView
android:id="@+id/android:list"
android:layout_height="fill_parent"
android:layout_width="fill_parent" />

<TextView
android:id="@+id/android:empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/nodata" />

</RelativeLayout>

layoutのxmlファイルでUIを作成する場合、なるべくRelativeLayoutを使うようにしましょう。後々の修正が楽になります。 javaでのハードコードとか問題外なのでやめましょうね。後で改修する人が泣きます…。

ListViewの下に記述したTextViewタグは、ListViewにデータが存在しない場合に表示されるテキストメッセージです。

android:id="@+id/android:empty"

と指定するのが決まり事です。
表示されるメッセージは、android:text="@string/nodata"と記述したので、 strings.xmlに記載する「nodata」属性が反映されます。 では、strings.xmlファイルを以下のように書きかえましょう。

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">iphone風インターフェース</string>
<string name="nodata">データが存在しません</string>
</resources>

上記のようにすることでデータが存在しない場合に、strings.xmlに記載した「nodata」属性の文字が表示されるようになります。

では、ここまでやったことが上手くいっているか、確認してみましょう。ビルドして、androidエミュレーターを起動させてみましょう。すると以下のような画面が表示されるはずです。



Oh Yeah Great!!
思った通りの動きをしましたね。

さてさて次回は、リストの中身を作成していきましょう。
まだまだ続きます。おつきあいよろしくお願いします。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加
Related Posts Plugin for WordPress, Blogger...