0

I want to pass the readings of a sensor to the class MyCompassView that extends a view, and based on the readings from the sensor to be passed, a pointer is changing its orientation. Actually, all this works fine, i tested it. But the same concept when I tried to implement it on a surface view that opens the camera preview on the surface, it does not work and crashes the app. Simply, I have SurfaceViewHolder class the holds the camera preview, the MyCompassView class as described above and the MainActivity that should has both views of MyCompassView and SurfaceHolder on its surface. The way I used to overlay the MainActivity with these views is as posted below: please help me to find why the method myCompassView.update(azimuth);that is located inside the onSensorChanged cause the logcate to say"Null Pointer Exception"

UPDATE:

When I omit myCompassView.update(azimuth); the app works but with drawings in the MyCompassView class is static not indicting orientation, ofcourse because of the myCompassView.update(azimuth); is not activated.However, when i activate that method
the app crashs and the logcat generates the posted output. Line 100 is myCompassView.update(azimuth);

MainActivity.java

     public class Mainactivity extends ActionBarActivity  implements SensorEventListener {

    private SurfaceHolderActivity myCameraSurfaceHolder;
    private View compassOverLayView;
    private MyCompassView myCompassView;
    private LayoutInflater loiViewInflater = null;
            ..
            ..
            //myCompassView = new MyCompassView(getApplicationContext());               
            myCompassView = (MyCompassView) findViewById(R.id.mycompass);
        myCameraSurfaceHolder = new SurfaceHolderActivity(this);
        setContentView(myCameraSurfaceHolder);          
                    
        loiViewInflater = (LayoutInflater) getSystemService (Context.LAYOUT_INFLATER_SERVICE);
        loiViewInflater = LayoutInflater.from(getApplicationContext());
        compassOverLayView = loiViewInflater.inflate(R.layout.activity_viewactivity, null);
        addContentView(compassOverLayView, new LayoutParams(LayoutParams.FILL_PARENT, 
                LayoutParams.FILL_PARENT));
    ...
    ...
            @Override
    public void onSensorChanged(SensorEvent event) {
        // TODO Auto-generated method stub
        switch (event.sensor.getType()) {
        case Sensor.TYPE_ACCELEROMETER:
            valuesAccelerometer = event.values.clone();
            /*for (int i=0; i<3; i++) {
                valuesAccelerometer[i] = event.values[i];
            }*/
            break;
        case Sensor.TYPE_MAGNETIC_FIELD:
            valuesMagneticField = event.values.clone();
            /*for (int i=0; i<3; i++) {
                valuesMagneticField[i] = event.values[i];
            }*/
            break;
        }
        
        boolean success = SensorManager.getRotationMatrix(MatrixR, MatrixI, 
                valuesMagneticField, valuesAccelerometer);
        if (success) {
            SensorManager.getOrientation(MatrixR, MatrixValues);
            azimuth = Math.toDegrees(MatrixValues[0]);
            pitch = Math.toDegrees(MatrixValues[1]);
            roll = Math.toDegrees(MatrixValues[2]);             
            myCompassView.update(azimuth);
        } 
    }

Activity_ViewActivity.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="com.example.augrealtest00.Mainactivity" >

<view 
        android:id="@+id/mycompass" 
        android:layout_height="match_parent" 
        android:layout_width="match_parent" 
        class="com.example.augrealtest01.MyCompassView"/>

</RelativeLayout>

Logcat:

04-26 23:38:15.136: E/AndroidRuntime(18873): java.lang.NullPointerException
04-26 23:38:15.136: E/AndroidRuntime(18873):    at 
com.example.augrealtest01.Mainactivity.onSensorChanged(Mainactivity.java:100)
04-26 23:38:15.136: E/AndroidRuntime(18873):    at         android.hardware.SystemSensorManager$SensorEventQueue.dispatchSensorEvent(SystemSensorManag    er.java:467)
04-26 23:38:15.136: E/AndroidRuntime(18873):    at  
android.os.MessageQueue.nativePollOnce(Native Method)
04-26 23:38:15.136: E/AndroidRuntime(18873):    at    
android.os.MessageQueue.next(MessageQueue.java:132)
04-26 23:38:15.136: E/AndroidRuntime(18873):    at    
android.os.Looper.loop(Looper.java:124)
04-26 23:38:15.136: E/AndroidRuntime(18873):    at android.app.ActivityThread.main(ActivityThread.java:5493)
4

2 回答 2

0

移动那条线:

myCompassView = (MyCompassView) findViewById(R.id.mycompass);

之后调用:

setContentView(myCameraSurfaceHolder);
....
addContentView(compassOverLayView, new LayoutParams(LayoutParams.FILL_PARENT, 
            LayoutParams.FILL_PARENT));

因此 id =mycompass的视图附加到活动的视图层次结构中。

否则,findViewById将返回 null,因此您的 NPE。

于 2014-04-26T22:44:07.983 回答
-1

我还不能添加注释,但是您的代码中的哪一行抛出了 NullPointerException?

我不相信会这样event。是否为myCompassView空?

更新的答案

你可以做这样的事情

<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="com.example.augrealtest00.Mainactivity" >
<-- Include your SurfaceView inside your Activity layout -->
<SurfaceView
    android:id="@+id/surface_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

<view
    android:id="@+id/mycompass"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    class="com.example.augrealtest01.MyCompassView"/>

</RelativeLayout>

活动代码

...
setContentView(R.layout.[your_activity_layout});
myCompassView = (CompassView) findViewById(R.id.mycompass);
surfaceView = (SurfaceView) findViewById(R.id.surface_view);
...

现在您可以从一个布局资源文件访问您的 SurfaceView 和 CompassView,CompassView 将不再为 NULL,您可以从那里获取它。

我希望这有帮助!

于 2014-04-26T22:12:24.857 回答