Xperia arcの実機だが、GPSの切り替えがセキュリティポリシ上、アプリからできないみたいだ。
[java] function void changeGps(boolean isGps) { LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); if (locationManager != null) { if (isGps) { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); Settings.System.putInt(getContentResolver(), Settings.System.LOCATION_PROVIDERS_ALLOWED, 1); //Settings.Secure.putInt(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, 1); } else { locationManager.removeUpdates(this); Settings.System.putInt(getContentResolver(), Settings.System.LOCATION_PROVIDERS_ALLOWED, 0); //Settings.Secure.putInt(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, 0); } } } [/java] ここでSettiings.Secure 部分を有効にしてマニュフェストファイルで android.permission.WRITE_SECURE_SETTINGS と設定してもエラーになる。
ちなみにGoogle非公開のやり方では、機種によって動作した。 ※Xperia arcでは動かなかったが・・・ [java] function void changeGpsOn() { Uri uri = Uri.parse("custom:3"); Intent intent = new Intent().setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider") .addCategory(Intent.CATEGORY_ALTERNATIVE) .setData(uri); sendBroadcast(intent); } [/java] custom:3 ってのがGPSらしい。
通常の設定切り替えは、putInt() してやるだけで切り替わるが、 機内モード(3Gの有効/無効)に関しては、常駐のブロードキャストレシーバーにインテントを送信してやる必要がある。 [java] private void changeAirplaneModeService(boolean isAirplaneMode) { int airPlaneMode = isAirplaneMode ? 1:0; Settings.System.putInt(getContentResolver(), Settings.System.AIRPLANE_MODE_ON, airPlaneMode);
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", airPlaneMode);
sendBroadcast(intent);
}
[/java]
Settings の書き換えのため permission も変更を忘れないように。
[as3] require(ファイル名) [/as3]
物理エンジンはCoron SDK で標準サポートされているが、パッケージを指定する事なく、requireできる。 [as3] local physics = require("physics") physics.start() [/as3]
具体的に実装してみる。
(1) 各アクティビティファイル データモデルファイル、DB等のメイン処理
(2) DatabaseHepler -> SQLiteOpenHelper SQLiteOpenHelper を継承し、DB接続、テーブル管理等の基本処理
(3) SettingDao データモデルに関する、SELECT、INSERT、UPDATE等を実行
(4) Setting データモデル
XCode では CoreData でDBマッピング、管理機能が搭載されているが、Android ではSQLを実際に記述したりと、ちょっと手続きが増える。
コンストラクタでDB接続と、SQLiteDatabase クラスのインスタンスを取得することができる。
DBが存在しない場合は onCreate() が呼ばれるので、onCreate() でスキーマを作成する。 ここでDBを扱った人なら問題ないとは思うが、各テーブルには rowid のようにIDフィールドを追加する事が推奨されている。
またDBバージョンが異なる場合は、onUpgrade() が呼ばれるので、これを利用して管理する。 マイグレートの管理はバージョン番号を使ってやるのか?効率よく管理する方法は、ちょっと不明です。
[java] import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "Selector.db";
private static final int DATABASE_VERSION = 1;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS settings (" +
"rowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
" is_active INTEGER, " +
" name STRING" +
")"
);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS settings");
onCreate(db);
}
} [/java]
setter、getter でデータモデルを作成する。
[java] public class Setting { private long rowid; private boolean isActive; private String name;
//getter
public long getRowid() {
return rowid;
}
public String getName() {
return name;
}
public boolean getIsActive() {
return isActive;
}
//setter
public void setRowid(long rowid) {
this.rowid = rowid;
}
public void setName(String name) {
this.name = name;
}
public void setIsActive(boolean isActive) {
this.isActive = isActive;
}
} [/java]
DAOファイルには、DBカラムを定義し、SELECT、INSERT、UPDATE、DELETE 等のSQL処理や、モデルデータ(ここではSetting)にマッピングをする。
[java] import java.util.ArrayList; import java.util.List;
import Setting; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase;
public class SettingDao { private static final String TABLE_NAME = "settings";
private static final String COLUMN_ID = "rowid";
private static final String COLUMN_IS_ACTIVE = "is_active";
private static final String COLUMN_NAME = "name";
private static final String[] COLUMNS = {
COLUMN_ID,
COLUMN_IS_ACTIVE,
COLUMN_NAME
};
private SQLiteDatabase db;
public SettingDao(SQLiteDatabase db) {
this.db = db;
}
//入力
public long insert(Setting setting) {
ContentValues values = new ContentValues();
values.put(COLUMN_IS_ACTIVE, setting.getIsActive());
values.put(COLUMN_NAME, setting.getName());
return db.insert(TABLE_NAME, null, values);
}
//更新
public int update(Setting setting) {
ContentValues values = new ContentValues();
values.put(COLUMN_IS_ACTIVE, setting.getIsActive());
values.put(COLUMN_NAME, setting.getName());
String where = "rowid = " + setting.getRowid();
return db.update(TABLE_NAME, values, where, null);
}
//全取得
public List<Setting> fetchAll() {
List<Setting> values = new ArrayList<Setting>();
Cursor cursor = db.query(TABLE_NAME, COLUMNS, null, null, null, null, COLUMN_CREATED_AT);
while (cursor.moveToNext()) {
Setting setting = new Setting();
setting.setRowid(cursor.getInt(0));
setting.setIsActive(isBooleanForInt(cursor.getInt(1)));
setting.setName(cursor.getString(2));
values.add(setting);
}
return values;
}
//取得
public Setting fetch(long rowid) {
String where = "rowid = " + rowid;
Cursor cursor = db.query(TABLE_NAME, COLUMNS, where, null, null, null, null);
while (cursor.moveToNext()) {
Setting setting = new Setting();
setting.setRowid(cursor.getInt(0));
setting.setIsActive(isBooleanForInt(cursor.getInt(1)));
setting.setName(cursor.getString(2));
return setting;
}
return null;
}
//削除
public int delete(int rowid) {
String where = "rowid = " + rowid;
return db.delete(TABLE_NAME, where, null);
}
private boolean isBooleanForInt(int value) {
return (value == 1);
}
} [/java] DBとモデルデータのマッピングは Cursor を使って Itarate している。 ただ、Cursorからデータを取得するのにインデックスを利用するのはちょっと怖い気がする。 (他にやり方があるかも?) boolean の扱いはこの方法でいいのか定かではないが、差し当たり。
実際に、アクティビティでDBを操作してみる。
■ListViewに表示する [java] private void loadSetting() { loadDeviceStatus();
DatabaseHelper databaseHelper = new DatabaseHelper(this);
SQLiteDatabase db = databaseHelper.getReadableDatabase();
SettingDao settingDao = new SettingDao(db);
settings = settingDao.fetchAll();
db.close();
ListView listView = (ListView) findViewById(R.id.list);
SettingListAdapter adapter = new SettingListAdapter(this, R.layout.setting_list_item, settings);
listView.setAdapter(adapter);
}
[/java] リスト表示に関しては、「ListViewのカスタマイズ」等を参照。
■データ入力する [java] public void save() { EditText nameEditText = (EditText) findViewById(R.id.nameEditText); ToggleButton activeButton = (ToggleButton) findViewById(R.id.activeButton);
DatabaseHelper databaseHelper = new DatabaseHelper(this);
SQLiteDatabase db = databaseHelper.getWritableDatabase();
SettingDao settingDao = new SettingDao(db);
Setting setting = new Setting();
setting.setName(nameEditText.getText().toString());
setting.setIsActive(activeButton.isChecked());
settingDao.insert(setting);
db.close();
}
[/java]
アプリケーションのタイトルバーを非表示にするには、setContentView より前に requestWindowFeature(Window.FEATURE_NO_TITLE) を実行する。 [java] public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main); } [/java]
OS10.6.6で「く」とことえりでローマ字入力すると「u 」と入力されてしまう。 似たような症状が 「ローマ字打ちが特定の文字でできない」に報告されていたので、その記載のうち以下の対処をしたら、直りました。
以下のファイルを捨てて、再起動。
$HOME/Library/Preferences/com.apple.inputmethod.Kotoeri.plist $HOME/Library/Preferences/com.apple.JapaneseAnalysis $HOME/Library/Preferences/com.apple.KotoeriPreferences.plist $HOME/Library/Preferences/com.apple.KotoeriWordRegister.plist
Wifi の切り替えはWifiManager クラスで設定する。
Wifiの有効設定は setWifiEnabled で設定、ステータスは getSystemService(WIFI_SERVICE) で取得する。 [java] private void changeWifiService(boolean isWifi) { WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); if (wifiManager != null) { wifiManager.setWifiEnabled(isWifi); wifiStatus(); } }
public void wifiStatus() {
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
int wifiState = wifiManager.getWifiState();
switch (wifiState) {
case WifiManager.WIFI_STATE_DISABLING:
Log.d("WifiState", "WIFI_STATE_DISABLING");
break;
case WifiManager.WIFI_STATE_DISABLED:
Log.v("WifiState", "WIFI_STATE_DISABLED");
break;
case WifiManager.WIFI_STATE_ENABLING:
Log.d("WifiState", "WIFI_STATE_ENABLING");
break;
case WifiManager.WIFI_STATE_ENABLED:
Log.d("WifiState", "WIFI_STATE_ENABLED");
break;
case WifiManager.WIFI_STATE_UNKNOWN:
Log.d("WifiState", "WIFI_STATE_UNKNOWN");
break;
}
}
[/java]
FlexUGに久々に行ってきました。
真面目なデモは、まぁそれなりでいたが、Lite Talking の内容が濃かったです。
今、流行に流行ってる NFC ネタ。 Felica のカードでVideo Player にタグを入れたり、音楽再生したり。
Air & Flex & NFC ネタは Felica Developer's Blog にまとまってます。 その他、Flash/AIRとFeliCaの連携 - 携帯電話の制御 とか Sony Felica SDK も。 開発はWindowsじゃないとできない?
てか、
2009年に発表されてたって知らなかったorz
いやぁ、作るアプリによっては Flex 4 でのスマフォ開発はありかも知れない。
という事で、家にあった 「Sony PaSoRi」カードリーダー(Windows用)を Mac で試してみる事に。 しかも Air アプリです!
まず、前述のドライバー FeliCa Proxy を起動する。
次に、FLO:Qの Widget Manager をインストール後、電子マネービューワー をインストールするだけ。
4,350円入ってました。
あと、面白かったのは AWS の管理ツール。 Flex Coder
Amazon の API にActionScript がない!
って、ことでSWCライブラリを作ったそうです。
認証部分が面倒らしく、そこら辺をFlex仕様でまとめてます。 基本インスタンスを作成して、プロパティを設定するだけ。
これ見て、「あぁやっぱAmazonのサーバ使おうかな?」と思ったりw