Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/233.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 从正在运行的服务收集加速计数据_Android_Service_Background_Accelerometer_Transfer - Fatal编程技术网

Android 从正在运行的服务收集加速计数据

Android 从正在运行的服务收集加速计数据,android,service,background,accelerometer,transfer,Android,Service,Background,Accelerometer,Transfer,这就是我要做的。我有一项活动需要处理一些加速计数据。因此,我创建了一个扩展“服务”并实现“SensorEventListener”的服务 以下是我的活动代码: import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.graphics.Col

这就是我要做的。我有一项活动需要处理一些加速计数据。因此,我创建了一个扩展“服务”并实现“SensorEventListener”的服务

以下是我的活动代码:

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Color;
import android.os.IBinder;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.LineGraphSeries;


public class GraphActivity1 extends ActionBarActivity {
    private GraphView graph1;
    private GraphView graph2;

    private DataPoint[] xdata = new DataPoint[64];
    private DataPoint[] ydata = new DataPoint[64];
    private DataPoint[] zdata = new DataPoint[64];

    private DataPoint[] fxdata = new DataPoint[64];
    private DataPoint[] fydata = new DataPoint[64];
    private DataPoint[] fzdata = new DataPoint[64];

    private Complex[] xcdata = new Complex[64];
    private Complex[] ycdata = new Complex[64];
    private Complex[] zcdata = new Complex[64];

    private Complex[] xfdata = new Complex[64];
    private Complex[] yfdata = new Complex[64];
    private Complex[] zfdata = new Complex[64];

    private final int FFT_SIZE = 64;
    private boolean RUN_FLAG = true;
    private char run_times = 10;

    BoundService myService;
    boolean isBound = false;

    private ServiceConnection myConnection = new ServiceConnection() {

        public void onServiceConnected(ComponentName className,
                                       IBinder service) {
            BoundService.MyLocalBinder binder = (BoundService.MyLocalBinder) service;
            myService = binder.getService();
            isBound = true;
        }

        public void onServiceDisconnected(ComponentName arg0) {
            isBound = false;
        }

    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_graph_activity1);

        Log.i("New Tag", "Graph Activity Created");

        graph1 = (GraphView)findViewById(R.id.timegraph);
        graph2 = (GraphView)findViewById(R.id.frequencygraph);

        Intent intent = new Intent(this, BoundService.class);
        startService(intent);
        Log.i("New Tag", "Service Started");
        bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
        while (!isBound){
               Log.i("New Tag", "Service Binding in Progress");
        }
        Log.i("New Tag", "Service Bound");

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_graph_activity1, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onStart(){
        Log.i("New Tag", "Graph Activity Started");
        while(RUN_FLAG){
            Log.i("New Tag", "Entered While Loop");
            int i_state = myService.getStatus();
            //Log.i("New Tag", "State is"+i_state);
            if (i_state == 1){
                Log.i("New Tag", "Entered Second While Loop");
                Complex[][] alldata = myService.getData();
                xcdata = alldata[0];
                ycdata = alldata[1];
                zcdata = alldata[2];

                for (int i = 0; i < FFT_SIZE; i++){
                    xdata[i] = new DataPoint(i, xcdata[i].re());
                    ydata[i] = new DataPoint(i, ycdata[i].re());
                    zdata[i] = new DataPoint(i, zcdata[i].re());
                }

                xfdata = FFT.fft(xcdata);
                yfdata = FFT.fft(ycdata);
                zfdata = FFT.fft(zcdata);

                for (int i = 0; i < FFT_SIZE; i++){
                    fxdata[i] = new DataPoint(i, xfdata[i].abs());
                    fydata[i] = new DataPoint(i, yfdata[i].abs());
                    fzdata[i] = new DataPoint(i, zfdata[i].abs());
                }

                LineGraphSeries<DataPoint> series1t = new LineGraphSeries<DataPoint>(xdata);
                LineGraphSeries<DataPoint> series2t = new LineGraphSeries<DataPoint>(ydata);
                LineGraphSeries<DataPoint> series3t = new LineGraphSeries<DataPoint>(zdata);

                LineGraphSeries<DataPoint> series1f = new LineGraphSeries<DataPoint>(fxdata);
                LineGraphSeries<DataPoint> series2f = new LineGraphSeries<DataPoint>(fydata);
                LineGraphSeries<DataPoint> series3f = new LineGraphSeries<DataPoint>(fzdata);

                series1t.setColor(Color.RED);
                series2t.setColor(Color.GREEN);
                series3t.setColor(Color.BLUE);
                graph1.addSeries(series1t);
                graph1.addSeries(series2t);
                graph1.addSeries(series3t);
                graph1.setTitle("Time Domain Data [x(red), y(green), z(blue)]");

                series1f.setColor(Color.RED);
                series2f.setColor(Color.GREEN);
                series3f.setColor(Color.BLUE);
                graph2.addSeries(series1f);
                graph2.addSeries(series2f);
                graph2.addSeries(series3f);
                graph2.setTitle("Frequency Domain Data [x(red), y(green), z(blue)]");

                graph1.removeAllSeries();
                graph2.removeAllSeries();
            }
            run_times --;
            if (run_times == 0)
            {
                RUN_FLAG = false;
            }

        }
    }
}
非常感谢您事先的帮助

诚恳地

解释说,调用
bindService()
会立即返回,但实际绑定是异步进行的。在您的活动收到
onServiceConnected()
回调之前,该服务不可用。您的活动在
onCreate()
中调用
bindService()
。然后在
onStart()
中调用
myService.getStatus()
。这是在绑定完成并且调用了
onServiceConnected()
之前发生的,因此
myService
为null,您会得到异常

您需要重新构造代码,以便在服务绑定完成之前不会启动图形创建处理


还需要另一种改变。您不能在
onStart()
中将图形处理置于无休止的while循环中。无法在主线程上执行长时间运行的处理。它将干扰其他UI处理,并在几秒钟后导致“应用程序无响应”故障。

程序崩溃时会发生什么异常?如果它不是直接出现在你的代码中,你可能不得不用logcat过滤器来查看它。我刚刚用完整的logcat编辑了这篇文章。好的,所以我根据你的建议修改了代码,除了线程部分。我添加了while循环来检查服务是否绑定。当我运行代码时,它一直给我一个标签,表明服务绑定仍在进行中,直到应用程序冻结。绑定一个服务需要多长时间?绑定通常在不到一秒钟的时间内完成。那么,在我的情况下,为什么要花很长时间呢。我在其他地方读到,除非onCreate和onStart首先完成运行,否则服务将在ServiceConnected上运行。这是真的吗?我在回答中链接的这个指南描述了如何创建绑定服务。确保您的服务在清单文件中有一个条目。
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import com.jjoe64.graphview.series.DataPoint;

public class BoundService extends Service implements SensorEventListener {

    private SensorManager senSensorManager;
    private Sensor senAccelerometer;
    private long lastUpdate = 0;
    private int data_index = 0;
    private static final int FFT_SIZE = 64;

    private Complex[] xdata;
    private Complex[] ydata;
    private Complex[] zdata;
    private Complex[][] alldata;

    private final IBinder myBinder = new MyLocalBinder();
    private int data_ready = 0;

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return myBinder;
    }

    public int onStartCommand (Intent intent, int flags, int startId){
        Log.i("New Tag","Service Called");

        senSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        senAccelerometer = senSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        senSensorManager.registerListener(this, senAccelerometer , SensorManager.SENSOR_DELAY_NORMAL);

        return START_STICKY;
    }

    public Complex[][] getData() {
        if (data_ready == 0){
            Log.i("New Tag","getStatus Called, Data not ready");
            return null;
        }else {
            Log.i("New Tag","getStatus Called, Data is ready");
            alldata[0] = xdata;
            alldata[1] = ydata;
            alldata[2] = zdata;
            data_ready = 0;
            data_index = 0;
            return alldata;
        }
    }

    public class MyLocalBinder extends Binder {
        BoundService getService() {
            return BoundService.this;
        }
    }

    public int getStatus(){
        Log.i("New Tag","getStatus Called");
        return data_ready;
    }

    public void onSensorChanged(SensorEvent sensorEvent) {

        long nowTime = System.currentTimeMillis();

        if ((nowTime - lastUpdate) > 100){
            lastUpdate = nowTime;

            Sensor mySensor = sensorEvent.sensor;

            if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) {

                float x = sensorEvent.values[0];
                float y = sensorEvent.values[1];
                float z = sensorEvent.values[2];

                if (data_index < FFT_SIZE) {

                    xdata[data_index] = new Complex(x);
                    ydata[data_index] = new Complex(y);
                    zdata[data_index] = new Complex(z);
                    data_index++;
                    Log.i("New Tag","Data not Ready");
                }
                else if (data_index == FFT_SIZE)
                {
                    data_ready = 1;
                    Log.i("New Tag","Data is Ready");
                    Toast.makeText(getApplicationContext(), "Data Reading Complete", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

}
    06-28 15:16:14.632  28418-28441/adameve.relsa D/OpenGLRenderer﹕ endAllStagingAnimators on 0xb49b8b00 (RippleDrawable) with handle 0xaec2cfe0
06-28 15:16:20.921  28418-28418/adameve.relsa I/New Tag﹕ Graph Activity Created
06-28 15:16:20.929  28418-28418/adameve.relsa I/New Tag﹕ Service Bound
06-28 15:16:20.929  28418-28418/adameve.relsa I/New Tag﹕ Graph Activity Started
06-28 15:16:20.929  28418-28418/adameve.relsa I/New Tag﹕ Entered While Loop
06-28 15:16:20.930  28418-28418/adameve.relsa D/AndroidRuntime﹕ Shutting down VM
06-28 15:16:20.932  28418-28418/adameve.relsa E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: adameve.relsa, PID: 28418
    java.lang.RuntimeException: Unable to start activity ComponentInfo{adameve.relsa/adameve.relsa.GraphActivity1}: java.lang.NullPointerException: Attempt to invoke virtual method 'int adameve.relsa.BoundService.getStatus()' on a null object reference
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
            at android.app.ActivityThread.access$800(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int adameve.relsa.BoundService.getStatus()' on a null object reference
            at adameve.relsa.GraphActivity1.onStart(GraphActivity1.java:107)
            at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1236)
            at android.app.Activity.performStart(Activity.java:6006)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
            at android.app.ActivityThread.access$800(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)