mp.isPlaying()抛出致命的NullPointerException

时间:2014-02-27 13:09:32

标签: java android audio null media-player

我有一个按下按钮播放声音的应用程序。

我正试图强制MediaPlayer静音来电并继续以正常音量继续(在空闲模式下)。

我已经编写了下面的代码来完成这个,虽然它在下一行的NullPointerException下崩溃。

if (mp.isPlaying() && state == TelephonyManager.CALL_STATE_RINGING) {

因为

mp.isPlaying()

任何人都可以确定为什么会这样吗?稍后在我的代码中我引用mp来播放声音。

    // Release any resources from previous MediaPlayer
    if (mp != null) {
        mp.release();
    }
    // Create a new MediaPlayer to play this sound
    mp = MediaPlayer.create(this, resId);
    mp.setLooping(true);
    mp.start();

这是我的待命静音和空闲的简历代码。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    PhoneStateListener phoneStateListener = new PhoneStateListener() {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            if (mp.isPlaying() && state == TelephonyManager.CALL_STATE_RINGING) {
                mp.setVolume(0,0);
            } else if(mp.isPlaying() && state == TelephonyManager.CALL_STATE_IDLE) {
                mp.setVolume(1,1);
            } else if(mp.isPlaying() && state == TelephonyManager.CALL_STATE_OFFHOOK) {
                mp.setVolume(0,0);
            }
            super.onCallStateChanged(state, incomingNumber);
        }
    };

    TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
    if(mgr != null) {
        mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

如果在应用程序中稍后调用mp,我无法理解为什么mp为Null。如果它不播放将返回null?如果是这样,我将如何解决这个问题。

这是我要求的整个活动。

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;


public class MainActivity extends Activity implements OnClickListener{
    private MediaPlayer mp;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PhoneStateListener phoneStateListener = new PhoneStateListener() {
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                if (mp.isPlaying() && state == TelephonyManager.CALL_STATE_RINGING) {
                    mp.setVolume(0,0);
                } else if(mp.isPlaying() && state == TelephonyManager.CALL_STATE_IDLE) {
                    mp.setVolume(1,1);
                } else if(mp.isPlaying() && state == TelephonyManager.CALL_STATE_OFFHOOK) {
                    mp.setVolume(0,0);
                }
                super.onCallStateChanged(state, incomingNumber);
            }
        };

        TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        if(mgr != null) {
            mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
        }

        setVolumeControlStream(AudioManager.STREAM_MUSIC);
        Button button1=(Button)findViewById(R.id.button_1);
        Button button2=(Button)findViewById(R.id.button_2);
        Button button3=(Button)findViewById(R.id.button_3);
        Button button4=(Button)findViewById(R.id.button_4);
        Button button5=(Button)findViewById(R.id.button_5);
        Button button6=(Button)findViewById(R.id.button_6);
        Button button7=(Button)findViewById(R.id.button_7);
        Button button8=(Button)findViewById(R.id.button_8);

        final ImageView button_stop=(ImageView)findViewById(R.id.button_stop);
        ImageView button_rate=(ImageView)findViewById(R.id.button_rate);
        ImageView button_exit=(ImageView)findViewById(R.id.button_exit);
        button1.setOnClickListener(this);
        button2.setOnClickListener(this);
        button3.setOnClickListener(this);
        button4.setOnClickListener(this);
        button5.setOnClickListener(this);
        button6.setOnClickListener(this);
        button7.setOnClickListener(this);
        button8.setOnClickListener(this);
        button_stop.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if(null!=mp){
                    mp.release();
                    button_stop.setImageResource(R.drawable.ic_action_volume_muted);
                     }
            }});

        button_exit.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
                notificationManager.cancel(0);
                finish();
            }});

        button_rate.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                String str ="https://play.google.com/store/apps/details?id=example";
                startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(str)));

            }

       ;{ 

       }});




        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle("example")
                .setContentText("example.");
        // Creates an explicit intent for an Activity in your app
        final Intent notificationIntent = new Intent(this, MainActivity.class);
        notificationIntent.setAction(Intent.ACTION_MAIN);
        notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        mBuilder.setOngoing(true);
        // The stack builder object will contain an artificial back stack for the
        // started Activity.
        // This ensures that navigating backward from the Activity leads out of
        // your application to the Home screen.

        // Adds the back stack for the Intent (but not the Intent itself)
        PendingIntent resultPendingIntent = PendingIntent.getActivity(this,0,notificationIntent,PendingIntent.FLAG_UPDATE_CURRENT);

        mBuilder.setContentIntent(resultPendingIntent);
        NotificationManager mNotificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        int mId = 0;
        // mId allows you to update the notification later on.
        mNotificationManager.notify(mId, mBuilder.build());
    }

    public void onClick(View v) {
        int resId;
        switch (v.getId()) {
        case R.id.button_1:
            resId = R.raw.birdsong;
            break;
        case R.id.button_2:
            resId = R.raw.electrifying_thunderstorms;
            break;
        case R.id.button_3:
            resId = R.raw.fan;
            break;
        case R.id.button_4:
            resId = R.raw.jungle_river;
            break;
        case R.id.button_5:
            resId = R.raw.pig_frogs;
            break;
        case R.id.button_6:
            resId = R.raw.predawn;
            break;
        case R.id.button_7:
            resId = R.raw.shower;
            break;
        case R.id.button_8:
            resId = R.raw.twilight;
            break;
        default:
            resId = R.raw.birdsong;
            break;
        }
        // Release any resources from previous MediaPlayer
        if (mp != null) {
            mp.release();
        }
        // Create a new MediaPlayer to play this sound
        mp = MediaPlayer.create(this, resId);
        mp.setLooping(true);
        mp.start();

        ImageView button_stop=(ImageView)findViewById(R.id.button_stop);
        button_stop.setImageResource(R.drawable.ic_action_volume_on);

    }{


                        }
    @Override
    protected void onDestroy() {
        if(null!=mp){
            mp.release();
        }
        super.onDestroy();
    }

    }

logcat的

02-27 12:55:12.306: W/dalvikvm(887): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
02-27 12:55:12.326: E/AndroidRuntime(887): FATAL EXCEPTION: main
02-27 12:55:12.326: E/AndroidRuntime(887): java.lang.NullPointerException
02-27 12:55:12.326: E/AndroidRuntime(887):  at me.soundasleep.app.MainActivity$1.onCallStateChanged(MainActivity.java:36)
02-27 12:55:12.326: E/AndroidRuntime(887):  at android.telephony.PhoneStateListener$2.handleMessage(PhoneStateListener.java:369)
02-27 12:55:12.326: E/AndroidRuntime(887):  at android.os.Handler.dispatchMessage(Handler.java:99)
02-27 12:55:12.326: E/AndroidRuntime(887):  at android.os.Looper.loop(Looper.java:137)
02-27 12:55:12.326: E/AndroidRuntime(887):  at android.app.ActivityThread.main(ActivityThread.java:5041)
02-27 12:55:12.326: E/AndroidRuntime(887):  at java.lang.reflect.Method.invokeNative(Native Method)
02-27 12:55:12.326: E/AndroidRuntime(887):  at java.lang.reflect.Method.invoke(Method.java:511)
02-27 12:55:12.326: E/AndroidRuntime(887):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-27 12:55:12.326: E/AndroidRuntime(887):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-27 12:55:12.326: E/AndroidRuntime(887):  at dalvik.system.NativeStart.main(Native Method)
02-27 12:55:12.358: W/ActivityManager(292):   Force finishing activity me.soundasleep.app/.MainActivity
02-27 12:55:12.366: W/WindowManager(292): Failure taking screenshot for (328x583) to layer 21010
02-27 12:55:12.656: E/SurfaceFlinger(37): ro.sf.lcd_density must be defined as a build property
02-27 12:55:12.886: W/ActivityManager(292): Activity pause timeout for ActivityRecord{4132e3e0 u0 me.soundasleep.app/.MainActivity}
02-27 12:55:13.149: E/SurfaceFlinger(37): ro.sf.lcd_density must be defined as a build property
02-27 12:55:16.186: I/Process(887): Sending signal. PID: 887 SIG: 9
02-27 12:55:16.206: I/ActivityManager(292): Process EXAMPLE (pid 887) has died.

3 个答案:

答案 0 :(得分:4)

在创建PhoneStateListener()之前正在执行MediaPlayer,这就是你获得空指针异常的原因。在声明其侦听器phoneStateListener

之前,请使用以下方法
    mp = MediaPlayer.create(this, resId);
    mp.setLooping(true);
    mp.start();

    PhoneStateListener phoneStateListener = new PhoneStateListener() {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            if (mp.isPlaying() && state == TelephonyManager.CALL_STATE_RINGING) {
                mp.setVolume(0,0);
            } else if(mp.isPlaying() && state == TelephonyManager.CALL_STATE_IDLE) {
                mp.setVolume(1,1);
            } else if(mp.isPlaying() && state == TelephonyManager.CALL_STATE_OFFHOOK) {
                mp.setVolume(0,0);
            }
            super.onCallStateChanged(state, incomingNumber);
        }
    };

希望它有所帮助!

答案 1 :(得分:1)

您正在创建

mp = MediaPlayer.create(this, resId);中的{p> onClick()您在mp中使用的是onCreate()

创建对象,以便在mp

中使用之前创建onCreate()

答案 2 :(得分:0)

问题很简单。

您确实在类中声明了mp,但在创建时您还没有初始化它。因此,当它来onCreate方法时,mp为空。因此错误。

我的建议是在onCreate方法

中执行此操作
    mp = MediaPlayer.create(this, R.raw.birdsong);

不要玩它。只是将其初始化。它不会崩溃

更好理解的代码

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

   //this line is EXTRA    ///
    mp = MediaPlayer.create(this, R.raw.birdsong);

    PhoneStateListener phoneStateListener = new PhoneStateListener() {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            if (mp.isPlaying() && state == TelephonyManager.CALL_STATE_RINGING) {
                mp.setVolume(0,0);
            } else if(mp.isPlaying() && state == TelephonyManager.CALL_STATE_IDLE) {
                mp.setVolume(1,1);
            } else if(mp.isPlaying() && state == TelephonyManager.CALL_STATE_OFFHOOK) {
                mp.setVolume(0,0);
            }
            super.onCallStateChanged(state, incomingNumber);
        }
    };