marunomaruno-memo

marunomaruno-memo

作ればわかる!Androidプログラミング ―10の実践サンプルで学ぶAndroidアプリ開発入門

2011年11月20日 | Android
作ればわかる!Androidプログラミング ―10の実践サンプルで学ぶAndroidアプリ開発入門
http://books.shoeisha.co.jp/book/b89122.html

金宏 和實 (著)
大型本: 352ページ
出版社: 翔泳社 (2011/10/15)
言語 日本語
ISBN-10: 4798124338
ISBN-13: 978-4798124339
発売日: 2011/10/15
商品の寸法: 23.6 x 18.7 x 2.9 cm

第1章 アプリケーションを作るためのウォーミングアップ
1-1 Androidの概要
Androidの特徴
  Memo Apache v2ライセンス
Androidのアーキテクチャ
1-2 Windowsに開発環境を構築する
Java Development Kit(JDK)のインストール
統合開発環境Eclipseのインストール
  Memo Pleiadesの動作が遅く感じる場合
Android SDKのインストール
Android Development Tools(ADT)のインストール
Android Virtual Device(AVD)の作成
パスの設定
1-3 Androidプログラミングの基礎知識
Androidプロジェクトの作成
ファイルの構成と役割
  Memo オーバーライド
1-4 エミュレータでの実行方法
プロジェクトの実行構成を作成
エミュレータは事前に起動しておく
1-5 実機での実行方法
実機用サンプルの作成
  Memo 単位
コマンドラインツールで実機へ転送
Eclipseから実機で実行
1-6 アクティビティ
アクティビティとは
アクティビティのライフサイクル
  Memo エミュレータの時間を合わせる
  Memo DDMSパースペクティブ

第2章 なつかしの数字合わせパズル
2-1 作成するAndroidアプリケーション
  Memo イベントリスナー
2-2 ビュー/ビューグループの基本
  Memo エミュレータのハードキー
2-3 「数字合わせパズル」を作る
プロジェクトの作成
レイアウトの定義
strings.xml
マニフェストファイル(AndroidManifest.xml)
画像ファイルの準備
アクティビティの作成
  Memo Androidで使う主なデータ型

第3章 ○○ちゃんに電話&ワンタッチメール
3-1 作成するAndroidアプリケーション
3-2 インテントの基本
明示的なインテント
暗黙的なインテント
3-3 「○○ちゃんに電話」を作る
プロジェクトの作成
アクティビティの作成
マニフェストファイルの変更
3-4 「ワンタッチメール」を作る
プロジェクトの作成
アクティビティの作成
実機での実行

第4章 休日にサーバー状態チェックツール
4-1 作成するAndroidアプリケーション
4-2 プリファレンスの基本
プリファレンスへのアクセスと保存/読み込み
プリファレンスの削除
プリファレンスのクリア
  Memo クラスとオブジェクト
4-3 「休日にサーバー状態チェックツール」を作る
プロジェクトの作成
アクティビティの作成
  Memo @Overrideとは

第5章 思い出のアルバム
5-1 作成するAndroidアプリケーション
5-2 コンテントプロバイダの基本
データの取得方法
サンプルデータの準備
登録されている連絡先の全件取得
電話番号が登録されている連絡先のみを取得
電話番号の取得
メールアドレスの取得
5-3 「思い出のアルバム」を作る
プロジェクトの作成
ビューの構成
アクティビティの作成
  Memo Logによるデバッグ出力

第6章 口述筆記くん
6-1 作成するAndroidアプリケーション
6-2 音声認識プログラミングの基本
音声認識によるWeb検索
  Memo String、StringBuffer、StringBuilderの使い分け
6-3 「口述筆記くん」を作る
プロジェクトの作成
アクティビティの作成
  Memo TextViewとEditTextをスクロール可能にする

第7章 Never Touch Me!
7-1 作成するAndroidアプリケーション
7-2 実装されているセンサーを調べる
7-3 音声を録音する
プロジェクトの作成
アクティビティの作成
  Memo match_parentについて
パーミッションの追加
録音してみる
7-4 「Never Touch Me!」を作る
プロジェクトの作成
NeverTouchMe.javaの作成
  Memo オーバーロードとは
パーミッションの設定
VoicePlayer.javaの作成
7-5 サービスを利用する
プロジェクトの作成
アクティビティの作成
サービスの作成
パーミッションの追加
7-6 ノーティフィケーションを利用する
NeverTouchService.javaの修正

第8章 チーズ!でカシャ
8-1 作成するAndroidアプリケーション
8-2 音を感知する
スレッドとは
プロジェクトの作成
アクティビティの作成
  Memo LogCatビューにログが表示されないとき
LoudNessクラスの作成
  Memo サンプリングレート
パーミッションの追加
8-3 サーフェイスビューに画像を描く
アクティビティの作成
LoudSurFaceViewクラスの作成
8-4 カメラ機能(Cameraクラス)を使う
アクティビティの作成
CameraViewクラスの作成
パーミッションの追加
8-5 「チーズ!でカシャ」を作る
プロジェクトの作成
アクティビティの作成
LoudNessクラスの作成
CameraViewクラスの作成
パーミッションの追加

第9章 卓球少女養成ギプス
9-1 作成するAndroidアプリケーション
9-2 加速度センサーの基本
加速度を表示するアクティビティ
9-3 「玉転がしゲーム」を作ってみる
BallAccelクラスの作成
BallSurFaceViewクラスの作成
9-4 タブレイアウトを使う
プロジェクトの作成
タブページのレイアウト
タブページ1のコンテンツ
タブページ2のコンテンツ
  Memo ディザリングとフィルタリング
TabActivityを継承するTabTestクラスの作成
9-5 「卓球少女養成ギプス」を作る
プロジェクトの作成
ファイル構成と表示する文字列
表示する文字列とタブページのコンテンツ
TabActivityを継承するPingPongクラスの作成
SwingListenerクラスの作成

第10章 お散歩の友
10-1 作成するAndroidアプリケーション
  Memo GPSロガーとは
10-2 Android MapsとGPSの使い方
Android Maps APIのインストール
Android Maps APIキーの取得
プロジェクトの作成
GoogleマップとGPSを使うための設定
strings.xmlにMaps APIキーを追加
地図表示用レイアウトの定義
  Memo タッチイベントの操作を表わす用語
地図と現在地の描画
10-3「 お散歩の友」を作る
プロジェクトの作成
マニフェストファイルの設定
作成するクラス
レイアウトの定義
表示する文字列とMaps APIキーの準備
実行イメージの確認
地図上に自分アイコンを描く
  Memo 1E6について
地図上に経路を描く
AsyncTaskによる非同期実行~緯度と経度から住所を取得
データ保存のためのダイアログの作成
SQLiteデータベースの利用
オプションメニューの作成
ListViewによるレコード一覧表示

第11章 AndroidでマインドストームNXTリモコン
11-1 作成するAndroidアプリケーション
  Memo ペアリングとは
11-2「 マインドストームNXTリモコン」を作る
プロジェクトの作成とパーミッションの設定
作成するクラス
Bluetoothの対応確認と有効化
接続可能なデバイスの検出と一覧表示
  Memo android:visibilityの"gone"
  Memo OUIとは
Bluetoothデバイスへのソケット接続
  Memo ソケット
Bluetoothデバイスとの通信~ダイレクトコマンドの発行
  Memo PIN(Passkey)の入力
  Memo シフト演算子
  Memo LogCatの出力をテキストファイルへ
ソケット接続を閉じる
オプションメニューの作成
加速度センサーでロボットを操作する

[C++] テンプレートの特殊化

2011年11月19日 | C / C++
[C++] テンプレートの特殊化
================================================================================

テンプレートの指定で、Java のように、あるクラスを継承したクラスのみに限定する、
ということができる。
    Javaの例: class MyClass<T extends Number>

「テンプレートの特殊化」というものを使って実現できる。
でも、かなり面倒くさい。

まずは汎用的なテンプレート関数を宣言する。
    template<class T>                               // (4)
    void print(T& t) {

テンプレートの特殊化ということで、特定の型に対するテンプレート関数を宣言する。
    template<>                                      // (5)
    void print<Base> (Base& t) {

派生クラスのオブジェクト d を引数に渡すときは、基本クラスの型として渡す。
    print(*(dynamic_cast<Base*> (&d)));         // (10)

これで、派生クラスのオブジェクト d に対して、Base 型のテンプレート関数が使われる。

もちろん、単に
    print(d);                                   // (8)
とした場合は、汎用的なテンプレート関数が呼び出される。


□ generic_sample.cpp
---
#include <iostream>
using namespace std;

class Base {                                    // (1)
public:
    virtual void print() {
        cout << "Base" << endl;
    }
};

class Derived: public Base {                    // (2)
public:
    void print() {
        cout << "Derived" << endl;
    }
};

class Other {                                   // (3)
public:
    void print() {
        cout << "Other" << endl;
    }
};

template<class T>                               // (4)
void print(T& t) {
    cout << "G: ";
    t.print();
}

template<>                                      // (5)
void print<Base> (Base& t) {
    cout << "B: ";
    t.print();
}

//template<>                                    // (6)
//void print<Derived>(Derived& t) {
//    cout << "D: ";
//    t.print();
//}

int main() {
    Base b;
    print(b);                                   // (7)

    Derived d;
    print(d);                                   // (8)
    print(*((Base*) (&d)));                     // (9)
    print(*(dynamic_cast<Base*> (&d)));         // (10)

    Other o;
    print(o);                                   // (11)
//    print(*((Base*) (&o)));                   // (12) // 実行時エラー
//    print(*(dynamic_cast<Base*> (&o)));    // (13) // コンパイルエラー

    return 0;
}
---

□ 実行結果
---
B: Base                <- (7)
G: Derived             <- (8)
B: Derived             <- (9)
B: Derived             <- (10)
G: Other               <- (11)
---


(1) 基本クラス Base

    class Base {                                    // (1)
        ...
    };


(2) 派生クラス Derived

基本クラス Base を継承し、print() 関数をオーバーライドする。

    class Derived: public Base {                    // (2)
        ...
    };


(3) 関係ないクラス Other

Base クラスとも、Derived クラスとも関係のないクラス。

    class Other {                                   // (3)
        ...
    };


(4) テンプレート

汎用のテンプレート関数。引数は参照で受け取る。

    template<class T>                               // (4)
    void print(T& t) {
        ...
    }


(5) テンプレートの特殊化

Base 型で受け取るテンプレート関数。

    template<>                                      // (5)
    void print<Base> (Base& t) {
        ...
    }


(6) テンプレートの特殊化

Derived 型で受け取るテンプレート関数。今回は、コメントアウトしている。

    //template<>                                    // (6)
    //void print<Derived>(Derived& t) {
        ...
    //}

上記のコードを有効にしておくと、実行結果は次のようになる。

---
B: Base                <- (7) 
D: Derived             <- (8)
B: Derived             <- (9)
B: Derived             <- (10)
G: Other               <- (11)
---


(7) 基本クラスのオブジェクトをプリント

    print(b);                                   // (7)

特殊化によって、(5)のテンプレート関数が使われる。


(8)-(10) 派生クラスのオブジェクトをプリント

    print(d);                                   // (8)

特殊化は、あくまでも、そのクラス(型)が対象なので、その型の派生クラスというのは関
係ない。したがって、これは、あくまでも汎用のテンプレート関数を使う。


    print(*((Base*) (&d)));                     // (9)
    print(*(dynamic_cast<Base*> (&d)));         // (10)

派生クラスのオブジェクトを、基本クラスの型にキャストしてしまえば、基本クラスを使
った特殊テンプレートが利用できる。

キャストの方法としては、(9)のように、C言語のキャスト、dynamic_cast を使う 2 つの
方法があるが、dynamic_cast を使うほうがよい。これは、つぎの説明のように、基本ク
ラスとは派生関係にないクラスのオブジェクトをキャストして、特殊化したテンプレート
関数を使わせたいときに、C言語のキャストでは、実行時までエラーがわからないが、
dynamic_cast であれば、コンパイル・エラーになるからである。


(11) 関係ないクラスのオブジェクトをプリント

    print(o);                                   // (11)

汎用のテンプレート関数を使う。


//    print(*((Base*) (&o)));                   // (12) // 実行時エラー

このコードは、実行時にエラーになる。


//    print(*(dynamic_cast<Base*> (&o)));   // (13) // コンパイルエラー

このコードは、次のコンパイルエラーになる。
---
In function `int main()':
error: cannot dynamic_cast `&o' (of type `class Other*') to type `class Base
*' (source type is not polymorphic)
Build error occurred, build is stopped
---



[C++] クラス定数の補足

2011年11月18日 | Android
                                                                更新 2012-10-08
                                                                新規 2011-11-18
クラス定数の補足
================================================================================

クラス定数は、次の形で定義できる。
    static const データ型 定数名 = 値;

ただし、データ型は、int や double など、基本データ型である必要がある。
char* のように、ポインター型や、char [] のような配列、std::string のようなオブジ
ェクトでは
invalid in-class initialization of static data member of non-integral type 
`const char*'
のようなコンパイル・エラーとなる。
つまり、(キャストして)整数や実数となるような型でないとだめのようだ。

後述するが、上記のように書けない場合は、クラス宣言の中で
    static const データ型 定数名;
としておいて、実体を定義するときに
    static const データ型 クラス名::定数名 = 値;
とする必要がある。(2012-10-08追記)

□ Sample.cpp
---
#include <iostream>
#include <string>
using namespace std;

class A {
private:
    int data;
    double data2;
    bool data3;

public:
    static const int DATA = 1234;    // (1)
    static const double DATA2 = 3.14;    // (1)
    static const bool DATA3 = true;    // (1)
    //    static const char* MESSAGE = "Hello World!"; // コンパイルエラー // (2)
    A(int data = DATA, double data2 = DATA2, bool data3 = DATA3);    // (3)
    void print();
};

A::A(int data, double data2, bool data3) : data(data), data2(data2), data3(data3) {
}

void A::print() {
    cout << data << ", " << data2 << ", " << data3 << endl;
}

int main() {
    cout << A::DATA << endl; // prints Hello World!
    cout << A::DATA2 << endl; // prints Hello World!
    cout << A::DATA3 << endl; // prints Hello World!
    //    cout << A::MESSAGE << endl; // prints Hello World!
    A a;
    a.print();

    return 0;
}
---

□ 実行結果
---
1234
3.14
1
1234, 3.14, 1
---


(1) クラス定数の定義

    static const int DATA = 1234;    // (1)
    static const double DATA2 = 3.14;    // (1)
    static const bool DATA3 = true;    // (1)

(2) ポインターをクラス定数で定義

    //    static const char* MESSAGE = "Hello World!"; // コンパイルエラー // (2)

これは、
invalid in-class initialization of static data member of non-integral type 
`const char*'
でコンパイル・エラーになる。


(3) クラス定数をデフォルト引数に指定

    A(int data = DATA, double data2 = DATA2, bool data3 = DATA3);    // (3)

とくに問題はない。


(以下、2012-10-08 追記)

■ 自分自身のインスタンスを定数で持つクラス

自分自身のインスタンスを定数で持つクラスのサンプル。

メンバー変数は、たんに int 型の値を持っているだけ。
コンストラクターをすべて private にすれば、他から直接インスタンスを生成できない
ようにすることもできる。


□ Item.h
---
#ifndef ITEM_H_
#define ITEM_H_

#include <iostream>

class Item {
public:
    static const Item* ITEM1;    // (1)
    static const Item* ITEM2;    // (1)

    static const Item* ITEM_LIST[];    // (2)
    static const int ITEM_LIST_SIZE;    // (3)

private:
    int value;

public:
    Item();
    Item(int value);
    virtual ~Item();

    int getValue() const;
};

#endif /* ITEM_H_ */
---

(1) 自分自身のオブジェクトの定数の宣言

    static const Item* ITEM1;    // (1)
    static const Item* ITEM2;    // (1)

(2)(3) オブジェクト定数配列の宣言とその要素数の宣言

オブジェクト定数を配列で持っていることで、使い勝手が向上するかもしれない。
そのときの要素数も持たせておく。

    static const Item* ITEM_LIST[];    // (2)
    static const int ITEM_LIST_SIZE;    // (3)

ここで、ITEM_LIST_SIZE は int 型だから、
    static const int ITEM_LIST_SIZE = sizeof(Item::ITEM_LIST)
                / sizeof(Item::ITEM_LIST[0]);
とすると、つぎのメッセージでコンパイルエラーとなる。
    invalid application of `sizeof' to incomplete type `const Item*[]' 
この時点では、ITEM_LIST の要素が確定していないため。


□ Item.cpp
---
#include <iostream>
#include <cassert>
#include "Item.h"

const Item* Item::ITEM1 = new Item(10);    // (1)
const Item* Item::ITEM2 = new Item(20);    // (1)

const Item* Item::ITEM_LIST[] = { ITEM1, ITEM2 };    // (2)
const int Item::ITEM_LIST_SIZE = sizeof(Item::ITEM_LIST)
        / sizeof(Item::ITEM_LIST[0]);    // (3)

Item::Item() {
    assert(true);
}

Item::Item(int value) :
        value(value) {
    assert(true);
}

Item::~Item() {
    assert(true);
}

int Item::getValue() const {
    return value;
}
---

(1) 自分自身のオブジェクトの定数の定義

const Item* Item::ITEM1 = new Item(10);    // (1)
const Item* Item::ITEM2 = new Item(20);    // (1)


(2) オブジェクト定数配列の定義

const Item* Item::ITEM_LIST[] = { ITEM1, ITEM2 };    // (2)


(3) オブジェクト定数配列の要素数の定義

const int Item::ITEM_LIST_SIZE = sizeof(Item::ITEM_LIST)
        / sizeof(Item::ITEM_LIST[0]);    // (3)


□ ItemTest.cpp
---
#include <iostream>
using namespace std;

#include "Item.h"

int main() {
    cout << Item::ITEM1->getValue() << endl;
    cout << Item::ITEM2->getValue() << endl;

    for (int i = 0; i < Item::ITEM_LIST_SIZE; ++i) {
        cout << Item::ITEM_LIST[i]->getValue() << endl;
    }

    Item item;
    cout << item.getValue() << endl;

    Item item2(30);
    cout << item2.getValue() << endl;

    return 0;
}
---


□ 実行結果
---
10
20
10
20
0
30
---

                                                                            以上



[C++] ダイヤモンド継承

2011年11月03日 | C / C++
ダイヤモンド継承
================================================================================

※ mingw 3.4.2


ダイヤモンド継承で virtual 指定のときに、オーバーロードされた違うコンストラク
ターで初期化したときにどうなるの、ということで、試してみる。

クラス図としては、つぎのとおり
(U言語、http://objectclub.jp/technicaldoc/uml/u_lang/)。

    A <|------ B <|------- D
          +--- C <|---+

U 言語での多重継承の描き方はどうなんだろう。上記の表現は適当に記したが、本当はど
うかな。


□ diamond.cpp
---
#include <iostream>
using namespace std;

class A {
public:
    int a;
    A();
    A(int a);
};

class B: virtual public A {
public:
    B();
};

class C: virtual public A {
public:
    C(int a);
};

class D: public B, public C {
public:
    D(int a);
};

A::A() :
    a(-1) {
    cout << "A::A()" << endl;
}

A::A(int a) :
    a(a) {
    cout << "A::A(int a), a = " << a << endl;
}

B::B() :
    A() {
    cout << "B::B()" << endl;
}

C::C(int a) :
    A(a) {
    cout << "C::C(int a), a = " << a << endl;
}

D::D(int a) :
    B(), C(a) {
    cout << "D::D(int a), a = " << a << endl;
}

int main() {
    D d(123);
    cout << "d.a = " << d.a << endl;

    return 0;
}
---

□ 実行結果
---
A::A()
B::B()
C::C(int a), a = 123
D::D(int a), a = 123
d.a = -1
---



■ クラスD が B や C を指定する順番を逆にする


継承する順番を逆にすれば、d.a の値が 123 になるかと思ったが、そうはならず、-1 の
まま。
なぜだろう。


□ diamond.cpp
---
#include <iostream>
using namespace std;

class A {
public:
    int a;
    A();
    A(int a);
};

class B: virtual public A {
public:
    B();
};

class C: virtual public A {
public:
    C(int a);
};

//class D : public B, public C {
class D: public C, public B {
public:
    D(int a);
};

A::A() :
    a(-1) {
    cout << "A::A()" << endl;
}

A::A(int a) :
    a(a) {
    cout << "A::A(int a), a = " << a << endl;
}

B::B() :
    A() {
    cout << "B::B()" << endl;
}

C::C(int a) :
    A(a) {
    cout << "C::C(int a), a = " << a << endl;
}

//D::D(int a) :
//    B(), C(a) {
//    cout << "D::D(int a), a = " << a << endl;
//}

D::D(int a) :
    C(a), B() {
    cout << "D::D(int a), a = " << a << endl;
}

int main() {
    D d(123);
    cout << "d.a = " << d.a << endl;

    return 0;
}
---

□ 実行結果
---
A::A()
C::C(int a), a = 123
B::B()
D::D(int a), a = 123
d.a = -1
---


■ vartual を外す

vairtual を外すと、さすがにコンパイル・エラー。
    request for member `a' is ambiguous

□ diamond.cpp
---
#include <iostream>
using namespace std;

class A {
public:
    int a;
    A();
    A(int a);
};

class B: public A {
public:
    B();
};

class C: public A {
public:
    C(int a);
};

class D: public B, public C {
public:
    D(int a);
};

A::A() :
    a(-1) {
    cout << "A::A()" << endl;
}

A::A(int a) :
    a(a) {
    cout << "A::A(int a), a = " << a << endl;
}

B::B() :
    A() {
    cout << "B::B()" << endl;
}

C::C(int a) :
    A(a) {
    cout << "C::C(int a), a = " << a << endl;
}

D::D(int a) :
    B(), C(a) {
    cout << "D::D(int a), a = " << a << endl;
}

int main() {
    D d(123);
    cout << "d.a = " << d.a << endl;

    return 0;
}
---

□ ビルド結果
---
..\src\diamond.cpp: In function `int main()':
..\src\diamond.cpp:53: error: request for member `a' is ambiguous
..\src\diamond.cpp:6: error: candidates are: int A::a
..\src\diamond.cpp:6: error:                 int A::a
---




ソフトウェア原則

2011年11月02日 | オブジェクト指向
ソフトウェア原則
http://www.objectclub.jp/technicaldoc/object-orientation/principle/
にあるまとめ

[1] ADP(Acyclic Dependencies Principle)パッケージは循環依存してはならない
[2] DIP(Dependency Inversion Principle)抽象は詳細に依存してはならない
[3] ISP(Interface Segregation Principle) インターフェイスは最小であるべき
[4] SDP(Stable Dependencies Principle)パッケージの依存方向は安定性の方向と一致すべき
[5] SAP(Stable Abstractions Principle)安定したパッケージは抽象的であるべき
[6] CRP(Common Reuse Principle)1パッケージ内のクラス群は同時に再利用される
[7] REP(Release-Reuse Equivalency Principle)再利用の粒度はリリースの粒度と一致する
[8] CCP(Common Closure Principle)1パッケージ内のクラス群は同種の変更に対して閉じている
[9] SRP(Single Responsibility Principle)1つのクラスに1つの責務(責務=変更理由)

以下の書籍が参照元
Agile Software Development, Principles, Patterns, and Practices (Alan Apt Series)
http://www.amazon.co.jp/exec/obidos/ASIN/0135974445/xpjp-22/


追加

http://hamasyou.com/archives/000210 より

クラス設計の原則
単一責任の原則 (The Single Responsibility Principle: SRP)
オープン・クローズドの原則 (The Open-ClosedPrinciple: OCP)
Liskovの置換原則 (The Liskov Substitution Principle: LSP)
依存関係逆転の原則 (The Dependency Inversion Principle: DIP)
インターフェース分離の原則 (The Interface Segregation Principle: ISP)

パッケージ設計の原則
再利用・リリース等価の原則 (Resuse-Release Equivalency Principle: REP)
全再利用の原則 (Common Resue Principle: CRP)
閉鎖性共通の原則 (Common Closure Principle: CCP)
非循環依存関係の原則 (Acyclic Dependencies Principle: ADP)
安定依存の原則 (Stable Dependencies Principle: SDP)
安定度・抽象度等価の原則(Stable Abstractions Principle: SAP)