2011年8月20日土曜日

[Windows Phone 7] アプリケーションの作成と起動

簡単に。
まずはVisualStdio2010(WP)を起動します。

で、見たことある感じの画面から
NEW Projectを選択するとこのような画面が出ます。


















なぜ、VBなんだ・・・。
というツッコミのもと、下のC#を選択します。
おそらくVBでもつくれなくはないのですが、エラーがでてとれなかったので(失格)、とりあえずこちらを。

















プロジェクト名に適当な名前を入れて(もちろんこのままでもいい)
OKを押すだけ。

あとは実行ボタンを押して待てばエミュレータが起動して
なにやらメッセージがでます。

終了。


というのもおもしろくないので
今回はコードはいじらずにデザイン画面からラベルを選択して
文字だけをいじってみました。

で、こうなる。























昔のHello Androidを思い出しますね、はい。

コードを書くときはそれぞれの配置したUIでクリックするなりなんだかんだりで
VisualStdion感満載でできるかとおもいます。

続きは後日。

[Windows Phone 7] 開発環境を整える

やってみることにしました。

OSはwindows7で。
Windows Phone 開発者向け技術情報 に飛ぶ

アプリケーション開発のところに
Windows Phone SDK 7.1 Beta 2
というリンクがあるのでジャンプ。

vm_web2.exe

をダウンロード。
ダウンロードしたファイルを実行するとインストーラーが走るのでまつべし。
私のパソコンはそんなに悪い性能ではないのですが、けっこうまたされました。
なのでコーヒー片手に本でも用意しておくとよいでしょう。

再起動を促されるのでおとなしく再起動をしましょう。


つづいては
Windows Phone Developer Tools RTW
のインストール。

余談ですが、この順序は逆なので・・・。(どちらからでもいいかとおもいますが)

vm_web.exe

をダウンロードして実行します。
こちらも時間がかかるので紅茶をのみながらのほほんとまっていましょう。

こちらは再起動は促されない様子です。

起動するとWindowsPhone用のVisualStudioが起動します。
外見は本当にVisualStudioなので(あたりまえだ)、触ったことある人は大体直感でわかるんじゃないかとおもいます。

2011年8月13日土曜日

[お知らせ] 日本Androidの会 関西支部のLTにでます。

9月3日にある
「日本Androidの会 関西支部勉強会」
でLTをやります。

もう人数埋まってますが、よかったらどうぞ。
ATNDより

LTやりますといったのはいいけど、ネタはこれからつくるのだったりする。
開発系のことをしゃべります。
あたまのなかで「あれをしゃべるかー」というのは考えているのですが

うーん。

5分で関西の人々の心をつかめるかはわからないですね。

ちなみに色々な都合上名前が「高田純三」になっています。
たぶんニッカポッカに木刀だな。

[Android] 007SH スクリーンショットの撮り方

いつのまにか007SH Jでスクリーンショットがとれるようになっておりました。

撮り方
取りたい画面で
終話キー(または側面のロックキー)+ ホームキー

ホームキーはさりげなく下にあってよくミスってうってしまうあのキーです。
0の下。

単体でスクリーンショットがとれるのはかなり便利。
友達とやりとりするときとか。

2011年8月6日土曜日

[Android] 2.1以上の電話帳(つまりContacts)とたたかってみるんだぜ その1

電話帳って2.1から変更されたんですよね。
ゆえにそんなにリファレンスサイトがないので自分でどーこーしてみることにした。
某会議でよく電話帳が話題になるので
まー、興味がでたっていえばでたんですけど。

Androidでは電話帳DBなるものが標準で搭載されている。
/data/data/com.android.providers.contacts/databases/contacts2.db
という場所にあったりする。
実際にデータをpullなどでぬいてきて
SQLite3のビューアーとかでみるとたしかにデータがはいっている。

が、これがすごくわかりづらい。
一回に解説したいですが、私にもわかってない箇所があるので
まー、それはゆっくりと。
とりあえず2.1からでは「ごっそりと仕組みが変わった」ということを覚えていただきたいです。
覚えなくてもいいけど。

では、簡単につかってみましょう。
前提条件として電話帳にこんな感じのデータをいれておきます。



















これは標準電話帳の画面です。
で、最終的にこんな感じにする。



















今回はかるーくテストなんで名前だけの表示にしています。
本来なら、下に電話番号をだすなり、メアドだすなり好きにしていいんですが
仕事中の休み時間にできることは限られているので(1時間しかない)。
時間があればそのうちハイパーなものをつくりたんですが、はてさて。

では本日のコードです。

まずはレイアウトのXMLを。

  1. <!--xml version="1.0" encoding="utf-8"?-->  
  2. <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent">  
  3.     <listview android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/listView"></listview>  
  4. </linearlayout>  

簡単にListViewだけを表示しているのでこれだけです。
つづいてはこちらに名前を入れるコード。

  1. import android.app.Activity;  
  2. import android.database.Cursor;  
  3. import android.os.Bundle;  
  4. import android.provider.ContactsContract;  
  5. import android.widget.ArrayAdapter;  
  6. import android.widget.ListView;  
  7.   
  8. public class AddressListActivity extends Activity {  
  9.    
  10.  private ListView mListView;  
  11.    
  12.  @Override  
  13.     public void onCreate(Bundle savedInstanceState) {  
  14.         super.onCreate(savedInstanceState);  
  15.         setContentView(R.layout.address_list);  
  16.           
  17.         // 表示  
  18.         mListView = (ListView) findViewById(R.id.listView);  
  19.         mListView.setAdapter(displayNameList());  
  20.     
  21.  }  
  22.    
  23.  // DBから取り出してごにょっとする  
  24.  private ArrayAdapter<string> displayNameList() {  
  25.     
  26.   // DBアクセス  
  27.   databaseAccess access = new databaseAccess(this);  
  28.   Cursor cursor = access.selectAllAddress();  
  29.     
  30.   cursor.moveToFirst();  
  31.   ArrayAdapter<string> adapter = new ArrayAdapter<string>(this,android.R.layout.simple_list_item_1);  
  32.     
  33.   // Contactsのデータを管理しているRAW_CONACT_ID  
  34.   int idIndex = cursor.getColumnIndexOrThrow(ContactsContract.Data.RAW_CONTACT_ID);  
  35.   // 表示名  
  36.   int nameIndex = cursor.getColumnIndexOrThrow(ContactsContract.Data.DISPLAY_NAME);  
  37.   // idにとりあえずの初期値を入れておく  
  38.   int id = 0;  
  39.     
  40.   while (!cursor.isAfterLast()) {  
  41.    // idが変わったら次の人  
  42.    if(id != cursor.getInt(idIndex)) {  
  43.     // idの入れ替え  
  44.     id = cursor.getInt(idIndex);  
  45.     // 表示名取得  
  46.     adapter.add(cursor.getString(nameIndex));  
  47.       
  48.       
  49.    }  
  50.    cursor.moveToNext();  
  51.   }  
  52.     
  53.   cursor.close();  
  54.     
  55.   return adapter;  
  56.     
  57.     
  58.     
  59.  }  
  60.    
  61. }  
  62. </string></string></string>  

コメントいれてあるのですが、実は上のコードにはDBにアクセスする処理はございません。
アクセスするにはこちらのコードを。
別にクラスを分ける必要性はなかったのですが、
あとあと入力とかを拡張しようと思っていたのでわけました。

  1. import android.content.Context;  
  2. import android.database.Cursor;  
  3. import android.net.Uri;  
  4. import android.provider.ContactsContract;  
  5.   
  6. public class databaseAccess {  
  7.    
  8.  private Context context;  
  9.  private Uri uri = ContactsContract.Data.CONTENT_URI;  
  10.    
  11.  // コンストラクタ  
  12.  public databaseAccess(Context context){  
  13.   this.context = context;  
  14.     
  15.  }  
  16.    
  17.  /** 
  18.   * DB全件返しメソッド 
  19.   * @return 
  20.   */  
  21.  public Cursor selectAllAddress() {  
  22.   return context.getContentResolver().query(uri, nullnullnullnull);  
  23.  }  
  24.   
  25. }  

クエリのつかいかたですが、

  1. Cursor android.content.ContentResolver.query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)  

という記述がDevelopersなんとかっていう解説書(もう忘れた)にあります。
場所を指定して、取り出すものを指定。さらに条件・・・といったところでしょうか。
今回は簡易なのでいやでも全件返すようにしています。

全件返すことでもちろん名前以外にも電話番号まで帰ってきているので

  1. while (!cursor.isAfterLast()) {  
  2.  // idが変わったら次の人  
  3.  if(id != cursor.getInt(idIndex)) {  
  4.   // idの入れ替え  
  5.   id = cursor.getInt(idIndex);  
  6.   // 表示名取得  
  7.   adapter.add(cursor.getString(nameIndex));  
  8.     
  9.     
  10.  }  
  11.  cursor.moveToNext();  
  12. }  

このあたりのところでいろいろ分岐させています。
IDは一人につき1つなので、そのIDが切り替わったら次の人。
同じIDが名前を2回もっていることもあるのでこういう重複チェックをかけています。
なぜ名前を2回もっているのかというと・・・

「ID」「表示名」「電話番号」
「ID」「表示名」「苗字」

というようなデータ構造になっているためです。
表示名は何回もはいってくるのですね(汗)


なのでまわりくどいコードになっています。
このあたりは私の調査不足なのでおいおいかっこいいコードに(そりゃもう鼻血がでるほど)していけたらいいなーとおもいますがな。


そんな感じで第一回電話帳会議終了。

ではもどるぞ!!だいじゅうよんてい(ry)

はい、仕事します。

2011年8月4日木曜日

[Android] JUnitで単体テストをする

前回の記事の補足になってしまいますが、
前回のActivityInstrumentationTestCase2は「機能テスト」を行うためでした。
機能テストはその機能がテストするかどうかのテストです。

次は「単体テスト」をやりましょう。
Activityの単体テストということで、開始→終了までをテストします。

今回の流れはこちら。

1.ActivityInstrumentationTestCaseを継承する
2.テストしたいクラスを指定したコンストラクタを作成
3.テスト準備を行うsetUpメソッドを記述する
4.Activityを終了させる(この場合はBACKボタンの押下)

基本的には動作を変えただけですが。
UIをいじっての終了ではなく、ハードキー動作での終了なので
わりと簡素なコードになってます。
さ、順番に見ていきましょう。

1.ActivityInstrumentationTestCaseを継承する

  1. /* 1.ActivityInstrumentationTestCaseを継承する */  
  2. public class CheckActivityTest2 extends ActivityUnitTestCase<checkactivity> {  
  3.   
  4. }  
  5. </checkactivity>  

*ソースコードにとありますが、エディタの補完機能でこうなっているだけです。無視してください。
今回は単体テストなので(Activity全体のテスト)、ActivityInstrumentationTestCaseを継承して使います。


2.テストしたいクラスを指定したコンストラクタを作成

  1. /* 2.テストしたいクラスを指定したコンストラクタを作成 */  
  2. public CheckActivityTest2() {  
  3.  super(CheckActivity.class);  
  4. }  

コンストラクタはクラス名のみ指定で。
次。
3.テスト準備を行うsetUpメソッドを記述する

  1. /* 3.テスト準備を行うsetUpメソッドを記述する */   
  2. @Override  
  3. protected void setUp() throws Exception {  
  4.  super.setUp();  
  5.    
  6.  // Activityの起動  
  7.  startActivity(new Intent(), nullnull);  
  8.    
  9.  // Activityを取得  
  10.  mActivity = getActivity();  
  11.    
  12. }  

自力でActivityを起動して取得しています。
次。
4.Activityを終了させる(この場合はBACKボタンの押下)

  1. /* 4.Activityを終了させる(この場合はBACKボタンの押下) */  
  2. public void testPushBackButton() {  
  3.   
  4.  KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);  
  5.  assertTrue(mActivity.dispatchKeyEvent(event));  
  6.    
  7. }  

本当はActivityが終了したら~という判定になると思うんですが、
そのあたりが未調査(おい)なので、BACKボタンの判定をしています。
うまいかんじにおせたらテストOKとしています。
Activityに何かさせる場合はその都度テストがいるのだとおもいますが、
そのあたりは機能テストで網羅させて単体テストでは開始→終了のサイクルがみれればいいかなーともおもっていたり。
なんつか技術者的にそれはいいのか?とも思うのですが、それもそのうち。
どうにかしたいです。

では本日のソースコードをのせておわりにします。
  1. package jp.co.mogakana.check.test.testcase;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.test.ActivityUnitTestCase;  
  6. import android.view.KeyEvent;  
  7. import jp.co.mogakana.check.test.CheckActivity;  
  8.   
  9. /* 1.ActivityInstrumentationTestCaseを継承する */  
  10. public class CheckActivityTest2 extends ActivityUnitTestCase<checkactivity> {  
  11.    
  12.  // Activity用  
  13.  private Activity mActivity;  
  14.    
  15.  /* 2.テストしたいクラスを指定したコンストラクタを作成 */  
  16.  public CheckActivityTest2() {  
  17.   super(CheckActivity.class);  
  18.  }  
  19.    
  20.  /* 3.テスト準備を行うsetUpメソッドを記述する */   
  21.  @Override  
  22.  protected void setUp() throws Exception {  
  23.      super.setUp();  
  24.     
  25.      // Activityの起動  
  26.      startActivity(new Intent(), nullnull);  
  27.        
  28.      // Activityを取得  
  29.      mActivity = getActivity();  
  30.        
  31.  }  
  32.    
  33.  /* 4.Activityを終了させる(この場合はBACKボタンの押下 */  
  34.  public void testPushBackButton() {  
  35.   
  36.   KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);  
  37.   assertTrue(mActivity.dispatchKeyEvent(event));  
  38.     
  39.  }  
  40.   
  41. }  
  42.   
  43. </checkactivity>  

今日も素敵にノイローゼ★