

現在ダイアログ上のスタートボタンを押すことで録音を開始し、ストップボタンを押すと別の保存確認ダイアログが表示され、そこで保存ボタンを押すと録音した音声が保存されるプログラムを組んでいます。しかし、録音を終了すると、
`RecDialog` クラスの `stopRecording` メソッド内の `mRecorder.stop()` で
`NullPointerException`が返ってきます。色々とトライしてみても依然結果は同じです。これはなぜなのでしょうか？
`DialogFragment` を使っているあたり何か関係があるのでしょうか？

すみませんが、宜しくお願いします。

_RecDialog_ :

[code]

    public class RecDialog extends DialogFragment {
        private MediaRecorder mRecorder;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            mView = inflater.inflate(R.layout.rec_dialog, null);
    
            final ImageButton recordButton = (ImageButton) mView.findViewById(R.id.recButton);
            recordButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (!mRecButtonClick) {
                        recordButton.setImageResource(R.drawable.microphone_on);
                        mRecorder = new MediaRecorder();
                        startRecording();
                        mRecButtonClick = true;
                    } else {
                        recordButton.setImageResource(R.drawable.microphone_off);
                        mRecButtonClick = false;
                        showDialogBroadcast();
                    }
            });
        }
    
        public class MyBroadcastReceiver extends BroadcastReceiver {
            @Override
            public void onReceive(Context context, Intent intent) {
                DialogFragment dialog = new SaveDialog();
                dialog.show(getFragmentManager(), "dialog");
            }
        }
    
        public void showDialogBroadcast() {
            Intent broadcastIntent = new Intent();
            broadcastIntent.setAction("show_saveDialog");
            getActivity().sendBroadcast(broadcastIntent);
        }
    
        public void startRecording() {
            File sampleDir = new File(Environment.getExternalStorageDirectory() + "/Test");
            try {
                mAudiofile = File.createTempFile("voice", ".3gp", sampleDir);
            } catch (IOException e) {
                return;
            }
            mRecorder = new MediaRecorder();
            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            mRecorder.setOutputFile(mAudiofile.getAbsolutePath());
            try {
                mRecorder.prepare();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mRecorder.start();
        }
    
        public void stopRecording(String fileName) {
            mRecorder.stop();
            mRecorder.release();
            addVoiceToMediaLibrary(fileName);
        }
    
[/code]

_SaveDialog_ :

[code]

    RecDialog recDialog = new RecDialog();
    recDialog.stopRecording(editText.getText().toString());
    
[/code]


CC BY-SA 3.0
2015-01-15T00:00:00.777
4576
2015-03-30T14:18:16.427
2015-01-29T13:23:16.370
4978
5210
question
android java nullpointerexception
MediaRecorder.stop() で NullPointerException が返ってくる


質問内容＋質問者さんコメントからの推測ですが、概ね下記のようなコード構造となっているのでは？

[code]

    class RecDialog {
      private MediaRecorder mRecorder;  // <-- インスタンス変数
      //...
    
      public void startRecording() {
        mRecorder = new MediaRecorder();
        // ...
        mRecorder.start();
      }
    
      public void stopRecording(String fileName) {
        mRecorder.stop();
        // ...
      }
    }
    
    class SaveDialog {
      //...
    
      public void startOperation() {
        RecDialog recDialog = new RecDialog();  // (1)
        recDialog.startRecording();
      }
    
      public void stopOperation() {
        RecDialog recDialog = new RecDialog();  // (2)
        recDialog.stopRecording(editText.getText().toString());
      }
    }
    
[/code]

`mRecorder`を`RecDialog`クラスの「インスタンス変数」としているならば、`RecDialog`クラスのインスタンスが破棄されると同時に`mRecorder`が指す先も破棄されます。前掲コードだと(1)と(2)は`RecDialog`クラスの
**異なる**
インスタンスを指すため、(1)で設定した`mRecorder`の値が(2)に引き継がれることはありません。(2)では`mRecorder`は未初期化(`null`)のままであり、`null`に対して「インスタンスメソッド」`stopRecording`を呼び出そうとした結果、NullPointerException例外が発生します。

これはAndroid環境固有の振る舞いではなくプログラミング言語Javaの仕様によるものですから、この辺りのJavaの基礎を再確認されるのが良いかと思います。（普通のJava入門書であれば必ず言及されているはずです。キーワードとしては「インスタンス変数」、「インスタンスメソッド」が該当します。）


CC BY-SA 3.0
2015-01-15T05:22:10.353
4592
2015-01-15T09:47:12.013
2015-01-15T09:47:12.013
49
49
4576
answer