ご注意!
Google Translate API v1が2011年12月1日にサービスが終了いたします。添付のサンプルソースでは、Google Translate API v1を利用していますので、翻訳が正常に機能しない場合がございます。ご承知おきください。
Android Market公開を目指してAndroidアプリを開発する!(TextToSpeech日本語対応編)の続きです。
今、作っているAndroidアプリのベースとしたAIRアプリ、TranslatAIRには、画面が閉じられていても、OSに常駐して、クリップボードにあるテキストデータを翻訳するという機能があります。
Androidは、マルチタスクをサポートしていてバックグラウンドでの処理が可能なので、同等の機能が実装できそうです。
※ iPhoneもiOS 4から対応されましたので、同等の機能が実装できると思います。
サービスクラスを利用して、翻訳画面が閉じられても、バックグラウンドで常駐プロセスを起動させておくようにします。
常駐アプリが作成できるAndroidの“サービス”とは (2/3) – @ITを参考にして、サービスクラスを継承したクラスの大枠を作ってみました。
package jp.flashcast.translator.android.service;
import jp.flashcast.translator.android.dao.TranslateDao;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class TranslateService extends Service {
private TranslateDao dao;
public class TranslateBinder extends Binder {
public TranslateService getService() {
return TranslateService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return new TranslateBinder();
}
@Override
public void onCreate() {
super.onCreate();
if (dao == null) {
dao = new TranslateDao(this);
}
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onRebind(Intent intent) {
}
@Override
public boolean onUnbind(Intent intent) {
return true; // 再度クライアントから接続された際に onRebind を呼び出させる場合は true を返す
}
}
アクティビティには、以下のようなコードをいくつか追加します。
まず、このサービスを開始する部分です。
Intent intent = new Intent(this, TranslateService.class);
startService(intent);
アクティビティとサービスを、ServiceConnectionクラスを用いてバインドすると、
bindService(intent, connection, Context.BIND_AUTO_CREATE);
binded = true;
アクティビティがサービスに接続したときと切断したときの処理を、コールバック関数のようにすることができます。
connection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder binder) {
service = ((TranslateService.TranslateBinder)binder).getService();
}
public void onServiceDisconnected(ComponentName name) {
service = null;
}
};
また、アクティビティが終了する際に、サービスがバインドされていたら、不要なリソースが残らないようアンバインドするようにします。
@Override
protected void onDestroy() {
super.onDestroy();
if (binded) {
unbindService(connection);
}
}
これらを翻訳画面のアクティビティに追加します。
TranslatAIRの場合には、WindowsのタスクトレイのアイコンやMac OS XのDockアイコンに常駐させて、それらのアイコンをクリックされたときにクリップボードの内容を翻訳するようにしました。
ですが、今回は、同じように常駐させるのが難しいので、クリップボードの内容を翻訳しにいくトリガーをどうするかが問題です。
そこで、考えたのが加速度センサーの利用です。とりあえず、携帯を振って、ある程度の加速度を検知した際に、クリップボードの内容を翻訳するようにしました。
常駐するサービスにSensorEventListenerを実装して、加速度センサーが変化したときのイベントリスナーを登録します。
manager = (SensorManager)getApplicationContext().getSystemService(SENSOR_SERVICE);
List<Sensor> sensors = manager.getSensorList(Sensor.TYPE_ACCELEROMETER);
if (sensors.size() > 0) {
Sensor sensor = sensors.get(0);
registered = manager.registerListener((SensorEventListener)this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}
加速度センサーの値が変化したときのイベントリスナーはonSensorChangedです。
※ onAccuracyChangedは加速度センサーの精度が変更されたときのイベントリスナーなので、今回は何もしていません。
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
if (!binded) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
accelerations[0] = event.values[0] - accelerations[0];
accelerations[1] = event.values[1] - accelerations[1];
accelerations[2] = event.values[2] - accelerations[2];
float acceleration =
Math.abs(accelerations[0]) +
Math.abs(accelerations[1]) +
Math.abs(accelerations[2]);
if (acceleration > 40.0f) {
String clipboard =
((ClipboardManager)(getApplicationContext().getSystemService(CLIPBOARD_SERVICE)))
.getText().toString();
if (!clipboard.equals("")) {
// 翻訳実行
if (model == null) {
}
model = new TranslateModel();
model.setOriginal(clipboard);
model.setSrcLanguage("en");
model.setDstLanguage("ja");
model.setDt(new Date().toLocaleString());
Translate();
}
accelerations[0] = 0.0f;
accelerations[1] = 0.0f;
accelerations[2] = 0.0f;
}
}
}
}
※ 加速度センサーの部分は、センサー(Sensor)を使用するには – 逆引きAndroid入門を参考にさせていただきました。
※ 17行目の値は、何度か試して適当な値を設定したものなので、特に意味はありません。
33行目の翻訳は、今までと同じように、別スレッドで処理します。
private void Translate() {
new TranslateThread(new Handler(), this, model).start();
}
加速度センサーが変化を検知し正常に翻訳が終了すると、翻訳結果が、画面上に浮き上がります。
これで、クリップボードにコピーして、携帯を振ると、サクっと(?)翻訳できるようになりました。他の翻訳系のAndroidアプリにはあまりないと思われる機能なので、このアプリのウリにしていきたいと思います。是非、試してみてください!
サンプルソース
- TranslatorSample10:ダウンロード
