sqlite(CoreData)で検索する際、大文字・子文字を区別せず検索するには、 [cd]のオプションをつけるだけで実現できる。
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@", searchName];
[fetchRequest setPredicate:predicate];
AppleのPredicate Format String Syntax に記載されている。
[c] = 大文字小文字 [d] = 発音区別記号
最近、Flexをさわっていなかったがスマフォ関連も絡んできたのでチェック。 Flex(プレビュー版)を使った Android アプリケーション開発 Flex for Android in 90 Minutes
次期バージョンはそれぞれFlex SDKが「Hero」、Flash Builderが「Burrito」だそうで、Adobe AIR 2.5ではモバイルデバイスに対応とのこと。 Flex SDK 「Hero」とFlash Builder 「Burrito」を使用したモバイルアプリケーション開発 ダウンロードはAdobe Labsから ・Adobe Flex SDK "Hero"
デブサミで発表したアドビの轟さん Flexで作るAndroidアプリ開発チュートリアル 1
FlexUGにも行かないとなぁ。
Androidのメモリ管理について調べていたら、 Androidの仕組みを知る(2) コーディングはJavaだけどDalvikVMっていう仮想システムで動いているんですね。
AndroidってJavaだからGCで勝手にメモリ管理してくれるでしょ?
と思うけど、調べてみると実はそうでもないみたい。
AndroidでActivityを頻繁に利用する以上、参照の状況次第ではすぐにメモりリークになる危険性もあるとのこと。 Androidでのメモリリーク回避 iOSに比べればGCが使えて便利な気もするが、だからといって放置はNGですね。
ListViewでデータを表示できたら、次はイベント処理。 まずは以下のサイトを参考にしてみた。 Androidアプリのインタフェース ~ListViewのイベント処理~
android.widget.ListView android.widget.AdapterView android.view.View.OnClickListener [java] ListView listView = (ListView)findViewById(R.id.ListView); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> adapter, View view, int position, long id) { //処理 } }); [/java]
setOnItemClickListener → AdapterView.OnItemClickListener → クリックイベント発生
みたいな解釈でいいのかな?
2.8 AdapterView を使ったデータのバインディング Gallery, ListView,Spinner はAdapterViewのサブクラスで、その中に
ItemClick(AdapterView parent, View v, int position, long id)
を持っているわけですね。
深く理解はできなけど、まぁそんな感じだろうと言う事で。 ちになみにListViewを利用する際は、ListViewActivityを継承すると便利らしいです。
android.app.AlertDialog; android.content.DialogInterface; [java] AlertDialog.Builder diag = new AlertDialog.Builder(SampleApp.this); diag.setTitle("Select Value"); diag.setMessage("テスト");
DialogInterface.OnClickListener listner = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setResult(RESULT_OK);
}
};
diag.setPositiveButton("OK",listner);
diag.create();
diag.show();
[/java]
また、上記の書き方だと行数が増えるので、簡易に出力したい場合は1センテンスで。 [java] public static AlertDialog show(Context context, CharSequence title, View view, CharSequence buttonText, OnClickListener buttonListener, CharSequence button2Text, OnClickListener button2Listener, boolean cancelable, OnCancelListener cancelListener); [/java] この辺はiOSのAlertViewと似たような感じですね。
以下のサイトなどを参考にしながら作成してみる。 [android] androidでBingでJSONで Android で JSON を使おう ~ 前編 ~ Android で JSON を使おう ~ 後編 ~
まずインターネット接続を許可する為に、AndroidManifest.xmlに以下を記述する。 [java]
[/java] 次にHTTPリクエスト&レスポンスの実装 [java] SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register( new Scheme( HttpHost.DEFAULT_SCHEME_NAME, PlainSocketFactory.getSocketFactory(), 80 ) );
HttpParams httpParams;
httpParams= new BasicHttpParams();
HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(httpParams, HTTP.UTF_8);
httpClient = new DefaultHttpClient(
new ThreadSafeClientConnManager(httpParams, schemeRegistry),
httpParams
);
[/java] HTTPリクエストは、まずSchemeRegistry()でプロトコルを設定する。 そして、BasicHttpParams()でヘッダ情報をパラメータ生成し、DefaultHttpClient()でリクエストする。 通信は、ThreadSafeClientConnManager()で非同期通信をしている。
[java] Uri.Builder uriBuilder = new Uri.Builder(); uriBuilder.scheme("http"); uriBuilder.authority("192.168.1.52"); uriBuilder.path("/api/areas");
String uri = uriBuilder.toString();
HttpUriRequest httpRequest = new HttpGet(uri);
//HTTP Request送信
HttpResponse response = null;
try{
response = httpClient.execute(httpRequest);
} catch(Exception e) {
setListItem(e.toString());
return;
}
[/java] schemeにプロトコル、authorityにホスト、pathにURLパスを記述する。 HttpClient.executeでリクエストするが、例外処理が必須。 こういうのは、Javaのきめ細かさですね。
HTTPレスポンスからInputStreamReaderとBufferdReaderを使って行を読み、StringBuilderに追加する [java] StringBuilder json = new StringBuilder(); try{ HttpEntity entity = response.getEntity(); InputStream input = entity.getContent(); InputStreamReader reader = new InputStreamReader(input); BufferedReader bufReader = new BufferedReader(reader); String line; while((line = bufReader.readLine()) != null){ json.append(line); } } catch(IOException e) { setListItem("バッファ読み込み失敗"); return; } [/java]
import org.json.* [java] private void loadValues() { try{ JSONObject jsonRoot = new JSONObject(json.toString()); JSONArray jsonAreas = jsonRoot.getJSONArray("areas");
List<String> items = new ArrayList<String>();
int i;
for (i = 0; i < jsonAreas.length(); i++){
JSONObject jsonRslt = jsonAreas.getJSONObject(i);
String title = jsonRslt.getString("area_code");
String url = jsonRslt.getString("area_name");
items.add(title + " " + url);
}
setListItems(items);
} catch(JSONException e) {
setListItem("JSON Error");
return;
}
}
private void setListItem(String item){
ListView listView = (ListView)findViewById(R.id.ListView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
new String[]{ item }
);
listView.setAdapter(adapter);
}
private void setListItems(List<String> items){
ListView listView = (ListView)findViewById(R.id.ListView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
items
);
listView.setAdapter(adapter);
}
[/java] JSONObjectのコンストラクタに、テキストデータをつっこむ。 生成したJSONObject以降は、各自データ構造によるが、上記の例の場合 getJSONArrayにキーを設定して、JSONArrayを取得している。
そしてforループで回して処理する。 この辺は、Objective-Cとは手順が違いますね。 むしろ原始的なコードなので取っつきやすいかもしれないが、少々回りくどい気もする。
まず、layout/main.xmlでレイアウトを作成しておく。 ※ListView
次に、先ほど生成したJSONArrayデータをListViewにバインディングするが、Adapterが肝っぽいですね。 ArrayAdapterを生成して、ListViewにsetAdapterする。
と言う事で、参考ページのおかげもあってすんなり実装できました!
[java] import android.app.Activity; import android.os.Bundle; import org.json.*; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.HttpVersion; import org.apache.http.params.HttpParams; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.http.protocol.HTTP; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpUriRequest;
import android.view.View; import android.widget.ListView; import android.widget.ArrayAdapter; import android.widget.Button;
import android.net.Uri; import android.view.View.OnClickListener;
import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.InputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List;
public class Yosou extends Activity implements OnClickListener { String json; DefaultHttpClient httpClient;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//スキーマ登録
SchemeRegistry schReg = new SchemeRegistry();
schReg.register(
new Scheme(
HttpHost.DEFAULT_SCHEME_NAME,
PlainSocketFactory.getSocketFactory(),
80
)
);
//HTTPパラメータ設定
HttpParams httpParams;
httpParams= new BasicHttpParams();
HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(httpParams, HTTP.UTF_8);
//HTTPクライアント生成
httpClient = new DefaultHttpClient(
new ThreadSafeClientConnManager(httpParams, schReg),
httpParams
);
Button loadButton = (Button)findViewById(R.id.loadButton);
loadButton.setOnClickListener(this);
}
public void onClick(View v) {
// URIを設定
Uri.Builder uriBuilder = new Uri.Builder();
uriBuilder.scheme("http");
uriBuilder.authority("192.168.1.52");
uriBuilder.path("/yosou/api/race_forecast_areas");
String uri = uriBuilder.toString();
HttpUriRequest httpRequest = new HttpGet(uri);
//HTTP Request送信
HttpResponse response = null;
try{
response = httpClient.execute(httpRequest);
} catch(Exception e) {
setListItem(e.toString());
return;
}
// レスポンスコードを確認
if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK){
setListItem(
String.format(
"Response Error code = %d",
response.getStatusLine().getStatusCode()
)
);
return;
}
//JSON取得
StringBuilder json = new StringBuilder();
try{
HttpEntity entity = response.getEntity();
InputStream input = entity.getContent();
InputStreamReader reader = new InputStreamReader(input);
BufferedReader bufReader = new BufferedReader(reader);
String line;
while((line = bufReader.readLine()) != null){
json.append(line);
}
} catch(IOException e) {
setListItem("buffer Error");
return;
}
// JSON解析
try{
JSONObject jsonRoot = new JSONObject(json.toString());
JSONArray jsonAreas = jsonRoot.getJSONArray("areas");
List<String> items = new ArrayList<String>();
int i;
for(i = 0; i < jsonAreas.length(); i++){
JSONObject jsonRslt = jsonAreas.getJSONObject(i);
String title = jsonRslt.getString("area_code");
String url = jsonRslt.getString("area_name");
items.add(title + " " + url);
}
setListItems(items);
}
catch(JSONException e){
setListItem("JSON Error");
return;
}
return;
}
private void setListItem(String item){
ListView listView = (ListView)findViewById(R.id.ListView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
new String[]{ item }
);
listView.setAdapter(adapter);
}
private void setListItems(List<String> items){
ListView listView = (ListView)findViewById(R.id.ListView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
items
);
listView.setAdapter(adapter);
}
} [/java]
触ってみないとわからないとは言っても、わからない事にぶつかったらネット検索、リファレンスは基本ですよね。 Android Developer Reference
Eclipseを利用するので、ヒエラルキーを追うのも効率的かもしれない。
さて、リファレンスを読む前に適当にプロジェクトを作成して感覚を掴んでみる。
・src/パッケージ名/ でプログラムソース管理。 ・genは基本的には自動ビルドされるとR.javaも自動更新されるので、いじる事はそんなにないっぽい。 ・assetsはリソース系のファイルを置くんだろう。 ・res/drawable-xxx にicon.pngが置いてあるが、解像度毎にアイコンを設置するっぽい ・layout/main.xml はView定義 ・values/strins.xml はプロパティ定義 ・AndroidManifest.xmlでアプリ全体の設定
非常に分かりやすい構成だと思う。
Graphical Layoutモードは、iPhone開発で言うInterface Builderにあたる部分だが、GUIはAppleと比べるとイマイチ感。 また、テキストモードでxmlを直接テキストコーディングする事もできる。 iPhoneだとxibファイルに相当するけど、直接コーディングする事はまずないでしょう。
各コンポーネントの種類は以下の通り。 -Views
-Layout
適当にレイアウトしたxmlはこんな感じ。
このプロパティの定義はいいですね。 ただ、Interface Builderみたいにドラッグ&ドロップでViewとバインディングする方法がわからない(って、そもそもできるのか?)
とりあえずmain.xml側でオブジェクトを右クリックしてみると色々メニューが出てくる。 多分、この辺だろうと推測するも眠いので今日はおしまい。
Androidの勉強を再開するけど、2009年の本だけど大丈夫かな? 開発環境をMacにするかWindowsにするか迷うところだが、とりあえずMacで。
Windowsの設定はAndroidはじめでメモした通り。 新iMacに環境作ってなかったので、おさらい。
Eclipse Hileosをベースにした。
http://www.eclipse.org/downloads/ IDE for Java Developersがシンプルだが、Helios PHP Developmentにしてみた。
日本語化は取りあえずあとでする事に。 http://mergedoc.sourceforge.jp/
Download the Android SDKからダウンロードし、以下に展開。
/Developer/android-sdk-mac_x86
SDKのパスをbash_profileに追加。
PATH=$PATH:/Developer/android-sdk-mac_x86/tools
ヘルプ>ソフトウェアインストールを開く。
Work with:には以下のアドレスを入力して、インストールする(ちょっと時間がかかる)。
https://dl-ssl.google.com/android/eclipse/
インストールが完了してEclipse再起動後、Android AVD Managerアイコンが現れるのでクリック。
Installed Packagesで全てアップデートする(結構時間がかかる)。
VirtualDeviceは最新バージョン2.3.3で設定した。 てか、次期バージョン3系はandroid-sdk_r09じゃできないのかな?
最後に、Eclipse>環境設定>Androidでパスを通し、もう一度Eclipseを再起動。
Hello Worldプロジェクト作って、起動確認。