在服务中运行加速度计会出现“无法创建服务”异常

时间:2013-12-30 11:55:10

标签: java android

实际上我希望Accelerometer在后​​台运行并发出消息,但我得到一些例外。这是我的所有xml和java文件。请帮忙!

这是我的Service班级

    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.os.IBinder;
    import android.widget.Toast;
    public class MyService extends Service implements AccelerometerListener 
    {
        private static  Context mycontext;  
        @Override
        public IBinder onBind(Intent arg0) {
            throw new UnsupportedOperationException("Not Implemented Yet");
        }   
        @Override
        public void onCreate() {
            // TODO Auto-generated method stub
            mycontext=MyService.this;
            Toast.makeText(this,"Accelerometer is starting", Toast.LENGTH_LONG);
            AccelerometerManager.startListening(this);
        }

        @Override
        public void onShake(float force) {
            // TODO Auto-generated method stub
            Toast.makeText(this,"Motion detected", Toast.LENGTH_SHORT);
        }

        @Override
        public void onDestroy() {
            // TODO Auto-generated method stub
            super.onDestroy();
            Toast.makeText(this,"Accelerometer is destroyed",Toast.LENGTH_LONG);
            AccelerometerManager.stopListening();
        }

        public static Context getContext() {
            return mycontext;
            }

        @Override
        public void onAccelerationChanged(float x, float y, float z) {
            // TODO Auto-generated method stub

        }
    }

MainActivity上课

    import android.os.Bundle;
    import android.app.Activity;
    import android.content.Intent;
    import android.view.Menu;
    import android.view.View;

    public class MainActivity extends Activity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
        // Start the  service
        public void startNewService(View view) 
        {
            startService(new Intent(MainActivity.this, MyService.class));
        }
        // Stop the  service
        public void stopNewService(View view) 
        {
            stopService(new Intent(MainActivity.this, MyService.class));
        }

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

    }  

AccelerometerListener

public interface AccelerometerListener {

    public void onAccelerationChanged(float x, float y, float z);

    public void onShake(float force);

}

AccelerometerManager上课

import java.util.List;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.widget.Toast;

public class AccelerometerManager {

    private static Context aContext=null;


    /** Accuracy configuration */
    private static float threshold  = 15.0f; 
    private static int interval     = 200;

    private static Sensor sensor;
    private static SensorManager sensorManager;
    // you could use an OrientationListener array instead
    // if you plans to use more than one listener
    private static AccelerometerListener listener;

    /** indicates whether or not Accelerometer Sensor is supported */
    private static Boolean supported;
    /** indicates whether or not Accelerometer Sensor is running */
    private static boolean running = false;

    /**
     * Returns true if the manager is listening to orientation changes
     */
    public static boolean isListening() {
        return running;
    }

    /**
     * Unregisters listeners
     */
    public static void stopListening() {
        running = false;
        try {
            if (sensorManager != null && sensorEventListener != null) {
                sensorManager.unregisterListener(sensorEventListener);
            }
        } catch (Exception e) {}
    }

    /**
     * Returns true if at least one Accelerometer sensor is available
     */
    public static boolean isSupported(Context context) {
        aContext = context;
        if (supported == null) {
            if (aContext != null) {


                sensorManager = (SensorManager) aContext.
                        getSystemService(Context.SENSOR_SERVICE);

                // Get all sensors in device
                List<Sensor> sensors = sensorManager.getSensorList(
                        Sensor.TYPE_ACCELEROMETER);

                supported = new Boolean(sensors.size() > 0);



            } else {
                supported = Boolean.FALSE;
            }
        }
        return supported;
    }

    /**
     * Configure the listener for shaking
     * @param threshold
     *             minimum acceleration variation for considering shaking
     * @param interval
     *             minimum interval between to shake events
     */
    public static void configure(int threshold, int interval) {
        AccelerometerManager.threshold = threshold;
        AccelerometerManager.interval = interval;
    }

    /**
     * Registers a listener and start listening
     * @param accelerometerListener
     *             callback for accelerometer events
     */
    public static void startListening( AccelerometerListener accelerometerListener ) 
    {

        sensorManager = (SensorManager) aContext.
                getSystemService(Context.SENSOR_SERVICE);

        // Take all sensors in device
        List<Sensor> sensors = sensorManager.getSensorList(
                Sensor.TYPE_ACCELEROMETER);

        if (sensors.size() > 0) {

            sensor = sensors.get(0);

            // Register Accelerometer Listener
            running = sensorManager.registerListener(
                    sensorEventListener, sensor, 
                    SensorManager.SENSOR_DELAY_GAME);

            listener = accelerometerListener;
        }


    }

    /**
     * Configures threshold and interval
     * And registers a listener and start listening
     * @param accelerometerListener
     *             callback for accelerometer events
     * @param threshold
     *             minimum acceleration variation for considering shaking
     * @param interval
     *             minimum interval between to shake events
     */
    public static void startListening(
            AccelerometerListener accelerometerListener, 
            int threshold, int interval) {
        configure(threshold, interval);
        startListening(accelerometerListener);
    }

    /**
     * The listener that listen to events from the accelerometer listener
     */
    private static SensorEventListener sensorEventListener = 
        new SensorEventListener() {

        private long now = 0;
        private long timeDiff = 0;
        private long lastUpdate = 0;
        private long lastShake = 0;

        private float x = 0;
        private float y = 0;
        private float z = 0;
        private float lastX = 0;
        private float lastY = 0;
        private float lastZ = 0;
        private float force = 0;

        public void onAccuracyChanged(Sensor sensor, int accuracy) {}

        public void onSensorChanged(SensorEvent event) {
            // use the event timestamp as reference
            // so the manager precision won't depends 
            // on the AccelerometerListener implementation
            // processing time
            now = event.timestamp;

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

            // if not interesting in shake events
            // just remove the whole if then else block
            if (lastUpdate == 0) {
                lastUpdate = now;
                lastShake = now;
                lastX = x;
                lastY = y;
                lastZ = z;
                Toast.makeText(aContext,"No Motion detected", 
                   Toast.LENGTH_SHORT).show();

            } else {
                timeDiff = now - lastUpdate;

                if (timeDiff > 0) { 

                    /*force = Math.abs(x + y + z - lastX - lastY - lastZ) 
                                / timeDiff;*/
                    force = Math.abs(x + y + z - lastX - lastY - lastZ);

                    if (Float.compare(force, threshold) >0 ) {
                        //Toast.makeText(Accelerometer.getContext(), 
                        //(now-lastShake)+"  >= "+interval, 1000).show();

                        if (now - lastShake >= interval) { 

                            // trigger shake event
                            listener.onShake(force);
                        }
                        else
                        {
                            Toast.makeText(aContext,"No Motion detected", 
                                Toast.LENGTH_SHORT).show();

                        }
                        lastShake = now;
                    }
                    lastX = x;
                    lastY = y;
                    lastZ = z;
                    lastUpdate = now; 
                }
                else
                {
                    Toast.makeText(aContext,"No Motion detected", Toast.LENGTH_SHORT).show();

                }
            }
            // trigger change event
            listener.onAccelerationChanged(x, y, z);
        }

    };

}

清单文件

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.secondapplication"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <service 
            android:name=".MyService"
            />
        <activity
            android:name="com.example.secondapplication.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >
<Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="22dp"
        android:layout_marginTop="44dp"
        android:onClick="startNewService"
        android:text="Start Activity" 
        />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/button1"
        android:layout_alignParentRight="true"
        android:layout_marginRight="14dp"
        android:onClick="stopNewService"
        android:text="Stop Activity"
         />


</RelativeLayout>

例外

FATAL EXCEPTION: main
12-30 17:28:12.729: E/AndroidRuntime(16553): java.lang.RuntimeException: Unable to create service com.example.secondapplication.MyService: java.lang.NullPointerException
12-30 17:28:12.729

1 个答案:

答案 0 :(得分:1)

我认为当您在Service onCreate方法中调用AccelerometerManager.startListening(this);时,AccelerometerManager的aContext字段为空。

您应该分配传递给aContext

的上下文

更改startListening(AccelerometerListener accelerometerListener)的签名 到startListening(Context accelerometerListener)

public static void startListening( Context accelerometerListener ) 
{

    aContext = accelerometerLister;
    sensorManager = (SensorManager) aContext.
            getSystemService(Context.SENSOR_SERVICE);

    .......
    .........

        listener = (AccelerometerListener) accelerometerListener;
    }
}