この一ヶ月強、UbuntuでBansheeとかで音楽を聞いていると1、2秒ぐらいの長さの部分を何度も繰り返す(DJとかがレコードをキコキコやるスクラッチみたいな感じ)不具合が多発してうんざりしていた。
OSをUbuntuからLinux Mintに切り替えてみたりしたのだが、不具合はなおらず。どうしたものかと思っていた。たまに不具合がなくなり安定する時もあるのだがそれがどういう条件でそうなるのか分からない。
Google Chrome上で動画を見ているときもやはり同じように繰り返しが起きたり、ひどいときには早回し再生のようになってまったく見れなくなる。ところがある時試しにFirefoxで見てみるとかなり安定して再生できる。
そうこうしているうちにChromeを立ち上げていないとBansheeなど音楽アプリでも不具合無く再生できることを発見。色々とググったり試行錯誤してみるとどうもChromeのFlashを無効に設定すれば不具合が消える様子。
どうもこれまではNetscape Plugin API(NPAPI)というAPI上でFlashを動かしていたのだが、最近はChrome独自?のPepper APIというAPI上に移行した様子。これが腐っているのではという感触。
とりあえずChromeはFlashを無効にしてFlashが必要なサイトはFirefoxで見るようにした。
2012年8月12日日曜日
2012年5月23日水曜日
minSdkVersion, targetSdkVersionとProject Build TargetのSDKバージョンの違い
Androidのアプリを作成する時にはManifestファイルに
さらにビルドするときに使用する SDKのバージョンもあります。
これらの違いはよく混乱するので簡単に纏めておきます。
minSdkVersion
指定したバージョン以上のシステムでならアプリが動作することを示します。これ未満のバージョンのシステムにはアプリはインストールできません。
動作することを保証するのは開発者の責任です。使用しているクラス・メソッドのAPIレベルを確認し、必要なら対処しましょう。
targetSdkVersion
指定したバージョンより新しいシステムではコンパチビリティを保証するためtargetSdkVersionで指定したシステムと同じように動作するようになります。
例えばこの値を11未満(Android 3.0.x HONEYCOMB未満)にするとたとえAndroid 3.0.xのシステムでもデフォルトのテーマはこれまでの @android:style/Theme になります(forward-compatibility)。
11に設定していればAndroid 3.0.xのシステムではHONEYCOMBスタイルの @android:style/Theme.Holo が使用されます。他にもAction Barの使用やオプションメニューがなくなる等の影響がでてきます。
アプリを作成した場合はエミュレータや実機で動作を十分に確認すると思いますが、そこで確認したことが保証されるよう確認に使用したバージョンをここに指定しましょう。
Buildに使用するSDKのバージョン
EclipseならPackage ExplorerのProperties - Android - Project Build Targetで指定するSDKのバージョンです。
この値によってソースコードで使用できるクラスやメソッドが決まります。targetSdkVersionより大きい値も設定できます。その場合、使用しているクラス・メソッドのAPIレベルを確認し対処するのは開発者の責任です。
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="7"/>等のようにSDKのバージョン(APIレベル)を設定すると思います。
さらにビルドするときに使用する SDKのバージョンもあります。
これらの違いはよく混乱するので簡単に纏めておきます。
minSdkVersion
指定したバージョン以上のシステムでならアプリが動作することを示します。これ未満のバージョンのシステムにはアプリはインストールできません。
動作することを保証するのは開発者の責任です。使用しているクラス・メソッドのAPIレベルを確認し、必要なら対処しましょう。
targetSdkVersion
指定したバージョンより新しいシステムではコンパチビリティを保証するためtargetSdkVersionで指定したシステムと同じように動作するようになります。
例えばこの値を11未満(Android 3.0.x HONEYCOMB未満)にするとたとえAndroid 3.0.xのシステムでもデフォルトのテーマはこれまでの @android:style/Theme になります(forward-compatibility)。
11に設定していればAndroid 3.0.xのシステムではHONEYCOMBスタイルの @android:style/Theme.Holo が使用されます。他にもAction Barの使用やオプションメニューがなくなる等の影響がでてきます。
アプリを作成した場合はエミュレータや実機で動作を十分に確認すると思いますが、そこで確認したことが保証されるよう確認に使用したバージョンをここに指定しましょう。
Buildに使用するSDKのバージョン
EclipseならPackage ExplorerのProperties - Android - Project Build Targetで指定するSDKのバージョンです。
この値によってソースコードで使用できるクラスやメソッドが決まります。targetSdkVersionより大きい値も設定できます。その場合、使用しているクラス・メソッドのAPIレベルを確認し対処するのは開発者の責任です。
2012年1月14日土曜日
Android - Javaでの文字列から小数への変換
色々な国で使われるアプリだと小数点がコンマ(,)で表現されるところもあることを意識しましょう。主にヨーロッパとかロシア、南米ですね(参考)。
EditTextビュー等に入力された文字列を数値に変換する時に
String str = someEditTextView.getText().toString();
String str = someEditTextView.getText().toString();
EditTextビュー等に入力された文字列を数値に変換する時に
String str = someEditTextView.getText().toString();
float v = Float.valueOf(str);
として値を取り出すとコンマが小数点だと認識されずに例外(NumberFormatException)が発生してしまいます。
小数点がピリオド(.)でもコンマ(,)でも正しく文字列を値に変換するには
NumberFormat nf = NumberFormat.getInstance(); // デフォルトのロケールを使う
Number n = nf.parse(str);
float v = n.floatValue();
等としましょう。これならロケールに合わせてピリオドやコンマを正しく小数点と認識してくれます。
また値を入力するためのEditTextビューに
<EditText
...
android:inputType="numberDecimal"
/>
と数字関係の文字のみ入力できるようにしている場合には
android:digits="0123456789.,"
等と入力できる文字を指定してコンマも入力できるようにしましょう。
2011年12月30日金曜日
Android Service を自動的に再起動する方法
Androidで常駐するアプリを作るときはサービスを用いて基本的にはずっと起動させておく。ところが以下の場合にはサービスが停止されてしまう。その場合に再起動させる方法を以下に示す。
1) Android OSがメモリ等リソースが少なくなると強制的に停止する場合がある。
Service.onStartCommandの戻り値を START_STICKY 又は START_REDELIVER_INTENT にすることで、OSが勝手に再起動してくれる。
2) 電源が落とされた場合。
Intent.ACTION_BOOT_COMPLETED ブロードキャストを受けるレシーバを作成しそこからサービスを起動する。
Manifestには
<receiver android:name=".BootUpReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
***** 2012-10-21追記 *****
Android 4.04のスマフォ(XPERIA GXです)でテストしたところ、Intent.ACTION_BOOT_COMPLETED ブロードキャストが受け取れなくなっていた。
Manifestに
<uses-permission
android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
1) Android OSがメモリ等リソースが少なくなると強制的に停止する場合がある。
Service.onStartCommandの戻り値を START_STICKY 又は START_REDELIVER_INTENT にすることで、OSが勝手に再起動してくれる。
2) 電源が落とされた場合。
Intent.ACTION_BOOT_COMPLETED ブロードキャストを受けるレシーバを作成しそこからサービスを起動する。
Manifestには
<receiver android:name=".BootUpReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
等と記述。注意点としてRECEIVE_BOOT_COMPLETEDのパーミッションを取る必要がある。
このブロードキャストを受けるクラスとして
public class BootUpReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
context.startService(new Intent(context, SomeService.class));
}
}
}
等としてサービスを起動しましょう。
***** 2012-10-21追記 *****
Android 4.04のスマフォ(XPERIA GXです)でテストしたところ、Intent.ACTION_BOOT_COMPLETED ブロードキャストが受け取れなくなっていた。
Manifestに
<uses-permission
android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
を追加することで解決した。
3) アプリケーションをアップデートした場合。
Intent.ACTION_PACKAGE_REPLACED ブロードキャストを受けるレシーバを作成しそこからサービスを起動する。
Manifestには
<receiver android:name=".PackageReplacedReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" android:path="your.package.path" />
</intent-filter>
</receiver>
等と記述。自分のものだけ受け他のアプリのものは除くようにandroid:pathを設定すること。
このブロードキャストを受けるクラスとして
public class PackageReplacedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) {
context.startService(new Intent(context, SomeService.class));
}
}
}
等としてサービスを起動しましょう。
***** 2012-1-17追記 *****
どうもandroid:pathを設定しても全てのアプリのアップデートを受けてしまう様子。PackageReplacedReceiverクラスの方で
public class PackageReplacedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) {
if (intent.getDataString().equals("package:your.package.path")) {
context.startService(new Intent(context, SomeService.class));
}
}
}
}
***** 2012-1-17追記 *****
どうもandroid:pathを設定しても全てのアプリのアップデートを受けてしまう様子。PackageReplacedReceiverクラスの方で
public class PackageReplacedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) {
if (intent.getDataString().equals("package:your.package.path")) {
context.startService(new Intent(context, SomeService.class));
}
}
}
}
とIntentのDataをチェックしてからサービスを起動しましょう。
2011年12月25日日曜日
JavaのTimerとTimerTaskの罠
Androidアプリで定期的に行う処理を起動するのに
java.util.Timer
と
java.util.TimerTask
を使用してハマった件のメモ。
スマホの時刻を手動で一時的に先の時刻に変更すると(例えば今8時だったら9時とか)、時刻を元に戻したときTimerがまったく動かなくなる!
どうもTimer、TimerTaskはシステムの時刻を元に次に処理を起動する時刻を決めて、その時刻になったら処理を呼び出すという動作のようだ。そのため一時的に未来の時刻になるとその時刻を元に次に起動する時刻を設定してしまう。時刻を元に戻すとその未来の時刻まではうんともすんとも言わなくなってしまうようだ。
まあActivityのような画面に表示されているときだけ動作するものにはそれでも良いのだが、Serviceのようなバックグラウンドでずっと動くものには要注意である。
そういう場合は
Executors.newSingleThreadScheduledExecutor()
等で
ScheduledExecutorService
を作成しましょう。これなら上記の問題は無いです。
java.util.Timer
と
java.util.TimerTask
を使用してハマった件のメモ。
スマホの時刻を手動で一時的に先の時刻に変更すると(例えば今8時だったら9時とか)、時刻を元に戻したときTimerがまったく動かなくなる!
どうもTimer、TimerTaskはシステムの時刻を元に次に処理を起動する時刻を決めて、その時刻になったら処理を呼び出すという動作のようだ。そのため一時的に未来の時刻になるとその時刻を元に次に起動する時刻を設定してしまう。時刻を元に戻すとその未来の時刻まではうんともすんとも言わなくなってしまうようだ。
まあActivityのような画面に表示されているときだけ動作するものにはそれでも良いのだが、Serviceのようなバックグラウンドでずっと動くものには要注意である。
そういう場合は
Executors.newSingleThreadScheduledExecutor()
等で
ScheduledExecutorService
を作成しましょう。これなら上記の問題は無いです。
2011年12月1日木曜日
2011年7月10日日曜日
Tab ContentのActivityからServiceにbindする場合の注意
Tabで切り替えるActivityからServiceに以下の様にbindしようとすると、bindできない。
bindService(intent, connection, BIND_AUTO_CREATE);
解決法は
getApplicationContext().bindService(intent, connection, BIND_AUTO_CREATE);
とすること。
その場合はunbindも同様に
getApplicationContext().unbindService(connection);
としませう。
bindService(intent, connection, BIND_AUTO_CREATE);
解決法は
getApplicationContext().bindService(intent, connection, BIND_AUTO_CREATE);
とすること。
その場合はunbindも同様に
getApplicationContext().unbindService(connection);
としませう。
登録:
投稿 (Atom)