Java 从服务类调用并连接到EEG耳机时出现计时器错误

Java 从服务类调用并连接到EEG耳机时出现计时器错误,java,android,timer,timertask,Java,Android,Timer,Timertask,我在从程序中检索正确的值时遇到问题。我目前正在使用startService,以便从服务类启动计时器,并能够从mainActivity类关闭计时器。我正在使用的示例激活了类中的计时器,并且似乎工作得很好,但问题是我无法从mainActivity类关闭它 另外,我正在使用EPOC+EEG耳机进行我的程序 这是我的活动训练班 import java.util.ArrayList; import java.util.Timer; import java.util.TimerTask; public c

我在从程序中检索正确的值时遇到问题。我目前正在使用startService,以便从服务类启动计时器,并能够从mainActivity类关闭计时器。我正在使用的示例激活了类中的计时器,并且似乎工作得很好,但问题是我无法从mainActivity类关闭它

另外,我正在使用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
        }
    });
这是原始计时器的位置

    Timer timeListenAction = new Timer();
    timeListenAction.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            handlerUpdateUI.sendEmptyMessage(1);
        }
    }, 0, 20);

}
正在从服务类调用connected方法,以将值传递给handlerUpdateUI

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 _电流功率=0.0 此外,它不会更新类中的值,并不断返回_currentAction=0和_currentPower=0.0的值 虽然这是正常的,因为这些是变量在类的开头声明的值

当我在ActivityTraining类中使用计时器时,值会得到很好的更新

@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类/

这是脑电图发生的连接。我还删除了这个类中一些不需要看的代码

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;
在Handler\u ACTION\u CURRENT:中,是活动培训类中引用的currentAction方法

            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;
        }
    }
};
}
我想知道从服务类激活计时器可能有什么问题


提前感谢

我的问题是,由于我的ActivityTraining类已经是一个activity,并且我正在将它的另一个对象创建到服务类中(ActivityTraining ActivityTraining=new ActivityTraining()),所以我有两个不同的ActivityTraining类对象

一个简单/好的解决方案如下:

活动A应该有一个变量

static ActivityA activityA;
在onCreate状态下:

activityA = this;
并添加此方法:

public static ActivityA getInstance(){
    return   activityA;
}
在活动B中,调用:

ActivityA.getInstance().myFunction(); //call myFunction using activityA

我的问题是,由于我的ActivityTraining类已经是一个activity,并且我正在将它的另一个对象创建到服务类中(ActivityTraining ActivityTraining=new ActivityTraining()),因此我有两个不同的ActivityTraining类对象

一个简单/好的解决方案如下:

活动A应该有一个变量

static ActivityA activityA;
在onCreate状态下:

activityA = this;
并添加此方法:

public static ActivityA getInstance(){
    return   activityA;
}
在活动B中,调用:

ActivityA.getInstance().myFunction(); //call myFunction using activityA