0

ビューを拡張するクラスにセンサーの読み取り値を渡したいのですが、MyCompassView渡されるセンサーからの読み取り値に基づいて、ポインターの向きが変わります。実際、これはすべて正常に動作します。テストしました。しかし、サーフェス上でカメラ プレビューを開くサーフェス ビューに実装しようとしたときと同じ概念が機能せず、アプリがクラッシュします。簡単に言えば、SurfaceViewHolderカメラのプレビューを保持するMyCompassViewクラス、上記のクラス、およびその表面とその表面MainActivityの両方のビューを持つ必要があるクラスがあります。これらのビューをオーバーレイするために使用した方法は、以下に投稿されているとおりです。logcate に「Null Pointer Exception」と表示される原因の内部にあるメソッドを見つけるのを手伝ってください。MyCompassViewSurfaceHolderMainActivitymyCompassView.update(azimuth);onSensorChanged

更新

myCompassView.update(azimuth);アプリ を省略すると動作しますが、MyCompassViewクラス内の図面は静的であり、方向を示してい ません。もちろん、myCompassView.update(azimuth);アクティブ化されていないため
です。100行目は 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>

ログキャット:

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のビューはアクティビティのビュー階層に関連付けられます。

それ以外の場合は、findViewByIdnull が返されるため、NPE が返されます。

于 2014-04-26T22:44:07.983 に答える
-1

まだコメントを追加できませんが、コードのどの行で NullPointerException がスローされていますか?

私はそうなるとは思わないeventmyCompassViewヌルですか?

更新された回答

このようなことができます

<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);
...

これで、1 つのレイアウト リソース ファイルから SurfaceView と CompassView にアクセスできるようになりました。CompassView は NULL ではなくなり、そこから取得できます。

これが役立つことを願っています!

于 2014-04-26T22:12:24.857 に答える