ubuntu11.04(x64)でJDK6+Eclipse+Androidアプリ開発環境
2011-09-26-1 / カテゴリ: [linux][Java][ubuntu][Android] / [permlink]

デスクトップで開発できるように環境構築。

JDK6

ここを参考: Ubuntu 11.04 日本語 Remix CD からのインストールログ
このまま叩けばOK
# add-apt-repository "deb http://archive.canonical.com/ natty partner"
# apt-get update
# aptitude install sun-java6-jdk

これで以下のjavaが入る(2011-09時点)
zaki@cheddar% java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
zaki@cheddar% javac -version
javac 1.6.0_26

Eclipse

ここを参考: Ubuntu 11.04 Eclipse 3.6 Heliosのインストール

aptだと3.5.2が入るみたいなので、公式から3.6を持ってきた。このへんのEclipse IDE for Java DevelopersのLinux 64-bitから。
ダウンロードしたら、適当な場所で展開すればOK。それだけ。
自分とこは /home/zaki/local/eclipse に置いてる。

日本語化(Pleiades)については公式から1.3.3のzipを落としてくる。
適当にunzipしたら、featuresとpluginsディレクトリをeclipse直下にコピーして、eclipse.iniを編集すればOK
zaki@cheddar% cp -a features ~/local/eclipse             [~/Downloads/pleiades]
zaki@cheddar% cp -a plugins ~/local/eclipse              [~/Downloads/pleiades]

--- eclipse.ini.org     2011-09-26 21:49:04.095663261 +0900
+++ eclipse.ini 2011-09-26 22:27:57.125662531 +0900
@@ -17,3 +17,4 @@
 -XX:MaxPermSize=256m
 -Xms40m
 -Xmx384m
+-javaagent:/home/zaki/local/eclipse/plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar
readmeには javaagent:plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar としか書かれていないけれど、eclipseの実行ディレクトリからの相対パス(あるいは絶対パス)で記述していないとエラーになるため「eclipseのインストールディレクトリにPath設定してどこからでも起動可能に設定」とかできなくなってしまうので絶対パスで記述。

あとはWindowsと同じ要領で
% eclipse -clean
で起動してやればOK

Android SDK

公式からLinux用のtgzを落としてきて、適当なディレクトリに展開。Windowsと違ってSDK Manager.exeはなく、tools/android を実行すればOK。
ただしSDKは32bit版しかないため、64bitOSの場合は、ia32-libsパッケージが必要なのでインストールしておく。
([2011-09-23-1]で書いてる内容で flashplugin-installer をaptでインストール済みなら依存で入っているはず)
自分とこは /home/zaki/local/android-sdk に置いて、toolsとplatform-toolsにPath設定してる。

SDK起動後の操作と、(eclipseから実行する)ADTについては省略!

実機との接続

手持ちの実機はほとんど(HTC Desire(X06HTII)/Nexus S/XOOM au版/XPERIA X10 mini pro)はケーブルを繋ぐだけでadbが認識してパッケージインストールやLogCatなど問題なく動作したけど、T-01C(ドコモ版REGZAフォン)のみシリアルNoが"????????"と表示されて認識されなかった。
みたいなことをツイートした@lgfuserさんと@sato_cさんからノータイムで教えて いただき ました m__m

WindowsのときにデバイスマネージャでベンダーIDとか書き写してドライバインストールしたり面倒だった作業に相当するのかな。
こちらを参照: http://developer.android.com/guide/developing/device.html

結局T-01Cの場合は以下のファイルを作成してUSBケーブルを接続しなおせばadbで認識した。
root@cheddar:/# cat /etc/udev/rules.d/51-android.rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="0930", MODE="0666"
複数デバイス記述が必要な場合は、2行目3行目と追記していけばよさげ。

あとは旧環境からデバッグキーを持ってくるなりエクスポートした設定を持ってくるなりすればOK


まぁもうすぐ11.10になるんだろうけど…

Preferencesで設定値の読書き
2011-06-08-1 / カテゴリ: [Java][Android] / [permlink]

設定の読書き。というか備忘録。
SharedPreferencesインスタンス経由で読んで、SharedPreferences.Editor経由で書き込む。

PreferenceActivity(PreferenceScreen)はまたそのうち。

続きを読む
Referrer (Inside): [2011-07-03-1]

日付の取得・変換(java.util.Calendar / java.util.Date)
2011-06-03-1 / カテゴリ: [Java] / [permlink]

今更メモ。すぐわからなくなるので。

現在の年月日・時分秒を取得する。

Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int min = cal.get(Calendar.MINUTE);
int sec = cal.get(Calendar.SECOND);
int msec = cal.get(Calendar.MILLISECOND);

現在のUNIX time(msec)を取得する。

long utc = System.currentTimeMillis();

UNIX timeを元に年月日・時分秒を取得する

long time = System.currentTimeMillis();
// time をなんか更新
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(time);

年月日・時分秒を指定してCalendarの日時をセット

Calendar cal = Calendar.getInstance();
cal.set(year, month - 1, day, hour, min, 0);
set(Year, Month, Day) や set(Year, Month, Day, Hour, Min) もある。未指定の場合はセット前の値が引き継がれる。ゆえに、ミリ秒の指定は(多分)できないので(set()を使う限りは)getInstance()時の時刻のままになる。

CalendarインスタンスからUNIX timeを取得

Calendar cal = Calendar.getInstance();
// cal をなんか操作
long utc = cal.getTimeInMillis();

CalendarインスタンスからDateインスタンスを取得

Calendar cal = Calendar.getInstance();
// calを何か操作
Date date = cal.getTime();

Dateインスタンスの指定でCalendarの日時をセット

long utc = System.currentTimeMillis();
Date date = new Date(utc);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
System.out.println("eq? " + (cal.getTimeInMillis() == utc));
// 出力はtrue

DateインスタンスからUNIX timeを取得

// ↑のコードの続きで
System.out.println("eq? " + (date.getTime() == utc));
// 出力はtrue

AlarmManagerで単純にブロードキャストを投げるだけ
2011-02-06-2 / カテゴリ: [Java][Android] / [permlink]

__軽く__ググってみても、「指定Activityを起動」「BroadcastReceiverをextendsした自前レシーバで受ける」しか見つけられなかったので「特定Activityが生きてれば受ける、なければ無視」をお試し。

ちなみに、定期/定時処理の実装は以下の方法がある(ほかにも有るかも。知らないだけで)
Timerアプリで管理
AlarmManagerシステム(android)で管理
するようなイメージみたい。(thanks! @amay077さん)
AlarmManagerはシステムレベルで動作するので、アプリの寿命と独立してるのがポイント。

public final static String INTENT_ACTION = "alarmmgr_broadcast";
:
:
	AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);

	Intent intent = new Intent(INTENT_ACTION);
	PendingIntent pending = PendingIntent.getBroadcast(this, 0, intent, 0);

	long current = SystemClock.elapsedRealtime();
	// 5秒後(current + 5*1000)にpending発動(1回きり)
	am.set(AlarmManager.ELAPSED_REALTIME, current + 5*1000, pending);
このBroadcastを受けるには[2011-02-06-1]の例で。

指定時間にブロードキャストでなく、単にActivityを起動するだけなら、
Intent intent = new Intent(this, FooBar.class);
PendingIntent pending = PendingIntent.getActivity(this, 0, intent, 0);
こんな感じで。サービス起動もいけそう(getService()で)。

AlarmManager.ELAPSED_REALTIME で「○msec後」に起動設定になる。
「Y年m月d日H時M分S秒に」の場合は、AlarmManager.RTC を使う
			Calendar cal = Calendar.getInstance();
			cal.set(2011, 1, 6, 3, 0, 0);	// 2011-02-06 03:00:00 の場合。monthは0オリジン(-1する)
			long next = cal.getTimeInMillis();
			Log.d(TAG, "current: " + next);
			am.set(AlarmManager.RTC, next, pending);

前記のAlarmManager#setは、指定時間に単に起動するのみ。
定期的に実行するにはAlarmManager#setRepeating()を使う。

キューに入ってるアラームを停止するにはcancel()
am.cancel(pending);
キャンセルは、Intentが同じ(filterEquals()がtrue)ものが対象らしい。
Remove any alarms with a matching Intent. Any alarm, of any type, whose Intent matches this one (as defined by filterEquals(Intent)), will be canceled.

AlarmManager#cancel

参考
Service(サービス)関連 mucchinのAndroid戦記
AlarmManagerで指定した時間に処理させる - Tech Booster
AlarmManager - 愚鈍人
Taosoftware: AlarmManager1 AndroidでCronみたいなことをするには
AlarmManagerの使用 - すにぺっと

レシーバおぼえがき(BroadcastReceiver)
2011-02-06-1 / カテゴリ: [Java][Android] / [permlink]

そのActivityがtopにいる場合にブロードキャストを受けるには。
public class FooBar extends Activity {
:
:
    // スレッドの通知を受けるためのレシーバ
	private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			Log.d(TAG, "  onReceive(" + context + ", " + intent + ")");
			if (intent.getAction().equals(Internal.INTENT_ACTION)) {
				Log.d(TAG, "intent val: " + intent.getIntExtra(Internal.INTENT_VAL, 0));
			}
		}
	};
	@Override
	public void onResume() {
		super.onResume();
		Log.d(TAG, "onResume()");
		// レシーバの登録
		registerReceiver(mReceiver, new IntentFilter(Internal.INTENT_ACTION));
	}
	
	@Override
	public void onPause() {
		super.onPause();
		Log.d(TAG, "onPause()");
		// レシーバの解除
		unregisterReceiver(mReceiver);
	}
:
registerReceiver()第2引数でフィルタを設定しているので、onReceive()内でgetAction()でAction名をチェックしてるのはこの例では冗長。
(rergisterReceive()を複数叩いて複数のレシーバを受ける場合は必要)

おまけ
↑のInternalは別クラス(ブロードキャスト元)
投げる部分はこんな感じ。(適当)
public class Internal extends Activity {
	public final static String INTENT_ACTION = "internal_thread_broadcast";
	public final static String INTENT_VAL = "internal_thread_val";
	private int mCount = 0;

// 中略
			Thread thread = new Thread(new Runnable() {

				@Override
				public void run() {
					// TODO 自動生成されたメソッド・スタブ
					try {
						for (;;) {
							Thread.sleep(1000);
							mCount ++;
							Log.d(TAG, "running count("+ mCount + ")");
							Intent intent = new Intent(INTENT_ACTION);
							intent.putExtra(INTENT_VAL, mCount);
							sendBroadcast(intent);
						}
					} catch (InterruptedException e) {
						// TODO 自動生成された catch ブロック
						e.printStackTrace();
					}
				}
				
			});
			thread.start();

// 後略
Referrer (Inside): [2011-02-06-2]

PKCS#5パディングでAES暗号化/復号
2011-01-25-2 / カテゴリ: [暗号][Java][Android] / [permlink]

初のAndroidネタ。というかJavaネタも初だった^^;

Androidは初学者だからもっと初学者ネタ(環境構築とか?)でもと思ったけど、入門系情報はたくさんあるので、うちらしく戯術っぽく小ネタで(ぇ
続きを読む
カテゴリ: Java

最終更新時間: 2013-05-02 16:12