Google Play服务活动识别会不断启动和停止

时间:2013-10-29 22:23:49

标签: android google-play-services activity-recognition

我需要通过服务(非活动)调用Google活动识别服务并在后台运行它,当然当用户启动应用程序时,该应用程序有活动(但服务不直接从活动调用)

因此我创建了一个服务类(ActivitySensor)和另一个类(ActivityRecognitionScan)。 当我在Galaxy Nexus S设备上安装应用程序时,该服务会自动开始调用onCreate和onDestroy。即使没有在GUI中做任何事情 这是非常奇怪的行为。有没有人有相同的经验或解决方案?

我的意思是我在调试控制台中得到如下内容: 活动记录--- onCreate 活动记录--- onDestroy 活动记录--- onCreate 活动记录--- onDestroy 活动记录--- onCreate 活动记录--- onDestroy ...

以下是我的两个课程:

    public class ActivitySensor extends IntentService {

        private ActivityRecognitionScan myascan;
        private Intent inIntent;
        private static long ACTIVITY_LOG_INTERVAL = 30000L;
        private static JsonEncodeDecode jsonencoder = new JsonEncodeDecode(); 
        public ActivitySensor() {
            super("ActivitySensor");
        }   

        @Override
        public void onCreate(){
            super.onCreate();
            Log.d("Activity-Logging", "--- onCreate");
            try {
                myascan = new ActivityRecognitionScan(getApplicationContext());
                myascan.startActivityRecognitionScan();
            } catch (Exception e) {
                Log.e("[Activity-Logging]","----------Error:"+e.getLocalizedMessage());
                e.printStackTrace();
            }   
        }

        @Override
        public void readSensor() {   
    //      Log.e("Activity-Logging", "ActivityRecognitionResult.hasResult: "+String.valueOf(ActivityRecognitionResult.hasResult(inIntent)));
            if (ActivityRecognitionResult.hasResult(inIntent)) {
                ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(inIntent);
                DetectedActivity activity = result.getMostProbableActivity();
                final int type = activity.getType();
                String strType = new String();
                switch(type){
                  case DetectedActivity.IN_VEHICLE:
                      strType = "invehicle";
                      break;
                  case DetectedActivity.ON_BICYCLE:
                      strType ="onbicycle";
                      break;
                  case DetectedActivity.ON_FOOT:
                      strType = "onfoot";
                      break;
                  case DetectedActivity.STILL:
                      strType = "still";
                      break;
                  case DetectedActivity.TILTING:
                      strType ="tilting";
                      break;
                  case DetectedActivity.UNKNOWN:
                      strType ="unknown";
                      break;
                }
                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
                Editor edt = prefs.edit();
                String previousActv = prefs.getString("PREVIOUS_ACTIVIY","");
                long previousDate = prefs.getLong("PREVIOUS_DATE", 0);
                if (previousActv.length()==0){ // nothing was in the string and it is the first time just initialize
                    previousActv = strType;
                    previousDate = new Date().getTime();
    //              Log.e("-----FIRST TIME: type:", previousActv+" date:"+String.valueOf(previousDate));
                    edt.putString("PREVIOUS_ACTIVIY", strType);
                    edt.putLong("PREVIOUS_DATE", previousDate);
                    edt.commit();
                }else {
                    if (!strType.equalsIgnoreCase(previousActv)){
                        Date readablePrevDate = new Date(previousDate);
                        Date nowDate = new Date();
                        String jsonstr = jsonencoder.EncodeActivity("Activity", readablePrevDate, nowDate, strType, activity.getConfidence());
    //                  Log.e("[Activity-Logging] ----->",jsonstr);
                        edt.putString("PREVIOUS_ACTIVIY", strType);
                        edt.putLong("PREVIOUS_DATE", nowDate.getTime());
                        edt.commit();
                        DataAcquisitor.dataBuff.add(jsonstr);
                    }
                }
            }
        }

        @Override
        protected void onHandleIntent(Intent intent) {
            Log.d("Activity-Logging", "--- onHandleIntent"+ "---"+intent.getAction());
            intent.putExtra("LOG_INTERVAL",ACTIVITY_LOG_INTERVAL );
            intent.putExtra("STOP",false);
            inIntent = intent;
            readSensor();
        }   

        @Override
        public void onDestroy(){
            Log.d("Activity-Logging", "--- onDestroy");
            myascan.stopActivityRecognitionScan();
            myascan=null;
            //super.onDestroy();
        }
}

这是调用Google活动识别服务的类:

ActivityRecognitionScan implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener {

    private Context ctx;
    private static final String TAG = "ActivityRecognition";
    private static ActivityRecognitionClient actrecClient;
    private static PendingIntent callbackIntent;
    private long ACTIVITY_LOG_INTERVAL=30000;
    public ActivityRecognitionScan(Context context) {
        ctx=context;
    }

    public void startActivityRecognitionScan(){
        int resp = GooglePlayServicesUtil.isGooglePlayServicesAvailable(ctx);
        if(resp == ConnectionResult.SUCCESS){
            actrecClient = new ActivityRecognitionClient(ctx, this, this);
            if (!actrecClient.isConnected()){
                actrecClient.connect();
            } else{
                Log.e("ActivityRecognitionScan"," ---Activity recognition client is already connected");
            }
        }else{
                Log.e("[Activity-Logging]", "Google Play Service hasn't installed");
        }

    }

    public void stopActivityRecognitionScan(){
        try{
            if (actrecClient.isConnected() || actrecClient.isConnecting() ){
                actrecClient.removeActivityUpdates(callbackIntent);
                actrecClient.disconnect();
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        Log.e("[ActivityRecognitionScan]", "Connection Failed");
    }

    @Override
    public void onConnected(Bundle connectionHint) {
        try{
            Intent intent = new Intent(ctx, ActivitySensor.class); 
            Bundle bundle = intent.getExtras(); 
            callbackIntent = PendingIntent.getService(ctx, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            long interval = 5000;
            if ( null!= bundle && bundle.containsKey("LOG_INTERVAL") ){
                interval = bundle.getLong("LOG_INTERVAL");
            }
            actrecClient.requestActivityUpdates(interval, callbackIntent);  
            actrecClient.disconnect();
        }catch(Exception ex){
            Log.e("[Activity-Logging]","Error in requesting Activity update "+ex.getMessage());
            ex.printStackTrace();
        }
    }

    @Override
    public void onDisconnected() {
        callbackIntent.cancel();
        actrecClient = null;
        Log.e("[ActivityRecognitionScan]","---onDisconnected");
    }
}

2 个答案:

答案 0 :(得分:2)

IntentService根据the source code完成onHandleIntent后会自动停止(ServiceHandler.handleMessage()the description of an IntentService

  

客户端通过startService(Intent)调用发送请求;服务根据需要启动,使用工作线程依次处理每个Intent,并在工作失败时自行停止。

如果您希望它在后台连续运行,请使用Service

答案 1 :(得分:0)

您的代码存在2个问题,导致您遇到问题。

  1. 当检测到活动时,被调用的挂起意图调用(并创建,因为它是一个IntentService)ActivitySensor。 onCreate将连接另一个ActivityRecognitionClient,这是不必要的。这会导致检测到另一个活动,导致您的日志记录循环。
  2. 您应该将ActivityRecognitionClient的创建与检测到的活动的处理分开。您无需继续重新创建它,因为后续检测将使用相同的PendingIntent。这将阻止日志记录循环。