2014-02-27 36 views
0

我有一个应用程序在按钮按下时播放声音。mp.isPlaying()正在投掷致命的NullPointerException

我试图强制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); 
    } 

我不明白为什么,如果它被称为应用程序以后,熔点为空。如果它没有播放,将返回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. 
+0

你可以发布你的整个活动之前产生的? – Giacomoni

+0

更新的问题,包括整个活动 – rossd

+1

你也可以粘贴堆栈跟踪? – zibi

回答

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

希望它能帮助!

+0

现在比你非常完美。这样一个简单的修复为新手错误:) – rossd

1

您正在创建onClick()

mp = MediaPlayer.create(this, resId);和您在使用onCreate()mp

创建对象,以便mp使用在onCreate()

+0

非常感谢!完美的作品。我忘记了代码是按顺序读取的,而且mp尚未创建。 – rossd