私のプログラムから正しい値を取得する際に問題があります。私は現在、サービスクラスからTimerを開始し、mainActivityクラスからTimerを閉じるためにstartServiceを使用しています。私が使用している例では、クラス内のタイマーを起動し、正常に動作しているようですが、問題はmainActivityクラスから閉じることができません。サービスクラスから呼び出され、EEGヘッドセットに接続されたときのタイマーエラー
PS。自分のプログラムにEPOC + EEGヘッドセットを使用しています。
は、これはここに私の活動のトレーニングクラス
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
public class ActivityTraining extends Activity implements EngineInterface {
EngineConnector engineConnector;
Spinner spinAction;
Button btnTrain, btnClear;
ProgressBar progressBarTime,progressPower;
AdapterSpinner spinAdapter;
ImageView imgBox;
ArrayList<DataSpinner> model = new ArrayList<DataSpinner>();
int indexAction, _currentAction,userId=0,count=0;
Timer timer;
TimerTask timerTask;
float _currentPower = 0;
float startLeft = -1;
float startRight = 0;
float widthScreen = 0;
boolean isTraining =false;
ArrayList<Song> songList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_trainning);
engineConnector = EngineConnector.shareInstance();
engineConnector.delegate = this;
init();
songList = (ArrayList<Song>) getIntent()
.getSerializableExtra(MusicPhoneUtils.SONG_LIST_INTENT);
Log.d("ActivityTraining", "GOT SONG COUNT = " + songList.size());
}
public void init() {
spinAction=(Spinner)findViewById(R.id.spinnerAction);
btnTrain=(Button)findViewById(R.id.btstartTraing);
btnClear=(Button)findViewById(R.id.btClearData);
btnClear.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
switch (indexAction){
case 0:
engineConnector.trainningClear(IEmoStateDLL.IEE_MentalCommandAction_t.MC_NEUTRAL.ToInt());
break;
case 1:
engineConnector.trainningClear(IEmoStateDLL.IEE_MentalCommandAction_t.MC_PUSH.ToInt());
break;
case 2:
engineConnector.trainningClear(IEmoStateDLL.IEE_MentalCommandAction_t.MC_PULL.ToInt());
break;
case 3:
engineConnector.trainningClear(IEmoStateDLL.IEE_MentalCommandAction_t.MC_LEFT.ToInt());
break;
case 4:
engineConnector.trainningClear(IEmoStateDLL.IEE_MentalCommandAction_t.MC_RIGHT.ToInt());
break;
default:
break;
}
}
});
progressBarTime=(ProgressBar)findViewById(R.id.progressBarTime);
progressBarTime.setVisibility(View.INVISIBLE);
progressPower=(ProgressBar)findViewById(R.id.ProgressBarpower);
imgBox = (ImageView)findViewById(R.id.imgBox);
setDataSpinner();
spinAction.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
indexAction = arg2;
}
public void onNothingSelected(AdapterView<?> arg0) {
//TODO Auto-genereted method stub
}
});
ですし、私は
Intent strtService = new Intent().setClass(getApplicationContext(), StartEndEpocService.class);
startService(strtService);
を開始するには、サービスクラスを呼び出していますので、ここでオリジナルのタイマーが
Timer timeListenAction = new Timer();
timeListenAction.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
handlerUpdateUI.sendEmptyMessage(1);
}
}, 0, 20);
}
に位置していましたさ
接続されたメソッドがServiceクラスから呼び出され、値がハンドルに渡されますrUpdateUI
public void connect() {
handlerUpdateUI.sendEmptyMessage(1);
}
Handler handlerUpdateUI = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what){
case 0:
count++;
int trainninTime = (int)MentalCommandDetection.IEE_MentalCommandGetTrainingTime(userId)[1]/1000;
if(trainninTime>0){
progressBarTime.setProgress(count/trainninTime);
}
if (progressBarTime.getProgress()>=100){
timerTask.cancel();
timer.cancel();
}
break;
case 1:
changePages();
default:
break;
}
};
};
public void startTrainingMentalcommand(IEmoStateDLL.IEE_MentalCommandAction_t MentalCommandAction) {
isTraining = engineConnector.startTrainingMetalcommand(isTraining, MentalCommandAction);
btnTrain.setText((isTraining) ? "Abort Trainning" : "Train");
}
public void setDataSpinner(){
model.clear();
DataSpinner data = new DataSpinner();
data.setTvName("Neutral");
data.setChecked(engineConnector.checkTrained(IEmoStateDLL.IEE_MentalCommandAction_t.MC_NEUTRAL.ToInt()));
model.add(data);
data = new DataSpinner();
data.setTvName("Push");
data.setChecked(engineConnector.checkTrained(IEmoStateDLL.IEE_MentalCommandAction_t.MC_PUSH.ToInt()));
model.add(data);
data = new DataSpinner();
data.setTvName("Pull");
data.setChecked(engineConnector.checkTrained(IEmoStateDLL.IEE_MentalCommandAction_t.MC_PULL.ToInt()));
model.add(data);
data=new DataSpinner();
data.setTvName("Left");
data.setChecked(engineConnector.checkTrained(IEmoStateDLL.IEE_MentalCommandAction_t.MC_LEFT.ToInt()));
model.add(data);
data=new DataSpinner();
data.setTvName("Right");
data.setChecked(engineConnector.checkTrained(IEmoStateDLL.IEE_MentalCommandAction_t.MC_RIGHT.ToInt()));
model.add(data);
spinAdapter = new AdapterSpinner(this, R.layout.row, model);
spinAdapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
spinAction.setAdapter(spinAdapter);
}
@Override
public boolean onCreateOptionMenu(Menu menu){
getMenuInflater().inflate(R.menu.activity_trainning, menu);
return true;
}
public void TimerTask(){
count = 0;
timerTask = new TimerTask() {
@Override
public void run() {
handlerUpdateUI.sendEmptyMessage(0);
}
};
}
private void changePages() {
//currentAction(_currentAction, _currentPower);
float power = _currentPower;
Log.e("ActivityTraining", "current_action: " + _currentAction);
Log.e("ActivityTraining", "power: " + power);
if ((_currentAction == IEmoStateDLL.IEE_MentalCommandAction_t.MC_PUSH.ToInt() && power > 0)) {
Log.e("ActivityTraining", "current_action: " + _currentAction);
Log.e("ActivityTraining", "power: " + power);
Intent MC_RIGHT = new Intent().setClass(getApplicationContext(), FragmentBondActivity.class);
MC_RIGHT.putExtra(MusicPhoneUtils.SONG_LIST_INTENT, songList);
MC_RIGHT.putExtra(MusicPhoneUtils.START_AUTO_PLAY_INTENT, false);
MC_RIGHT.putExtra(MusicPhoneUtils.LAST_SONG_USER_PLAYED_INTENT,
getIntent().getSerializableExtra(MusicPhoneUtils.LAST_SONG_USER_PLAYED_INTENT));
MC_RIGHT.putExtra("target", "play");
startActivity(MC_RIGHT);
}
if (((_currentAction == IEmoStateDLL.IEE_MentalCommandAction_t.MC_LEFT.ToInt())) && power > 0) {
Log.e("ActivityTraining", "current_action: " + _currentAction);
Log.e("ActivityTraining", "power: " + power);
Intent MC_LEFT = new Intent().setClass(getApplicationContext(),FragmentBondActivity.class);
MC_LEFT.putExtra(MusicPhoneUtils.SONG_LIST_INTENT, songList);
MC_LEFT.putExtra("target", "songList");
startActivity(MC_LEFT);
}
if(((_currentAction == IEmoStateDLL.IEE_MentalCommandAction_t.MC_RIGHT.ToInt())) && power > 0) {
Log.e("ActivityTraining", "current_action: " + _currentAction);
Log.e("ActivityTraining", "power: " + power);
Intent MC_RIGHT = new Intent().setClass(getApplicationContext(), SettingsActivity.class);
startActivity(MC_RIGHT);
}
if(((_currentAction == IEmoStateDLL.IEE_MentalCommandAction_t.MC_PULL.ToInt())) && power > 0) {
Log.e("ActivityTraining", "current_action: " + _currentAction);
Log.e("ActivityTraining", "power: " + power);
Intent MC_PULL = new Intent().setClass(getApplicationContext(), MainActivity.class);
MC_PULL.putExtra(MusicPhoneUtils.SONG_LIST_INTENT, songList);
MC_PULL.putExtra("target", "songList");
startActivity(MC_PULL);
}
}
public void enableClick() {
btnClear.setClickable(true);
spinAction.setClickable(true);
}
@Override
public void userAdd(int userId) {
// TODO Auto-generated method stub
this.userId=userId;
}
@Override
public void userRemoved() {
// TODO Auto-generated method stub
}
@Override
public void trainStarted() {
// TODO Auto-generated method stub
progressBarTime.setVisibility(View.VISIBLE);
btnClear.setClickable(false);
spinAction.setClickable(false);
timer = new Timer();
TimerTask();
timer.schedule(timerTask , 0, 10);
}
@Override
public void trainSucceed() {
// TODO Auto-generated method stub
progressBarTime.setVisibility(View.VISIBLE);
btnTrain.setText("Train");
enableClick();
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
ActivityTraining.this);
// set title
alertDialogBuilder.setTitle("Training Succeeded");
// set dialog message
alertDialogBuilder
.setMessage("Training is successful. Accept this training?")
.setCancelable(false)
.setIcon(R.drawable.ic_launcher)
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,int which) {
engineConnector.setTrainControl(MentalCommandDetection.IEE_MentalCommandTrainingControl_t.MC_ACCEPT.getType());
}
})
.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
engineConnector.setTrainControl(MentalCommandDetection.IEE_MentalCommandTrainingControl_t.MC_REJECT.getType());
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
@Override
public void trainFailed(){
progressBarTime.setVisibility(View.INVISIBLE);
btnTrain.setText("Train");
enableClick();
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
ActivityTraining.this);
// set title
alertDialogBuilder.setTitle("Training Failed");
// set dialog message
alertDialogBuilder
.setMessage("Signal is noisy. Can't training")
.setCancelable(false)
.setIcon(R.drawable.ic_launcher)
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog, int which) {
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
isTraining = false;
}
@Override
public void trainCompleted() {
// TODO Auto-generated method stub
DataSpinner data=model.get(indexAction);
data.setChecked(true);
model.set(indexAction, data);
spinAdapter.notifyDataSetChanged();
isTraining = false;
}
@Override
public void trainRejected() {
// TODO Auto-generated method stub
DataSpinner data=model.get(indexAction);
data.setChecked(false);
model.set(indexAction, data);
spinAdapter.notifyDataSetChanged();
enableClick();
isTraining = false;
}
@Override
public void trainErased() {
// TODO Auto-generated method stub
new AlertDialog.Builder(this)
.setTitle("Training Erased")
.setMessage("")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
DataSpinner data=model.get(indexAction);
data.setChecked(false);
model.set(indexAction, data);
spinAdapter.notifyDataSetChanged();
enableClick();
isTraining = false;
}
@Override
public void trainReset() {
// TODO Auto-generated method stub
if(timer!=null){
timer.cancel();
timerTask.cancel();
}
isTraining = false;
progressBarTime.setVisibility(View.VISIBLE);
progressBarTime.setProgress(0);
enableClick();
};
ここで問題が始まりました。私がサービスクラスからタイマーを呼び出すと、_currentActionと_currentPowerの値はクラスに更新されません。 次のようにEEGヘッドセットが接続された後に正常値にすべきである: _currentAction = 1 _currentPower = 0.0 また、それはクラスの値を更新しないと、それは_currentAction = 0と_currentPowerの値を返す維持= 0.0 もののこれは、変数がクラスの先頭で宣言された値なので正常です。
ActivityTrainingクラス内でTimerを使用しているとき、値は正常に更新されます。
@Override
public void currentAction(int typeAction, float power) {
// TODO Auto-generated method stub
progressPower.setProgress((int)(power*100));
_currentAction = typeAction;
_currentPower = power;
}
public void TrainingHomePage(View v) {
Intent goingB = new Intent(this, MainActivity.class);
setResult(RESULT_OK, goingB);
finish();
}
}
これは私のサービスクラス
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
import com.example.assiotiscy.headshake.MentalCommand.ActivityTraining;
import java.util.Timer;
import java.util.TimerTask;
public class StartEndEpocService extends Service {
ActivityTraining activityTraining = new ActivityTraining();
Timer timeListenAction;
@Override
public void onCreate() {
super.onCreate();
//Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
thread();
}
private void thread() {
timeListenAction =new Timer();
timeListenAction.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
activityTraining.connect();
}
},0,20);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started...", Toast.LENGTH_SHORT).show();
return START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
@Override
public void onDestroy() {
Toast.makeText(this, "Service Stopped...", Toast.LENGTH_SHORT).show();
if (timeListenAction != null){
timeListenAction.cancel();
timeListenAction.purge();
}
}
}
/最後に、これは私のEngineConnectorクラスです。ここで/
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import com.emotiv.insight.IEdk;
import com.emotiv.insight.IEdkErrorCode;
import com.emotiv.insight.IEmoStateDLL;
import com.emotiv.insight.IEmoStateDLL.IEE_MentalCommandAction_t;
import com.emotiv.insight.MentalCommandDetection;
import com.emotiv.insight.MentalCommandDetection.IEE_MentalCommandTrainingControl_t;
import java.util.Timer;
import java.util.TimerTask;
public class EngineConnector {
public static Context context;
public static EngineConnector engineConnectInstance = null;
private Timer timer;
private TimerTask timerTask;
public boolean isConnected = false;
private int state;
private int userId = -1;
private boolean firstActionAdded = false;
public EngineInterface delegate;
public static void setContext(Context context) {
EngineConnector.context = context;
}
public static EngineConnector shareInstance() {
if (engineConnectInstance == null) {
engineConnectInstance = new EngineConnector() {
};
}
return engineConnectInstance;
}
public EngineConnector() {
connectEngine();
}
private void connectEngine() {
IEdk.IEE_EngineConnect(EngineConnector.context, "");
timer = new Timer();
timerTask();
timer.schedule(timerTask, 0, 10);
}
EEG起こるの接続です。また、私はこのクラスからいくつかのコードを削除する必要はありません。 Handler_ACTION_CURRENTで
public void timerTask() {
if (timerTask != null)
return;
timerTask = new TimerTask() {
@Override
public void run() {
/*Connect device with Epoc Plus headset*/
int numberDevice = IEdk.IEE_GetEpocPlusDeviceCount();
//Log.d("EngineConnector: ", "numberDevice: " + numberDevice);
if (numberDevice != 0) {
if (!isConnected)
IEdk.IEE_ConnectEpocPlusDevice(0, false);
}
/*************************************/
state = IEdk.IEE_EngineGetNextEvent();
// Log.d("EngineConnector:- ", "State: " + state);
if (state == IEdkErrorCode.EDK_OK.ToInt()) {
int eventType = IEdk.IEE_EmoEngineEventGetType();
//Log.d("EngineConnector", "eventType: " +eventType);
switch (eventType) {
case TYPE_USER_ADD:
Log.e("connect", "User Added");
isConnected = true;
// TURNING OFF HEADSET WILL RESET ALL ACTIONS EVEN IF IN APP THAT ACTION STILL HAS "V" BESIDE
// userId is re-set by IEE_EmoEngineEventGetUserId();
userId = IEdk.IEE_EmoEngineEventGetUserId();
Log.e("UserID ", "" + userId);
hander.sendEmptyMessage(HANDLER_USER_ADD);
// This is the issue: by default activated action is Push (set by library so there is nothing we could do in our side
// We're going to get around this issue by replace Push with first action that user would choose in enableMentalcommandActions() method
long[] activeAction = MentalCommandDetection.IEE_MentalCommandGetActiveActions(userId);
Log.e("Default Action list: ", "0x" + Long.toBinaryString(activeAction[1]));
break;
case TYPE_USER_REMOVE:
Log.e("disconnect", "User Removed");
isConnected = false;
userId = -1;
hander.sendEmptyMessage(HANDLER_USER_REMOVE);
break;
case TYPE_EMOSTATE_UPDATE:
if (!isConnected)
break;
IEdk.IEE_EmoEngineEventGetEmoState();
hander.sendMessage(hander
.obtainMessage(HANDLER_ACTION_CURRENT));
break;
case TYPE_METACOMMAND_EVENT:
int type = MentalCommandDetection.IEE_MentalCommandEventGetType();
if (type == MentalCommandDetection.IEE_MentalCommandEvent_t.IEE_MentalCommandTrainingStarted
.getType()) {
Log.e("MentalCommand", "training started");
hander.sendEmptyMessage(HANDLER_TRAIN_STARTED);
} else if (type == MentalCommandDetection.IEE_MentalCommandEvent_t.IEE_MentalCommandTrainingSucceeded
.getType()) {
Log.e("MentalCommand", "training Succeeded");
hander.sendEmptyMessage(HANDLER_TRAIN_SUCCEED);
} else if (type == MentalCommandDetection.IEE_MentalCommandEvent_t.IEE_MentalCommandTrainingCompleted
.getType()) {
Log.e("MentalCommand", "training Completed");
hander.sendEmptyMessage(HANDLER_TRAIN_COMPLETED);
} else if (type == MentalCommandDetection.IEE_MentalCommandEvent_t.IEE_MentalCommandTrainingDataErased
.getType()) {
Log.e("MentalCommand", "training erased");
hander.sendEmptyMessage(HANDLER_TRAIN_ERASED);
} else if (type == MentalCommandDetection.IEE_MentalCommandEvent_t.IEE_MentalCommandTrainingFailed
.getType()) {
Log.e("MentalCommand", "training failed");
hander.sendEmptyMessage(HANDLER_TRAIN_FAILED);
} else if (type == MentalCommandDetection.IEE_MentalCommandEvent_t.IEE_MentalCommandTrainingRejected
.getType()) {
Log.e("MentalCommand", "training rejected");
hander.sendEmptyMessage(HANDLER_TRAIN_REJECTED);
} else if (type == MentalCommandDetection.IEE_MentalCommandEvent_t.IEE_MentalCommandTrainingReset
.getType()) {
Log.e("MentalCommand", "training Reset");
hander.sendEmptyMessage(HANDLER_TRAINED_RESET);
}
break;
default:
break;
}
}
}
};
}
Handler hander = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case HANDLER_USER_ADD:
if (delegate != null)
delegate.userAdd(userId);
break;
case HANDLER_USER_REMOVE:
if (delegate != null)
delegate.userRemoved();
break;
は:currentActionメソッドは、アクティビティトレーニングクラスIは、サービスクラスからタイマーを起動する問題が何であるか知っていただきたいと思い
case HANDLER_ACTION_CURRENT:
if (delegate != null)
delegate.currentAction(IEmoStateDLL
.IS_MentalCommandGetCurrentAction(), IEmoStateDLL
.IS_MentalCommandGetCurrentActionPower());
break;
case HANDLER_TRAIN_STARTED:
if (delegate != null)
delegate.trainStarted();
break;
case HANDLER_TRAIN_SUCCEED:
if (delegate != null)
delegate.trainSucceed();
break;
case HANDLER_TRAIN_FAILED:
if (delegate != null)
delegate.trainFailed();
break;
case HANDLER_TRAIN_COMPLETED:
if (delegate != null)
delegate.trainCompleted();
break;
case HANDLER_TRAIN_ERASED:
if (delegate != null)
delegate.trainErased();
break;
case HANDLER_TRAIN_REJECTED:
if (delegate != null)
delegate.trainRejected();
break;
case HANDLER_TRAINED_RESET:
if (delegate != null)
delegate.trainReset();
break;
default:
break;
}
}
};
}
から言及しましたさ。
は、私はその後、私の質問への問題は、私のActivityTrainningクラスは既に活動だったと私はサービスクラスにそれを別のオブジェクトを作成していた(ActivityTrainning activityTrainning =新しいActivityTrainning())ということであった事前