メモ代わり。てきとーに。 いや、ですからてきとーですって。 2年前ぐらいにPythonあたりでメールくれた方、ごめんなさい。メール紛失してしまい無視した形になってしまいました。。。

2012年6月27日水曜日

[Objective-C][お勉強][メモ]インスタンス変数の有効範囲

特に何も指定しなかったときのインスタンス変数の有効範囲は@protectedと同等。

以下ディレクティブ。

ディレクティブ意味
@privateクラス内でのみアクセス可能
@protectedクラス内と、その継承されたクラスでのみアクセス可能
@publicどこからでもアクセス可能
@package意味不明

@packageは意味不明。private_externが何なのか知らない。
シンボルテーブルには登録しないってやつ?
androidの@hideみたいな感じ?

[Objective-C][お勉強][メモ] インスタンス変数の参照

レシーバが持つインスタンス変数への参照
インスタンス変数の名前そのままでアクセス可能。

- (void)setA:(BOOL)b
{
   a = b;
}
レシーバが保持しているインスタンス変数aへアクセス


レシーバ以外が所有するインスタンス変数への参照
レシーバ以外が所有するインスタンス変数の場合、そのオブジェクトを静的に型定義しなければならない。静的に型定義したオブジェクトのインスタンス変数への参照は構造体ポインタ演算子(->)を使う。

@interface ObjA
{
  ObjB *objB;
}
@interface ObjB
{
@public
  BOOL a;
}

@implementation ObjA
- (void)methodA:(BOOL)b
{
   objB->a = b;
}

もちろん、そのインスタンス変数が有効範囲にあることが前提。

2012年6月24日日曜日

[Objective-C][お勉強][メモ] クラス実装

@implementationで始まり、@endで終わる。

#import "この実装のインタフェース.h"

@implementation  クラス名
{
  インスタンス変数宣言
}
メソッド定義

インスタンス変数宣言は必要なければ省略可能。その歳は{}も省略する。

メソッド定義
メソッドは{}の間に定義する。以下参照。
- (型)メソッド名 {
  // ここに実装を定義
}



可変パラメータのメソッド
関数と同じように処理する。以下参照。
#import "stdarg.h"

- (void)methods: param1, ... {
  va_list  ap;
  va_start(ap, param1);
  ....
}

[Objective-C][お勉強][メモ] クラス参照

インタフェースが、その階層以外のクラス名を記述している場合は、

そのクラスのインタフェースファイルをインクルードするか、

@classディレクティブを記述する。

@class クラス名;
@class クラス名, クラス名;

@classディレクティブは、インタフェースをインクルードしない。
@classディレクティブは、クラス名が「クラス名」であることをコンパイラに知らせるだけ。
クラスのインタフェースを実際に使うのであれば、@classではなく、インタフェースをインクルードする必要あり。

.

[Objective-C][お勉強][メモ] インポート

インタフェースの場合、そのインタフェースに依存する全てのソースにincludeする必要がある。
インタフェースファイルは通常以下のようにincludeする。

#import "インタフェースファイル.h"

#importと#includeの違い
#importは2回以上includeされない。そのほかは#includeと同じ。

.

2012年6月23日土曜日

[Objective-C][お勉強][メモ]クラス定義

クラスは以下の2つに分けて定義する。

1) インタフェース
2) 実装

通常インタフェースと実装は別々のファイルとし、インタフェースは.h、実装は.mという拡張子をもつ。


インタフェース
インタフェースはディレクティブ@interfaceで始まり、ディレクティブ @endで終わる。
クラスのインタフェースは以下のように定義する。

@interface クラス名 : スーパクラス
{
  インスタンス宣言
}
メソッド宣言
プロパティ宣言
@end









メソッド宣言
クラスメソッド
先頭に"+"(プラス)をつける。
戻り値の型はC言語の型キャストの構文を使って記述する。
戻り値やパラメータの型を省略すると、デフォルトでidが使用される。
パラメータはメッセージと同様に名前の後のコロンの後に記述する。
+ (戻り値の型)メソッド名;
+(戻り値の型)メソッド名:(パラメータの型)パラメータ;
+(戻り値の型)メソッド名:(パラメータの型)パラメータ 名前:(パラメータの型)パラメータ;

インスタンスメソッド
先頭に"-"(マイナス)をつける。
戻り値の型はC言語の型キャストの構文を使って記述する。
戻り値やパラメータの型を省略すると、デフォルトでidが使用される。
パラメータはメッセージと同様に名前の後のコロンの後に記述する。
-(戻り値の型)メソッド名;
-(戻り値の型)メソッド名:(パラメータの型)パラメータ;
-(戻り値の型)メソッド名:(パラメータの型)パラメータ 名前:(パラメータの型)パラメータ;



可変パラメータをもつメソッド
Cと同様にカンマと省略記号を使って宣言する。
- (void)methoddayo:param1, ...;




プロパティ宣言
プロパティ宣言は以下のように記述する。
@property (attribute) Type propertyName;





インスタンス宣言
もともと必要だったが、今や実装ブロックやプロパティからの自動生成が可能なため、
通常はここでインスタンス宣言すべきでない、とのこと。
(波括弧も不要)


.



[Objective-C][お勉強][メモ]ソース上のクラス名

クラス名は以下の2つの場合にのみ使用できる。


1) 型名として使う場合

ObjA *objA;

等。

2) メッセージ式のレシーバとして使う場合
この場合のクラス名はクラスオブジェクトを意味する。

[ObjA alloc];

などなど。


また、クラス名はグローバル変数とネームスペースが同一のため、
同じ名前をつけることはできない。


.

[Objective-C][お勉強][メモ] ルートクラスのメソッド

クラスオブジェクトはルートクラスのインスタンスメソッドを実行する権限があるらしい。

.

[Objective-C][お勉強][メモ] クラスオブジェクトの初期化

クラスが静的変数やグローバル変数を使っている場合、initializeというメソッドで初期化するのが良いんでないかい、と書いてある。


ランタイムがinitializeメッセージを送るタイミングは以下のとおり。

1) メッセージを受信する前
2) 該当クラスのスーパークラスがinitializeメッセージを受信した後

よって、クラスは使用される前にinitializeメッセージを処理する機会が与えられる。

特に初期化する必要がなければ、initializeメソッドを実装する必要は無い。


注意点!
initializeを実装したスーパークラスObjAを継承したinitializeを実装しないクラスObjBがある場合、ObjBに対して送られたinitializeメッセージはObjBに該当するinitializeメソッドが
無いため、スーパークラスObjAのinitializeへと転送する。そのため、ObjAのinitializeメソッドが複数回実行されてしまう場合がある。

複数回実行されるのを防ぐために、以下のように実装する。

+(void)initialize
{
  if (self == [ObjA class]) {
    // ここで初期化処理
  }
}


とのこと。

2012年6月22日金曜日

[Objective-C][お勉強][メモ] クラス変数

そんなものは無い。



グローバル変数やstatic変数で代用した例。
static ObjA *objA;

@implementation ObjA;
+(id)getInstance
{
  どーのこーのどーのこーの
  return objA;
}

もちろん

static ObjA *objA;

じゃなく、

ObjA *objA;

とすることも可能。
だけど、なるべく有効範囲を限定した方が有効、とのこと。

.

[Objective-C][お勉強][メモ] インスタンス作成

allocメソッド
新しいオブジェクトのインスタンス変数を動的にメモリを割り当てる。
割り当てたインスタンス変数を0に初期化する。
クラスオブジェクトには少なくともallocのようなメソッドが1つ以上ある。

id str = [NSString alloc];

みたいな。


initメソッド
オブジェクトが有用であるためには、0で初期化するだけじゃなく
完全に初期化する必要があり、その初期化を行う。
通常allocの直後に行う。
クラスオブジェクトには少なくともinitのようなメソッドが1つ以上ある。

id str = [[NSString alloc] init];

とか。

[Objective-C][お勉強][メモ] クラスオブジェクト

ソースコード上では、クラスオブジェクトはクラス名として表される。
ex)
[NSString alloc];

メッセージ式で、単なるレシーバオブジェクトとして表される。
その他の場合、クラスまたはインスタンスに対してidクラスを返すよう要求することで
クラスオブジェクトを得られる。
ex)
id classObjDaYo = [NSString class];

NSString *strObj = [NSString @"aaa"];
id classObj2DaYo = [strObj class];

上記で、クラスオブジェクトはid型としているが、すべてのクラスオブジェクトは
Class型なので、Class型とすることもできる。
ex)
Class classObjDaYo = [NSString class];

.

[Objective-C][お勉強][メモ] 型のイントロスペクション

実行時にインスタンスがどの型かを調べることができる。
調べるためには、NSObjectのメソッドが使える。

isMemberOfClass:
レシーバが、引数で指定されたクラスであるかどうか調べる。

[objA isMemberOfClass:ObjA];

objAはObjAクラスであるかどうか。


isKindOfClass:
レシーバが、引数で指定されたクラスを継承しているか、または属しているかを調べる。

.

[Objective-C][お勉強][メモ] 継承

クラス定義は追加的に定義する。

新しいクラスはすべて別のクラスをベースとする。


NSObjecgt
ルートクラスは普通はNSObject。
NSObjectはルートクラスなのでスーパクラスが無い。
ルートクラスを定義することも可能だけど、止めといた方がいいってさ。
オブジェクトとして動作させるコードが書いてあるらしい。

インスタンス変数
普通に継承

メソッド
普通

メソッドのオーバライド
普通.

インスタンス変数のオーバライド
できない。

抽象クラス
継承されることが目的であったり、主に継承されることが目的のクラス。
通常、単独では不完全。
ただし、Objective-Cにはクラスを抽象クラスとしてマークするような構文は無い。
抽象クラスであってもallocできる。




2012年6月21日木曜日

[Objective-C][お勉強][メモ] クラス

Objective-Cではクラスを定義することでオブジェクトを定義する。

クラスの定義は一種のオブジェクトのプロトタイプ。

コンパイラによってクラスに1つだけアクセス可能な「クラスオブジェクト」(ファクトリオブジェクト)が作成される。
このクラスオブジェクトにより構築されるオブジェクトが、クラスのインスタンス。


慣習的にクラス名は大文字で始まる。
インスタンス名は小文字で始まる。

.

[Objective-C][お勉強][メモ] ドット構文

アクセサメソッドを呼び出す[]の代わりにドットを使うことができる。
直接インスタンス変数を変更しているわけではなく、アクセサメソッド呼び出しの「構文糖」。

[ObjA setValue:10];

と書く代わりに

ObjA.value = 10;

と書くことができる。
同様に

int a = [ObjA getValue];

と書く代わりに

int a = ObjA.value;

と書くことができる。

直接ObjAのインスタンス変数valueにアクセスしているわけではなく、
ObjAのアクセサメソッドを経由している。

自分の保有するインスタンス変数にアクセスする場合、self.(selfドット)をつけて
アクセスすれば、アクセサメソッド経由になる。もちろんself.を付けなければ
直接インスタンス変数にアクセスする。

[self setValue:10];



self.value = 10;

と同等だけど、

value = 10;

とは違う。インスタンス変数に直接アクセスしている。


へへ。
.

[Objective-C][お勉強][メモ] 動的バインディング

受信側のオブジェクトと、メッセージは、メッセージが送信されるまで結合されない。

なので、実際にどのメソッドが実行されるかは、実行時にだけ知ることができる。


さらに、送信するメッセージ(メソッドセレクタ)も実行時に決定させることが可能。
(メッセージ(メソッドセレクタ)を変数にする)

.

[Objective-C][お勉強][メモ] ポリモーフィズム

異なるオブジェクトでも同じセレクタ名を持つのであれば
同じメッセージに対して、応答することができる。

@implementation ObjBase;
- (void)methodBase:(id)obj
{
  [obj methodYahoo];
}
@implementation ObjA;
- (void)methodYahoo
{
  NSLog(@"ObjA DA YO!");
}
@implementation ObjB;
- (void)methodYahoo
{
  NSLog(@"ObjB DA YO!");
}

であれば、

[[[ObjBase alloc] init] methodBase:[[ObjA alloc] init]];

がいけるとすれば、

[[[ObjBase alloc] init] methodBase:[[ObjB alloc] init]];

もいけるって感じかどうなのか。
.

[Objective-C][お勉強][メモ] オブジェクトメッセージング

あるオブジェクトに対して何か実行させたいなら、そのオブジェクトに対してメッセージを送るんだそうだ。
その書式は以下。

[receiver message];

これを「メッセージ式」というらしい。

receiver は、メッセージを受信するオブジェクト。
messageは、receiverが実行すべきこと。



ランタイムシステムはメッセージが送信されると、receiverの持つ全てのメソッドの中から適切なメソッドを選んで呼び出す。

なので、message部分はreceiverのメソッド実装を「選択」することから
セレクタと呼ぶこともあるとのこと。

message部の書き方
AオブジェクトのBメソッドを実行する場合
[A B];

Aオブジェクトの引数1つのBメソッドを実行する場合
メソッド名の直後にコロンを置いて、その直後に引数の値を指定する。
[A B:10];

Aオブジェクトの複数の引数を持つBメソッドを実行する場合
2つ目以降の引数には引数名とコロン、そして引数の値を指定する。
[A B:10 C:20 D:30];

セレクタ名(Javaで言えばシグネチャ?)は、メソッド名とパラメータ名で成る。
上記の例だと
B:C:D:
となるとのこと。コロンが3つあるのは引数を3つ取るため。
戻り値や引数の型はセレクタ名には含まれない。

Aオブジェクトの可変引数を持つBメソッドを実行する場合
コロンの後にカンマで区切って指定する。
[A B:10,20,30];

セレクタ名にはカンマは含まれない。
なので[A B:10,20,30]のセレクタ名は
B:
となる。

値を返すメッセージ式
メッセージ式で指定されたメソッドが値を返す場合、メッセージ式は値を返すことができる。
A = [B C];

BオブジェクトのCメソッドを実行した結果、その戻り値をAに代入。

 メッセージ式の中にメッセージ式
メッセージ式はネストできるので以下のように書くことができる。
[A B:[C D]];

上記は、CオブジェクトのDメソッドの戻り値をAオブジェクトのBメソッドのパラメータとしている。


nilへのメッセージ
nilへメッセージ送信可能。

nilへのメッセージパターン
1) メソッドがオブジェクトを返す場合、nilを返す。

ObjB *objB = nil;
ObjA *objA = [ObjB methodReturnsObjA];

の場合objAはnil。


2) メソッドが以下の型を返す場合、メソッドは0を返す。
ポインタ型、sizeof(void*)以下のサイズの整数スカラ、float、double、long double、long long

@implementation ObjA;
- (float)methodReturnsFloat;

の場合、

ObjA *objA = nil;
[objA methodReturnsFloat];

は、0.0を返す。

3) メソッドがstructを返す場合は、そのstructのすべてのフィールドに0.0を返す。

4) 上記、1)〜3)以外の場合は、返す値は不定。


そんだけ。
.

2012年6月20日水曜日

[Objective-C][お勉強][メモ] 動的型定義

オブジェクトは実行時に動的に型定義されるらしい。

どうやって型を特定するかというと、

振る舞い(メソッド)とデータ(インスタンス変数)の種類

で特定するっぽい。


で、これはisa変数ってのがやるみたい。

.



[Objective-C][お勉強][メモ] nil

NULLみたいなものでnilっていうのがある。

NULLオブジェクトだそうで。


値が0のid。


.

[Objective-C][お勉強][メモ] id

どんなオブジェクトにも対応する汎用的な型に


id

という型がある。なんだかよく分からないけど、デフォルトのデータ型らしい。


typedef struct objc_object {
  Class isa;
} *id;

だそうで。

なので、idはstruct objc_objectへのポインタ。

isaっていうのは、このオブジェクトがどのクラスのインスタンスかを
表すobjc_classへのポインタ。

.

[Objective-C][お勉強][メモ] メモリ管理

Objective-Cがサポートしているメモリ管理の仕組みは

1) 自動参照カウント(ARC:Automatic Reference Counting)
2) 非自動参照カウント(MRC:Manual Reference Counting/MRR:Manual Retain/Releae)
3) ガべージコレクション

の3つ。3)はiOSでは非対応。


1) 自動参照カウント(ARC)
コンパイラが勝手にオブジェクトの存続期間を推論しちゃって決定する。

2) 非自動参照カウント(MRC)
オブジェクトの存続期間は人間(ディベロッパ)が管理する。

3) ガベージコレクション
自動コレクタというのが勝手にオブジェクトの存続期間を管理する。


らしいよ。
.

2012年6月9日土曜日

[iphone][xcode] コマンドラインでbuildする

まぁ、manのとおり。

Xcodeプロジェクトのbuildするためには、.xcodeprojファイルのあるディレクトリにいってxcodebuildを実行すればいいらしい。



xcodebuild [-project projectname] [-target targetname ...] [-configuration
configurationname] [-sdk [sdkfullpath | sdkname]] [buildaction ...] [setting=val
ue ...]

って書いてあるんだけど、target、configuration、sdkってなんだろね。
targetとconfigurationはxcodebuild -listで分かるみたい。

$ xcodebuild -list


Information about project "exp1":
    Targets:
        exp1
        exp1Tests

    Build Configurations:
        Debug
        Release

    If no build configuration is specified and -scheme is not passed then "Release" is used.

    Schemes:
        exp1



sdkはxcodebuild -showsdksってやれば良さそうだね。

$ xcodebuild -showsdks
Mac OS X SDKs:
Mac OS X 10.6                 -sdk macosx10.6
Mac OS X 10.7                 -sdk macosx10.7

iOS SDKs:
iOS 5.1                       -sdk iphoneos5.1

iOS Simulator SDKs:
Simulator - iOS 5.1           -sdk iphonesimulator5.1


ほらね。

ということで、以下でbuildできるはず。

$ xcodebuild -target exp1 -configuration Debug -sdk iphoneos5.1 clean build

と思ったら、以下のエラー。。

User interaction is not allowed.
Command /usr/bin/codesign failed with exit code 1

調べたら、keychainをunlockしなきゃいけないみたい。
ということで

$ security unlock-keychain /Users/konno/Library/Keychains/login.keychain

で、xcodebuildリラン。

$ xcodebuild -target exp1 -configuration Debug -sdk iphoneos5.1 clean build

** BUILD SUCCEEDED **

って出たのでOKっぽい。



あとはパッケージングと実機への転送かな。
.



2012年6月8日金曜日

[iphone] 入門するよ

リファレンス


iOS Developer Library
https://developer.apple.com/library/ios/navigation/


日本語
https://developer.apple.com/jp/devcenter/ios/library/japanese.html


[macbook][autoconf] autoconf

あれれ。

ということで、autoconf最新版にするよ。
できるかな。

$ curl -O http://mirrors.kernel.org/gnu/autoconf/autoconf-latest.tar.gz
$ tar xvzf autoconf-latest.tar.gz
$ cd autoconf-*
$ ./configure --prefix=/usr/local
$ make
$ sudo make install


そんだけ。

[macbook]Xcode4.3とか

Xcode4.2だったので、Xcode4.3入れなおした。

appstoreからインストールしようと思ったら、、、いくらクリックしてもダウンロード
はじめない。。。

ということで、xcode_432_lion.dmgってやつを落してきて以下な感じでインストール。

$ hdiutil attach ~/Downloads/xcode_432_lion.dmg
$ sudo cp -R -p -v /Volume/Xcode/Xcode.app /Applications/Xcode.app

ついでにcltools_lion_latemarch12.dmgってのも。
$ hdiutil attach ~/Downloads/cltools_lion_latemarch12.dmg
$ cd /Volume/Command\ Line\ Tools
$ sudo installer -pkg ./Command\ Line\ Tools.mpkg -target /

そんだけ。


2012年5月14日月曜日

[freeRadius][android] freeRadius+CG-WLR300NM+android端末でEAP

EAP認証をWiFiでやってみようと思い立つ。

WiFi+EAPなんてさっぱりわからん。

どうすりゃいいんだ、ということでググると・・・
WiFiルータでEAPに対応すると価格の桁が1つupするみたいね。。

個人的にはCoregaかPlanexのものしか手が出せない模様。。
ということでWiFiルータは安かったCoregaのCG-WLR300NMを選択。

で、CG-WLR300NMを入手して早速CG-WLR300NMをセットアップ。
するとRADIUSサーバを設置しないとダメみたい。



ちょうどDebianが入っているThinkPad X30があったのでここにRADIUSサーバを立てる。
$ aptitude search radius

ってたたくとfreeradiusがいっぱい出てくる。

ふーん、、、freeradiusを立てればいいのかな。
設定とか分からん。

ということで、再びggl。

http://www.eduroam.jp/docs/conf-freeradius2.html

というのを見つけた。これなら楽できそうだ。ということで
aptitutde installしないで、freeradius-2.1.1のソースをダウンロード。
FreeRadiusのホームページからだと2.1.1が見つからなかったので
(Old versionに2.1.1が無い?)githubからダウンロード。

コンパイル&/usr/local以下にインストール。
で、パッチ。
設定はパッチを当てると、概ねOKらしい。

/usr/local/etc/raddb/client.confを編集し以下を追加。


client wifi-ap {
    ipaddr = 192.168.1.18
    secret = abc123
}

/usr/local/etc/raddb/usersを編集し、以下を追加。

"foo" Cleartext-Password := "bar"


さて、あとは証明書。証明書が必要なんすね。

ということで
/usr/local/etc/raddb/certsへcd。
んで、
# make distclean
# rm ./index.txt
# touch ./index.txt
# make
# make client
よくわかんないけど、とりあえずクライアント証明書も作っとく。

できた証明書をandroidで読み込めるよう、pkcs12に変換。

# openssl pkcs12 -export -in ca.pem -inkey ca.key -out ca.p12 -name 'wifi-ca'
# openssl pkcs12 -export -in client.pem -inkey client.key -out client.p12 -name 'wifi-client'

あ、ここで-nameをつけとかないと、androidで使う時面倒(Wifi Managerを使う場合)。
android標準のWifiツールを使うのであれば、選択できるので-nameいらないかも。

で、これらの証明書をandroidへpush

$ adb push ./ca.p12 /mnt/sdcard
$ adb push ./client.p12 /mnt/sdcard

あとはandroid端末で操作。
「Settings」から「Location&Security」を選択して「install from microSD」を選択。
すると画面に
ca.p12
client.p12
が表示されるので、それぞれ選択。
パスワードをきかれるので、openssl pkcs12 -export時に設定したパスワードを入力。
そして、androidのcredential storage用のパスワードも設定。

準備完了。

radiusサーバを起動。
最初は動くかどうか分からんので
# radiusd -X
で起動。

wifi-apの設定。
radiusサーバのIPと、client.confに設定したsecretを設定。

android側から接続。
Network SSIDはCG-WLR300NMのCG-Guestでないやつ。
Securityは「802 1xEAP」を選択。(Scanリストから設定する場合は選択不可)
EAP methodは、「PEAP」を選択。
Phase 2 authenticationは、「None」。
CA certificateは「wifi-ca」。
User certificateは「wifi-client」。
Identityは「foo」。
Anonymous Identityは空。
Passwordは「bar」。

んで、Connect。


つながった。


radius -Xの出力も
Login OK
とか
success
とか出てる。
というか、エラーっぽいのが無いっぽい。



あら、簡単。

正しいかどうかは知らない。
そして、802 1xEAPとか、PEAPとかが、一体何のかさっぱり分からん。

さて、、、freeradiusってなんじゃらほい。



そんだけ。
.







2012年4月17日火曜日

[Android][お勉強][NDK] ログ出力

.cでandroid/log.hをインクルード。

Android.mkに以下を追加。

LOCAL_LDLIBS := -llog

もしかしたら

LOCAL_LDLIBS += -llog

の方がいいかも。
(いや、CLEARしてるので無意味でした。。。)

 __android_log_printが使えるようになると。

ログレベルは

typedef enum android_LogPriority {
  ANDROID_LOG_UNKNOWN = 0,
  ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
  ANDROID_LOG_VERBOSE,
  ANDROID_LOG_DEBUG,
  ANDROID_LOG_INFO,
  ANDROID_LOG_WARN,
  ANDROID_LOG_ERROR,
  ANDROID_LOG_FATAL,
  ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
} android_LogPriority;

な感じ。


2012年4月16日月曜日

[Android][その他] ProcessBuilderやらRuntime.execやら

ProcessBuilderでプロセス作ってスタートすると
プロセスがきっちり終わらない場合ロックする場合がある。

多分ProcessManagerのexec中

synchronized(なんたらReferences) {

あたりかな。。。

アプリから起動したプロセスをアプリに紐付けたいからかしらね。

.

[Android][お勉強] NDK環境構築とGetting Started

NDK環境構築&Getting Startedメモ

NDK環境作ってGetting Startedのメモ。

といってもドキュメントにあるとおり、インストールは「straightforward」で「involves extracting」するだけな感じ。

さっそくドキュメントみながらメモ。


Installing NDK
==========
1. http://developer.android.com/sdk/ndk/index.htmlからAndroid NDKをダウンロード

2. Android SDK最新版がインストールされていることを確認。
もし必要であれば最新版へとUPGRADE。
(NDKか過去バージョンと互換性はあるものの、過去バージョンのツールでは無いため)
http://developer.android.com/sdk/ndk/overview.html#reqs
も見といてね!

3. 1. でダウンロードしたものを、自分の環境の解凍ツールを使って解凍する。
ex) linux、tar.bz2の場合

  $ tar xvjf android-ndk-r7c-linux-x86.tar.bz2

4. 解凍が終わると、「android-ndk-」というフォルダができるので、必要があればリネームor移動。

5. 完了ー


Getting Started
===========

概ねの流れ
-----------
1. native codeで書かれたソースを/jni/以下に設置。まぁ、JNI。
2. NDK Buildシステム用に/jni/Android.mkを作る
3. 必要があれば/jni/Application.mkも作る
4. ディレクトリ直下でndk-buildスクリプトを起動しBuildする。
5. stripped shared librariesをprojectルートにコピー。
6. いつもの手段で.apk作成。

おしまい。

Creating Android.mk
--------------------
Android.mkファイルはちょっとしたbuildスクリプト。
書き方の詳細は/docs/ANDROID-MK.htmlにあり。
作成されるライブラリは
1. static library
2. shared library
のいずれか。
Shared libraryだけがapplicationパッケージにコピーまたはインストールされる。
NDKシステムはデフォルトで/jni/Android.mkを探しにいく。
サブディレクトリにAndroid.mkファイルを作りたいなら/jni/Android.mkに
以下のように記述すればOK。

  include $(call all-subdir-makefiles)

1つのAndroid.mkにいくつものモジュールを定義することも可能だし
複数のAndroid.mkでいくつものモジュールを定義することも可能。

buildシステムはあなたのためにおおくの詳細を扱ってくれる。
例えば、ヘッダーリストや生成されたファイルの依存関係など。
それらはbuildシステムが自動的に計算してくれる。

これは、NDKがアップデートされた際、Android.mkをいじることなく
移植することができるというメリットがある。

サンプルAndroid.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni 
LOCAL_SRC_FILES := hello-jni.c

include $(BUILD_SHARED_LIBRARY)


以下、それぞれの行の説明。

LOCAL_PATH := $(call my-dir)
Android.mkファイルはLOCAL_PATH変数の定義ではじめなければならない。
開発環境のツリー構造、どこにソースがあるか、を特定することに使われる。 
my-dirはマクロで、NDKシステムにより提供されていて、カレントディレクトリを返す。

 include $(CLEAR_VARS) 
CLEAR_VARSはNDKシステムにより提供される変数。
ある特別なGNU Makefileを指していて、LOCAL_PATHを除くいくつかのLOCAL_XXXX変数をクリアする。
一つのGNU Makeによりパースされ、全変数はglobalとなる。
よってこのクリアは必須。

LOCAL_MODULE := hello-jni
必須。モジュール名。一意でなければならず、スペースを含んではいけない。
仮に、ここにfooという名前を定義すると、NDKシステムにより、libfoo.soのように
自動的にPrefixとSuffixが付加され、生成される。
ここにlibfooという名前を定義した場合にはliblibfooとはならず、libfoo.soとprefixは
自動的に付加されない。

LOCAL_SRC_FILES := hello-jni.c
モジュールに含めるC/C++のソースリストを定義。
ヘッダファイルやincludeファイル、依存関係はNDKシステムが自動的に計算する
ので、ここにはヘッダファイルやincludeファイルは含めない。
デフォルトではC++の拡張子は'.cpp'となっている。
変更したい場合にはLOCAL_CPP_EXTENSION変数を定義する。(ドットから始まる値をセット)

include $(BUILD_SHARED_LIBRARY)
BUILD_SHARED_LIBRARY変数は、'include $(CLEAR_VARS)'以降のLOCAL_XXX変数で定義した情報を集め、何をbuildするか、どのようにbuildするかを決定するGNU Makefileスクリプトを指し示す、NDKシステムより提供される変数。共有ライブラリを生成する。
静的ライブラリを生成するBUILD_STATIC_LIBRARYもあるよ!

予約されている名前
以下の名前は予約済み。

1. LOCAL_で始まる名前。
2. PRIVATE_、NDK_ 、APP_ で始まる名前(NDK内部で使用)
3. 小文字の名前(my-dirなど)

なので、もし自分で何かしら変数を定義したいなら
"MY_"プレフィックスをつけること推奨。


と、とりあえずはしょぼいものであれば、これだけで充分かな。。。

そんだけ。
.

2012年4月10日火曜日

[Android][メモ] WifiManager.calclateSignalLevel

    public static int calculateSignalLevel(int rssi, int numLevels) {
        if (rssi <= MIN_RSSI) {
            return 0;
        } else if (rssi >= MAX_RSSI) {
            return numLevels - 1;
        } else {
            int partitionSize = (MAX_RSSI - MIN_RSSI) / (numLevels - 1);
            return (rssi - MIN_RSSI) / partitionSize;
        }
    }
となってて、MIN_RSSI = -100、MAX_RSSI = -50となっているので
numLevelsに51より大きい数を指定すると0除算エラー。 
そんな大きな数指定するなってことだろうけども。

 そんだけ。

.

2012年4月9日月曜日

[Android][Galaxy NEXUS] infinite reboot

Galaxy NEXUSがね、WiFi Onした途端、落ちたんよ。

でね、再起動するものの、起動しきれずに落ちるんよ。

いずれ復旧するかと思って早3時間。ずっと再起動、クラッシュを繰り返してるんよ。

adbはつながるのでlogcat見てると、GTalkってのがWRITEできないってエラー吐いてるんだよね。。。
怪しい・・・


調べたらね、同様の現象が起きてる人がいるっぽい。

中には店で交換してもらったという人もいるっぽい。でもその人また再起動の無限ループ。



docomo行くか、文鎮か。

初期化すればいいのかな。


でも、docomoの保証なんていらないし、rootedしとくか
つーことで、


以下よくある手順(Debian squeeze)。

1) ボリュームボタン上下とも同時に押しながら、電源ボタン長押し

2) するとfastbootモードで起動する。(でかでかと「Start」って出てる)

3) PC(Debian squeeze)に接続

4) Superbootってやつを
http://android.modaco.com/topic/348161-01-feb-r4-superboot-rooting-the-gsm-lte-galaxy-nexus/からゲット。

5) 上記ダウンロードしたzipを解凍

$ unzip r4-galaxynexus-gsm-superboot.zip
 


6) cd
$  cd r4-galaxynexus-gsm-superboot
 


7) なんだか良くわからないコマンドを実行
$ ./fastboot-linux oem unlock
 

documentには書いてないんだけど多分、Galaxy NEXUSの一番したに
LOCK STATE - LOCKED
 

ってなってるんで、これをUNLOCKにするんじゃないかなぁ・・・

で、上記コマンドを実行すると、Galaxy NEXUSの画面に
「Unlock bootloader?」
って出るので
「Yes」を選択。(ボリュームの上下で選択を変更できる)
で、電源ボタン押下。

そうするとGalaxy NEXUSの画面の一番下、
LOCK STATE - LOCKED
 

が、
LOCK STATE - UNLOCKED
 

に。
ああ、やっぱり。
で、このLOCK STATEが何を意味しているのかは知らない。 


8) chmod
$ chmod +x ./install-superboot-linux.sh
 



9) ./install-superboot-linux.sh実行
$  ./install-superboot-linux.sh
downloading 'boot.img'... OKAY
booting... OKAY
 


これでrooted完了。


で、起動してみる。
3時間ぶりに起動した。


再起動する問題は解決したわけじゃないんで
また起きたら今度こそ文鎮かな。。。
初期化すれば良さそうではあるけれど。
って感じ。


ま、これで遊べるはず。

そんだけ。

.
---
$ adb shell
$ su
#

ね。

で、busybox installerっすか?

2012年4月3日火曜日

[Android][メモ] java.beans.*

android sdk(rev 16)ではjava.beans.*は実装されてないらしい。

だもんで、もう終わってるApache Harmonyからjava.beans実装をパチって
使えるようにしてみる。

Apache Harmonyのjre/lib/boot/beans.jarを<プロジェクト>/libsへコピー。

でコンパイルしてみると、


[dx]
[dx] trouble processing "java/beans/AppletInitializer.class":
[dx]
[dx] Ill-advised or mistaken usage of a core class (java.* or javax.*)
[dx] when not building a core library.
[dx]
[dx] This is often due to inadvertently including a core library file
[dx] in your application's project, when using an IDE (such as
[dx] Eclipse). If you are sure you're not intentionally defining a
[dx] core class, then this is the most likely explanation of what's
[dx] going on.
[dx]
[dx] However, you might actually be trying to define a class in a core
[dx] namespace, the source of which you may have taken, for example,
[dx] from a non-Android virtual machine project. This will most
[dx] assuredly not work. At a minimum, it jeopardizes the
[dx] compatibility of your app with future versions of the platform.
[dx] It is also often of questionable legality.
[dx]
[dx] If you really intend to build a core library -- which is only
[dx] appropriate as part of creating a full virtual machine
[dx] distribution, as opposed to compiling an application -- then use
[dx] the "--core-library" option to suppress this error message.
[dx]
[dx] If you go ahead and use "--core-library" but are in fact
[dx] building an application, then be forewarned that your application
[dx] will still fail to build or run, at some point. Please be
[dx] prepared for angry customers who find, for example, that your
[dx] application ceases to function once they upgrade their operating
[dx] system. You will be to blame for this problem.
[dx]
[dx] If you are legitimately using some code that happens to be in a
[dx] core package, then the easiest safe alternative you have is to
[dx] repackage that code. That is, move the classes in question into
[dx] your own package namespace. This means that they will never be in
[dx] conflict with core system classes. JarJar is a tool that may help
[dx] you in this endeavor. If you find that you cannot do this, then
[dx] that is an indication that the path you are on will ultimately
[dx] lead to pain, suffering, grief, and lamentation.
[dx]
[dx] 1 error; aborting
 

といわれるので、いわれたとおりに作業する。

1. buid.xmlを修正(カスタマイズする準備)
<プロジェクト>/build.xmlの<import file="${sdk.dir}/tools/ant/build.xml" />
をコメントアウト。

<SDK>/tools/ant/build.xmlの<project />の中身
<プロジェクト>/build.xmlの<import file="${sdk.dir}/tools/ant/build.xml" />
のあったところにコピー。


2. jarjarでrepackageするように修正
(jarjar.jarはここらへん)
jarjar-1.2.jarをダウンロードし、<プロジェクト>/buildtools/以下に保存。

jarjarターゲットをbuid.xmlに追加。内容は以下のとおり。

<!-- Converts this project's .class files into .dex files -->
<target name="-jarjar" depends="-compile">
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask"
classpath="buildtools/jarjar-1.2.jar"/>
<jarjar jarfile="${out.absolute.dir}/repackagedclasses.jar">
<zipgroupfileset dir="${extensible.libs.classpath}" includes="*.jar" />
<rule pattern="java.beans.**" result="jp.co.qsdn.android.@1"/>
</jarjar>
</target>
 

At this point you'll need to edit the tag to refer to the javax.* appropriate package prefix, and to the rename target.
とのことなので、jp.co.qsdn.android.とした。
これでjava.beans.*パッケージはjp.co.qsdn.android.java.beans.*へ書き換わる。

そして

<target name="-dex" depends="-compile, -post-compile, -obfuscate">
 



<target name="-dex" depends="-compile, -post-compile, -obfuscate, -jarjar">
 

に書き換え。

dex-helper中の

<path refid="jar.libs.ref" />
 



<fileset file="${out.absolute.dir}/repackagedclasses.jar" />
 

に書き換え。

で、できたはず。


$ ant debug


で、とりあえずコンパイルして*-debug.apkは作成できるようになった。
とりあえずjava.beans.*使ったcommons-beanutilsは動いている模様。

うーむ、、、
.

2012年3月28日水曜日

[Android][Wifi] Android4.0のstatic ip

androidでstatic ipを割り当てるとき、


Settings.System.putString(getContentResolver(), Settings.System.WIFI_STATIC_IP, IPアドレス)
Settings.System.putString(getContentResolver(), Settings.System.WIFI_STATIC_GATEWAY,Gatewayアドレス)
Settings.System.putString(getContentResolver(), Settings.System.WIFI_STATIC_NETMASK, ネットマスク)
Settings.System.putString(getContentResolver(),Settings.System.WIFI_STATIC_DNS1, DNS1アドレス)
Settings.System.putString(getContentResolver(), Settings.System.WIFI_STATIC_DNS2, DNS2アドレス) Settings.System.putString(getContentResolver(), Settings.System.WIFI_USE_STATIC_IP, "1")
 

ってな感じでいいと思うんだけど、Android4.0だとダメみたい。
Android4.0以前だとstatic ipはWifiConfigurationとは別にもっていたんだけど
Android4.0から(?)WifiConfigurationに紐づく。

4.0のWifiConfiguration.javaを見ると、

public IpAssignment ipAssignment;
public ProxySettings proxySettings;
public LinkProperties linkProperties;
 

というメンバが登場。

こいつらをセットアップすれば良さそうなんだけど、documentには公開されてないっぽいし
rev16のsdkでもコンパイルできないっぽい。IpAssignmentなんて知らない!っていわれる。

いじっちゃダメというオーラを感じるもののまぁいいやということで
IpAssignmentとLinkPropertiesを知ってるクラスローダを頂戴しまして、
そのクラスローダから、IpAssignmentやらLinkPropertiesやらを
ロードして必要事項をセットしてWifiConfigurationにセットすればいいんでないかい?

ということでやってみたら無事できたんだけど
いいのかなぁ・・・

.

2012年3月13日火曜日

[Android][WiFi] 保存されている設定の一意キー

もしかしてSSIDで一意としてる???

BSSがいいなぁ。

一応networkIdというのがキーになっているっぽい。

毎回設定クリアしてWEPキー入れるの面倒ね。

WiFi static、、惜しい!
.

[Android][Xperia初代] WiFiが変?

Xperia初代だと見えて良いはずのWiFiルータがXperiaから見えない。。。
0cmぐらいの距離でも同じ。
他の端末は今のところ問題なし。

全く同じ型のWiFiルーターを別の場所で使うと、あら不思議。
Xperiaから見えるんですねー。


うーん、、、dhcp以下に何か残ってるのかしら。
意味不明。。。


全然違う話だけどOpenStreetMap良さそうね。

そんだけ。

--
Xperia初代は、Wifi Channel 13はダメらしい。
rootedでパッチあてろって。。
関係あるかな。。

--
sim無なしだとChannel13のApはスキャンしても出てこない。。

そういうもんか。
とういことで、APの方のChannelを13、12以外に設定して解決。


.

[Android][その他] IS05 memo

0xc08bb2d8 ?

2012年2月24日金曜日

[Android][aChartEngine][メモ] GraphicalView

aChartEngineのメモ

ChartFactory.getほげほげViewでViewとってもいいんだけど、
そうすると、GraphicalViewのonDrawで


canvas.getClipBounds(mRect);
int top = mRect.top;
int left = mRect.left;
int width = mRect.width();
int height = mRect.height();
 

ってなってるんで、ScrollView内にGraphを置いても、Scrollする状況にならない。

ということで自前の悲しめのViewを用意する。

といってもonDrawでClipBoundsしたくないだけなので以下のViewでいいや。


public class GraphicalView
extends View
{
private AbstractChart mChart;
private Paint mPaint = new Paint();

public GraphicalView(Context context, AbstractChart chart) {
super(context);
mChart = chart;
}


@Override
protected void onDraw(Canvas canvas) {
mChart.draw(canvas, 0, 0, getWidth(), getHeight(), mPaint);
}
} 

ズームはしないし、スクロールもaChartEngineの方でする必要はないので
こんなもんか。つーか、こんなんでいいや.

あとは使うだけ。

使いたいChartを作って・・・


TimeChart chart = new TimeChart(ほげほげセット, ほげほげレンダラー);
chart.setDateFormat("HH:mm:ss");
 


んで、



GraphicalView chartView = new GraphicalView(getApplicationContext(), chart);
chartView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, getResources().getDimensionPixelSize(R.dimen.height_of_graph)));
graphView.addView(chartView);
 

といつもな感じで使うだけ。

.

2012年2月23日木曜日

[Android][aChartEngine][メモ] AChartEngineのTimeSeriesのx


public synchronized void add(Date x, double y) {
super.add(x.getTime(), y);
}
 



x.getTime()

ってなってる。


そんだけ.

.

2012年2月13日月曜日

[Android] com.antivirus

com.antivirusってやつ使ってると

logcatプロセスがもりもり増えていく。


で、最後に再起動。。。

.
--
2012/3/1時点ですでに修正されてるっぽい。
logcatプロセス増えない!

良かったー
.

2012年2月12日日曜日

[Android][メモ] ls

/system/bin/ls

のメモ。


if (!strcmp(argv[i], "-l")) {
flags |= LIST_LONG;
} else if (!strcmp(argv[i], "-s")) {
flags |= LIST_SIZE;
} else if (!strcmp(argv[i], "-a")) {
flags |= LIST_ALL;
} else if (!strcmp(argv[i], "-R")) {
flags |= LIST_RECURSIVE;
} else if (!strcmp(argv[i], "-d")) {
flags |= LIST_DIRECTORIES;


.

2012年2月11日土曜日

[Android] 某キャリアの某端末一覧

某キャリアでの発売済機種一覧を探してて、

結局某キャリアのサイトで取得できることが分かり

早速GET。


が、

「横かよ!」

と思ったのは私だけではないはず。



わざとかな。。


--

というか、Wikipediaでいいじゃん


そんだけ
.

2012年1月26日木曜日

[Android] 消せないアプリ

Android必須ではない、
プリインストールされているアプリで消せないアプリを見つけると、
必要以上にイラっとするね。。。

まぁ、root取れれば大体は消せるんだけど・・・。


ちなみにIS05
.

[Android][SQLite] LIMIT OFFSET


SELECT * FROM HOGEHOGE WHERE TARATARA = "HOGETARAPIN" LIMIT 10 OFFSET 20
 



SELECT * FROM HOGEHOGE WHERE TARATARA = "HOGETARAPIN" LIMIT 10,20
 


らしい。

あれ?

"HOGETARAPIN"じゃなくて"HOGETARAPI"かも。

.

2012年1月21日土曜日