我正在尝试制作一个简单的收音机,我下面的代码在所有设备(真实设备)上都可以正常工作,但是当我在仿真器上进行测试(Nexus 7 API 22)我收到此错误:
java.lang.NullPointerException:尝试调用虚拟方法'void 对空对象引用的maa.RadioTools.RadioService.playOrPause()' 在maa.RadioTools.RadioManager.playOrPause(RadioManager.java:32) 在maa.MainActivity $ 1.onCompletion(MainActivity.java:130)
崩溃行:
public void playOrPause() {
service.playOrPause();
}
RadioManager.java :
public class RadioManager {
@SuppressLint("StaticFieldLeak")
private static RadioManager instance = null;
private static RadioService service;
private Context context;
private RadioManager(Context context) {
this.context = context;
}
public static RadioManager with(Context context) {
if (instance == null)
instance = new RadioManager(context);
return instance;
}
public static RadioService getService() {
return service;
}
public void playOrPause() {
service.playOrPause();
}
public boolean isPlaying() {
return service.isPlaying();
}
public void bind() {
Intent intent = new Intent(context, RadioService.class);
context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
if (service != null)
EventBus.getDefault().post(service.getStatus());
}
public void unbind() {
context.unbindService(serviceConnection);
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName arg0, IBinder binder) {
service = ((RadioService.LocalBinder) binder).getService();
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
}
};
}
RadioService.java:
public class RadioService extends Service implements Player.EventListener, AudioManager.OnAudioFocusChangeListener {
public static final String ACTION_PLAY = "com.mcakir.radio.player.ACTION_PLAY";
public static final String ACTION_PAUSE = "com.mcakir.radio.player.ACTION_PAUSE";
public static final String ACTION_STOP = "com.mcakir.radio.player.ACTION_STOP";
private final IBinder iBinder = new LocalBinder();
Handler handler;
private final DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter();
private SimpleExoPlayer exoPlayer;
private MediaSessionCompat mediaSession;
private MediaControllerCompat.TransportControls transportControls;
private WifiManager.WifiLock wifiLock;
private AudioManager audioManager;
private MediaNotificationManager notificationManager;
private String status;
String strAppName;
String strLiveBroadcast;
public String streamUrl = "http://radio.link.one/mp3";
public static Boolean AudioFosucSbab = false;
public class LocalBinder extends Binder {
public RadioService getService() {
return RadioService.this;
}
}
private BroadcastReceiver becomingNoisyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
pause();
}
};
private MediaSessionCompat.Callback mediasSessionCallback = new MediaSessionCompat.Callback() {
@Override
public void onPause() {
super.onPause();
pause();
}
@Override
public void onStop() {
super.onStop();
stop();
notificationManager.cancelNotify();
}
@Override
public void onPlay() {
super.onPlay();
resume();
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return iBinder;
}
@Override
public void onCreate() {
super.onCreate();
strAppName = getResources().getString(R.string.app_name);
strLiveBroadcast = getResources().getString(R.string.live_broadcast);
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
notificationManager = new MediaNotificationManager(this);
wifiLock = ((WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE))
.createWifiLock(WifiManager.WIFI_MODE_FULL, "mcScPAmpLock");
mediaSession = new MediaSessionCompat(this, getClass().getSimpleName());
transportControls = mediaSession.getController().getTransportControls();
mediaSession.setActive(true);
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mediaSession.setMetadata(new MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, "...")
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, strAppName)
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, strLiveBroadcast)
.build());
mediaSession.setCallback(mediasSessionCallback);
handler = new Handler();
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
AdaptiveTrackSelection.Factory trackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
DefaultTrackSelector trackSelector = new DefaultTrackSelector(trackSelectionFactory);
exoPlayer = ExoPlayerFactory.newSimpleInstance(getApplicationContext(), trackSelector);
exoPlayer.addListener(this);
registerReceiver(becomingNoisyReceiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
status = PlaybackStatus.IDLE;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String action = intent.getAction();
if (TextUtils.isEmpty(action))
return START_NOT_STICKY;
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
stop();
return START_NOT_STICKY;
}
if (action.equalsIgnoreCase(ACTION_PLAY)) {
transportControls.play();
} else if (action.equalsIgnoreCase(ACTION_PAUSE)) {
transportControls.pause();
} else if (action.equalsIgnoreCase(ACTION_STOP)) {
transportControls.stop();
}
return START_NOT_STICKY;
}
@Override
public boolean onUnbind(Intent intent) {
if (status.equals(PlaybackStatus.IDLE))
stopSelf();
return super.onUnbind(intent);
}
@Override
public void onRebind(final Intent intent) {
}
@Override
public void onDestroy() {
pause();
exoPlayer.release();
exoPlayer.removeListener(this);
notificationManager.cancelNotify();
mediaSession.release();
unregisterReceiver(becomingNoisyReceiver);
super.onDestroy();
}
@Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
exoPlayer.setPlayWhenReady(true);
exoPlayer.setVolume(1.0f);
break;
case AudioManager.AUDIOFOCUS_GAIN:
exoPlayer.setVolume(0.8f);
resume();
break;
case AudioManager.AUDIOFOCUS_LOSS:
AudioFosucSbab = true;
stop();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
AudioFosucSbab = true;
if (isPlaying()) pause();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
if (isPlaying())
exoPlayer.setVolume(0.1f);
break;
}
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState) {
case Player.STATE_BUFFERING:
status = PlaybackStatus.LOADING;
break;
case Player.STATE_ENDED:
status = PlaybackStatus.STOPPED;
break;
case Player.STATE_IDLE:
status = PlaybackStatus.IDLE;
break;
case Player.STATE_READY:
status = playWhenReady ? PlaybackStatus.PLAYING : PlaybackStatus.PAUSED;
break;
default:
status = PlaybackStatus.IDLE;
break;
}
if (!status.equals(PlaybackStatus.IDLE)) {
final Uri uri = Uri.parse("http://radio.link.one/mp3");
OnNewMetadataListener listener = new OnNewMetadataListener() {
@Override
public void onNewHeaders(String stringUri, List<String> name, List<String> desc, List<String> br, List<String> genre, List<String> info) {
}
@Override
public void onNewStreamTitle(String stringUri, final String streamTitle) {
MainActivity.songinfo.setText(streamTitle);
notificationManager.startNotify(getApplicationContext(), status, streamTitle);
}
};
AudiostreamMetadataManager.getInstance()
.setUri(uri)
.setOnNewMetadataListener(listener)
.setUserAgent(UserAgent.WINDOWS_MEDIA_PLAYER)
.start();
}
EventBus.getDefault().post(status);
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
}
@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
@Override
public void onLoadingChanged(boolean isLoading) {
}
@Override
public void onPlayerError(ExoPlaybackException error) {
EventBus.getDefault().post(PlaybackStatus.ERROR);
}
@Override
public void onRepeatModeChanged(int repeatMode) {
}
@Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
@Override
public void onPositionDiscontinuity(int reason) {
}
@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
@Override
public void onSeekProcessed() {
}
public void play(String streamUrl) {
this.streamUrl = streamUrl;
if (wifiLock != null && !wifiLock.isHeld()) {
wifiLock.acquire();
}
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this, getUserAgent(), BANDWIDTH_METER);
ExtractorMediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory)
.setExtractorsFactory(new DefaultExtractorsFactory())
.createMediaSource(Uri.parse(streamUrl));
exoPlayer.prepare(mediaSource);
exoPlayer.setPlayWhenReady(true);
}
public void resume() {
if (streamUrl != null)
play(streamUrl);
}
public void pause() {
exoPlayer.setPlayWhenReady(false);
audioManager.abandonAudioFocus(this);
wifiLockRelease();
}
public void stop() {
exoPlayer.stop();
audioManager.abandonAudioFocus(this);
wifiLockRelease();
}
public void playOrPause() {
if (!isPlaying()) {
play("http://radio.link.one/mp3");
} else {
pause();
}
}
public String getStatus() {
return status;
}
public MediaSessionCompat getMediaSession() {
return mediaSession;
}
public boolean isPlaying() {
return this.status.equals(PlaybackStatus.PLAYING);
}
private void wifiLockRelease() {
if (wifiLock != null && wifiLock.isHeld()) {
wifiLock.release();
}
}
private String getUserAgent() {
return Util.getUserAgent(this, getClass().getSimpleName());
}
}
Manifest.xml :
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
MainActivity.java :
if (!this.isFinishing()) {
statrup.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
radioManager.playOrPause();
}
});
}