MediaPlayer error-getCurrentPosition - java

Please teach me how can I solve a MediaPlayer error. I have Mediaplayer, MediaController and listview. When I touch the list, a song starts with MediaController, but when I touch keycode_home and restart my app, the error occurs. Here is my code and error.
java.lang.RuntimeException: Unable to resume activity {}:
java.lang.IllegalStateException
Caused by: java.lang.IllegalStateException at android.media.MediaPlayer.getCurrentPosition(Native Method)
int si[]={R.raw.sample1,R.raw.sample2,R.raw.sample3};
onCreate
ItemBean IB1 = new ItemBean();
IB1.setName("sample1");
IB1.setUrl("http~");
ItemBean IB2 = new ItemBean();
IB2.setName("sample2");
IB2.setUrl("http~");
ItemBean IB3 = new ItemBean();
IB3.setName("sample3");
IB3.setUrl("http~");
List<ItemBean> list = new ArrayList<ItemBean>();
list.add(IB1);
list.add(IB2);
list.add(IB3);
mp = new MediaPlayer();
controller = new MediaController(this);
controller.setAnchorView(findViewById(R.id.mediaController));
controller.setMediaPlayer(this);
list2 = (ListView) findViewById(R.id.song_list);
SonglistAdapter_test adapter = new SonglistAdapter_test(getApplicationContext(),list);
list2.setAdapter(adapter);
list2.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
try {
mp.reset();
mp.release();
mp = MediaPlayer.create(SongsActivity.this,si[position]);
} catch (Exception e) {}
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
handler.post(new Runnable() {
#Override
public void run() {
controller.setEnabled(true);
controller.show(mp.getDuration());
mp.start();
try {
Method m = android.widget.MediaController.class.getDeclaredMethod("updatePausePlay");
m.setAccessible(true);
m.invoke(controller);
} catch (Exception e) {
}
}
});
}
});
}
#Override
public void start(){
mp.start(); }
#Override
public void pause(){
mp.pause(); }
#Override
public int getDuration(){
return mp.getDuration(); }
#Override
public int getCurrentPosition(){
return mp.getCurrentPosition(); }
#Override
public void seekTo(int pos){
mp.seekTo(pos); }
#Override
public boolean isPlaying(){
return mp.isPlaying(); }
#Override
public int getBufferPercentage(){
return 0; }
#Override
public boolean canPause(){
return true; }
#Override
public boolean canSeekBackward(){
return true; }
#Override
public boolean canSeekForward(){
return true; }
#Override
public int getAudioSessionId(){
return 0; }
#Override
protected void onPause(){
super.onPause();
}
#Override
protected void onResume(){
super.onResume();
}
#Override
protected void onStop(){
super.onStop();
controller.hide();
mp.stop();
mp.release();
}
#Override
public void onRestart(){
super.onRestart();
controller.show();
}
#Override
protected void onDestroy(){
super.onDestroy();
finish();
}
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
finish();
}
return super.dispatchKeyEvent(event);
}

The problem is in your onStop() method -- you are releasing your media player there and not recreating it before you show the controller during onRestart(). The onStop() method is not the same as onDestroy() -- onStop() doesn't mean that your activity will necessarily run through onCreate() again when it is resumed.
You should have a look at the Activity Lifecycle to get a better understanding of when these events occur.

Related

Media Player not playing sound from a live source but works for mp3

Currently working on an app in Android Studio to play music from a live audio source. I got the play and pause button to work for certain url's such as this, which may only work either because it's http. However, when doing it with this link, which is live audio from a college radio station, it doesn't play anything (the static when the station is not on can't be heard in the app).
My code is below:
public class RadioSelection extends AppCompatActivity {
ImageView fm;
ImageView digital;
MediaPlayer mediaPlayer;
ImageView playPause;
String stream = "http://wmuc.umd.edu:8000/wmuc-hq";
boolean prepared = false;
boolean started = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radio_selection);
mediaPlayer=new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
new PlayerTask().execute(stream);
playPause = findViewById(R.id.play_pause);
fm = findViewById(R.id.fm);
digital = findViewById(R.id.digital);
playPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (started) {
started = false;
mediaPlayer.pause();
Toast.makeText(RadioSelection.this, "Paused", Toast.LENGTH_SHORT).show();
} else {
started = true;
mediaPlayer.start();
Toast.makeText(RadioSelection.this, "Playing", Toast.LENGTH_SHORT).show();
}
}
});
fm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
digital.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
private class PlayerTask extends AsyncTask<String, Void, Boolean> {
#Override
protected Boolean doInBackground(String... strings) {
try {
mediaPlayer.setDataSource(strings[0]);
mediaPlayer.prepare();
prepared = true;
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("It's prepared!");
return prepared;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
}
}
#Override
protected void onPause() {
super.onPause();
if (started) {
mediaPlayer.pause();
}
}
#Override
protected void onResume() {
super.onResume();
if (started) {
mediaPlayer.start();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (prepared) {
mediaPlayer.release();
}
}
}
I feel like it has to do with the protocol but I'm not sure, and I don't really know of a way to test if it actually successfully connected to the audio source. I'd really appreciate any help.

NavigationView with useroffroute MapBox Android

I'm actually trying to use the useroffroute function but it's not working, I saw this other post and it said to NavigationView, only I don't know how to do it exactly. I am currently using this code to detect if the user has left the route, but he is not calling the useroffroute function. What I'm trying to do is that when the user leaves the route he fires a Toast for the user, but unfortunately I was not successful.
public class mapbox extends AppCompatActivity{
private MapView mapView;
Button button;
private static final String TAG = "resultados";
private MapboxNavigation navigation;
private boolean running;
private NavigationMapboxMap map;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapbox.getInstance(this, getString(R.string.mapbox_access_token));
setContentView(R.layout.activity_mapbox);
button = findViewById(R.id.button);
MapboxNavigationOptions options = MapboxNavigationOptions.builder().isDebugLoggingEnabled(true).build();
navigation = new MapboxNavigation(getApplicationContext(), getString(R.string.mapbox_access_token), options);
/*
navigation.addOffRouteListener(new OffRouteListener() {
#Override
public void userOffRoute(Location location) {
Toast.makeText(getApplicationContext(), "Off route detected.........", Toast.LENGTH_SHORT).show();
// Make sure you call for a new DirectionsRoute object
// and end by calling MapboxNavigation#startNavigation on a successful
}
});
*/
/*
mapView = (MapView) findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(#NonNull MapboxMap mapboxMap) {
mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() {
#Override
public void onStyleLoaded(#NonNull Style style) {
// Map is set up and the style has loaded. Now you can add data or make other map adjustments
}
});
}
});
*/
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// From Mapbox to The White House
Point origin = Point.fromLngLat(-38.62882018, -3.78666528);
Point destination = Point.fromLngLat(-38.56038094, -3.7337361F);
NavigationRoute.builder(mapbox.this)
.accessToken(getString(R.string.mapbox_access_token))
.origin(origin)
.destination(destination)
.build()
.getRoute(new Callback<DirectionsResponse>() {
#Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
Log.i(TAG, response+"");
// Route fetched from NavigationRoute
DirectionsRoute route = response.body().routes().get(0);
// Create a NavigationLauncherOptions object to package everything together
NavigationLauncherOptions options = NavigationLauncherOptions.builder()
.directionsRoute(route)
.shouldSimulateRoute(false)
.build();
// Call this method with Context from within an Activity
NavigationLauncher.startNavigation(mapbox.this, options);
}
#Override
public void onFailure(Call<DirectionsResponse> call, Throwable t) {
}
});
}
});
}
#Override
protected void onStart() {
super.onStart();
//mapView.onStart();
}
#Override
protected void onResume() {
super.onResume();
//mapView.onResume();
}
#Override
protected void onPause() {
super.onPause();
//mapView.onPause();
}
#Override
protected void onStop() {
super.onStop();
//mapView.onStop();
}
#Override
public void onSaveInstanceState(#NonNull Bundle outState, #NonNull PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
//mapView.onSaveInstanceState(outState);
}
#Override
public void onLowMemory() {
super.onLowMemory();
//mapView.onLowMemory();
}
#Override
protected void onDestroy() {
super.onDestroy();
//mapView.onDestroy();
}
}
After many hours looking for a solution, I finally found one. You have to use NavigationViewer to obtain the parameters that the application passes, so you can listen if the user leaves the route. Here's an example:
public class last extends AppCompatActivity implements OnNavigationReadyCallback,
NavigationListener, RouteListener, ProgressChangeListener {
private NavigationView navigationView;
private boolean dropoffDialogShown;
private Location lastKnownLocation;
private List<Point> points = new ArrayList<>();
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
Mapbox.getInstance(this, getString(R.string.mapbox_access_token));
setTheme(R.style.Theme_AppCompat_NoActionBar);
super.onCreate(savedInstanceState);
points.add(Point.fromLngLat(-38.62882018, -3.78666528));
points.add(Point.fromLngLat(-38.56038094, -3.7337361));
setContentView(R.layout.activity_last);
navigationView = findViewById(R.id.navigationView);
navigationView.onCreate(savedInstanceState);
navigationView.initialize(this);
}
#Override
public void onStart() {
super.onStart();
navigationView.onStart();
}
#Override
public void onResume() {
super.onResume();
navigationView.onResume();
}
#Override
public void onLowMemory() {
super.onLowMemory();
navigationView.onLowMemory();
}
#Override
public void onBackPressed() {
// If the navigation view didn't need to do anything, call super
if (!navigationView.onBackPressed()) {
super.onBackPressed();
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
navigationView.onSaveInstanceState(outState);
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
navigationView.onRestoreInstanceState(savedInstanceState);
}
#Override
public void onPause() {
super.onPause();
navigationView.onPause();
}
#Override
public void onStop() {
super.onStop();
navigationView.onStop();
}
#Override
protected void onDestroy() {
super.onDestroy();
navigationView.onDestroy();
}
#Override
public void onNavigationReady(boolean isRunning) {
fetchRoute(points.remove(0), points.remove(0));
}
#Override
public void onCancelNavigation() {
// Navigation canceled, finish the activity
finish();
}
#Override
public void onNavigationFinished() {
// Intentionally empty
}
#Override
public void onNavigationRunning() {
// Intentionally empty
}
#Override
public boolean allowRerouteFrom(Point offRoutePoint) {
return true;
}
#Override
public void onOffRoute(Point offRoutePoint) {
Toast.makeText(this, "Off route", Toast.LENGTH_SHORT).show();
}
#Override
public void onRerouteAlong(DirectionsRoute directionsRoute) {
}
#Override
public void onFailedReroute(String errorMessage) {
}
#Override
public void onArrival() {
if (!dropoffDialogShown && !points.isEmpty()) {
showDropoffDialog();
dropoffDialogShown = true; // Accounts for multiple arrival events
Toast.makeText(this, "You have arrived!", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onProgressChange(Location location, RouteProgress routeProgress) {
lastKnownLocation = location;
}
private void startNavigation(DirectionsRoute directionsRoute) {
NavigationViewOptions navigationViewOptions = setupOptions(directionsRoute);
navigationView.startNavigation(navigationViewOptions);
}
private void showDropoffDialog() {
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setMessage(getString(R.string.dropoff_dialog_text));
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, getString(R.string.dropoff_dialog_positive_text),
(dialogInterface, in) -> fetchRoute(getLastKnownLocation(), points.remove(0)));
alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.dropoff_dialog_negative_text),
(dialogInterface, in) -> {
// Do nothing
});
alertDialog.show();
}
private void fetchRoute(Point origin, Point destination) {
NavigationRoute.builder(this)
.accessToken(Mapbox.getAccessToken())
.origin(origin)
.destination(destination)
.alternatives(true)
.build()
.getRoute(new Callback<DirectionsResponse>() {
#Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
DirectionsResponse directionsResponse = response.body();
if (directionsResponse != null && !directionsResponse.routes().isEmpty()) {
startNavigation(directionsResponse.routes().get(0));
}
}
#Override
public void onFailure(Call<DirectionsResponse> call, Throwable t) {
}
});
}
private NavigationViewOptions setupOptions(DirectionsRoute directionsRoute) {
dropoffDialogShown = false;
NavigationViewOptions.Builder options = NavigationViewOptions.builder();
options.directionsRoute(directionsRoute)
.navigationListener(this)
.progressChangeListener(this)
.routeListener(this)
.shouldSimulateRoute(false);
return options.build();
}
private Point getLastKnownLocation() {
return Point.fromLngLat(lastKnownLocation.getLongitude(), lastKnownLocation.getLatitude());
}
}
XML File:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mapbox.services.android.navigation.ui.v5.NavigationView
android:id="#+id/navigationView"
android:layout_width="0dp"
android:layout_height="0dp"
app:navigationLightTheme="#style/NavigationViewLight"
app:navigationDarkTheme="#style/NavigationViewDark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
When I start navigation with multiple waypoints, the navigation stops after reaching first waypoint.
Please suggest changes.`
try{
NavigationRoute.Builder builder = NavigationRoute.builder(this)
.accessToken("pk." + getString(R.string.gh_key))
.baseUrl(getString(R.string.base_url))
.user("gh")
.alternatives(true);
Location lastKnownLocation = new Location(LocationManager.GPS_PROVIDER);
lastKnownLocation.setLatitude(Double.parseDouble(SharePref.getInstance(MapBoxNavActivity.this).getJavaRXPref(getString(R.string.latitude))));
lastKnownLocation.setLongitude(Double.parseDouble(SharePref.getInstance(MapBoxNavActivity.this).getJavaRXPref(getString(R.string.longitude))));
Point location = Point.fromLngLat(lastKnownLocation.getLongitude(), lastKnownLocation.getLatitude());
if (lastKnownLocation.hasBearing()){
// 90 seems to be the default tolerance of the SDK
builder.origin(location, (double) lastKnownLocation.getBearing(), 90.0);
}
else{
builder.origin(location);
}
try {
if(waypoints.size()>0){
for (int i = 0; i < waypoints.size(); i++) {
Point p = waypoints.get(i);
if (i < waypoints.size() - 1) {
try {
builder.addWaypoint(p);
}catch (Exception e){
e.printStackTrace();
}
} else {
builder.destination(p);
}
}
}
}catch (Exception se){
se.printStackTrace();
}
builder.build().getRoute(new SimplifiedCallback() {
#Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
if (validRouteResponse(response)) {
route = response.body().routes().get(0);
try {
MapboxNavigationOptions.Builder navigationOptions = MapboxNavigationOptions.builder();
NavigationViewOptions.Builder options = NavigationViewOptions.builder();
options.navigationListener(MapBoxNavActivity.this);
options.directionsRoute(route);
options.shouldSimulateRoute(false);
options.directionsProfile(DirectionsCriteria.PROFILE_DRIVING_TRAFFIC);
navigationOptions.enableOffRouteDetection(true);
navigationOptions.snapToRoute(true);
options.navigationOptions(navigationOptions.build());
navigationView.startNavigation(options.build());
}catch (Exception e){
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
super.onFailure(call, throwable);
Log.i("Fetch route error",throwable.getMessage());
}
});
}
}
catch ( Exception se){
se.printStackTrace();
}
}
`

WallpaperService keeps music playing in background although app is closed

in my app i want to offer the user a option to set an animation as live wallpaper using WallpaeprService, also my app include a Radio player (playing in the backgroud) if app is open so you can navigate in other apps while music is playing.
my problem :
if live wallpaper is working and user try to close the app by (Swipe to exit / Recent Task),the music keeps playing although app is closed.
i tried to stop music like this ,but doesn't work :
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
#SuppressLint({"CommitPrefEdits", "Assert"})
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, KillNotificationService.class));
trackSelector = new DefaultTrackSelector();
loadControl = new DefaultLoadControl();
exoPlayer = ExoPlayerFactory.newSimpleInstance(new DefaultRenderersFactory(getApplicationContext()), trackSelector, loadControl);
MusicButton.setVisibility(View.INVISIBLE);
MusicButton.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (Build.VERSION.SDK_INT > 15) {
if (started && MusicButton.isChecked()) {
started = false;
exoPlayer.setPlayWhenReady(false);
MusicButton.setChecked(true);
releaseAudioFocusForMyApp(MainActivity.this);
} else {
boolean gotFocus = requestAudioFocusForMyApp(MainActivity.this);
if (gotFocus) {
started = true;
exoPlayer.setPlayWhenReady(true);
MusicButton.setChecked(false);
}
}
} else {
if (started && MusicButton.isChecked()) {
started = false;
mediaPlayer.pause();
MusicButton.setChecked(true);
releaseAudioFocusForMyApp(MainActivity.this);
} else {
boolean gotFocus = requestAudioFocusForMyApp(MainActivity.this);
if (gotFocus) {
started = true;
mediaPlayer.start();
MusicButton.setChecked(false);
}
}
}
}
});
private void playRadio(String url) {
Uri audioUri = Uri.parse(url);
DefaultHttpDataSourceFactory dataSourceFactory = new DefaultHttpDataSourceFactory("ExoPlayerDemo");
ExtractorsFactory extractor = new DefaultExtractorsFactory();
MediaSource audioSource = new ExtractorMediaSource.Factory(dataSourceFactory).setExtractorsFactory(extractor).createMediaSource(audioUri);
exoPlayer.prepare(audioSource);
prepared = true;
exoPlayer.setPlayWhenReady(true);
exoPlayer.addListener(new Player.EventListener() {
#Override
public void onTimelineChanged(Timeline timeline, #Nullable Object manifest, int reason) {
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if (isPreparing && playbackState == ExoPlayer.STATE_READY) {
MusicButton.setVisibility(View.VISIBLE);
MusicButton.setChecked(true);
isPreparing = false;
isReady = true;
}
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
});
}
#Override
protected void onResume() {
super.onResume();
try {
MApplication.sBus.register(this);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onStop() {
super.onStop();
}
#Override
protected void onDestroy() {
super.onDestroy();
try {
MApplication.sBus.unregister(this);
} catch (Exception e) {
e.printStackTrace();
}
MApplication.sBus.post(PlaybackEvent.PAUSE);
}
#Override
protected void onStart() {
super.onStart();
}
#Subscribe
public void handlePlaybackEvent(PlaybackEvent event) {
switch (event) {
case PAUSE:
if (Build.VERSION.SDK_INT > 15) {
if (exoPlayer.getPlayWhenReady()) {
exoPlayer.setPlayWhenReady(false);
MusicButton.setChecked(true);
}
} else {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
MusicButton.setChecked(true);
}
}
break;
case PLAY:
if (Build.VERSION.SDK_INT > 15) {
if (!exoPlayer.getPlayWhenReady()) {
exoPlayer.setPlayWhenReady(true);
MusicButton.setChecked(false);
}
} else {
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
MusicButton.setChecked(false);
}
}
break;
}
}
#Override
public void onPause() {
super.onPause();
}
}
}
problem solved by checking if live wallpaper are running in the backgroud or not:
#Override
protected void onDestroy() {
super.onDestroy();
try {
WallpaperManager wpm = WallpaperManager.getInstance(this);
WallpaperInfo info = wpm.getWallpaperInfo();
if (info != null && info.getPackageName().equals(this.getPackageName())) {
/*stop music*/
} else {
Log.d(TAG, "We're not running");
}
} catch (Exception e) {
e.printStackTrace();
}
}

java.lang.IllegalStateException with MediaPlayerService

When I come back after click the back button and I try to play music I have error 'java.lang.IllegalStateException' - but why..? I noticed that others method like player.isPlaying() or player.reset() didn't work too. If somebody had already this problem - please help. Nice day :)
java.lang.IllegalStateException
at android.media.MediaPlayer.prepareAsync(Native Method)
Activity class:
#Override
protected void onStart() {
super.onStart();
playIntent = new Intent(this, MediaPlayerService.class);
bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
}
#Override
protected void onDestroy() {
super.onDestroy();
if(musicConnection!=null){
unbindService(musicConnection);
}
}
private ServiceConnection musicConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MediaPlayerService.LocalBinder musicBinder = (MediaPlayerService.LocalBinder) service;
musicService = musicBinder.getService();
musicBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
musicBound = false;
}
};
MusicService class:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return iBinder;
}
#Override
public boolean onUnbind(Intent intent) {
player.stop();
player.reset();
player.release();
return false;
}
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
#Override
public void onCreate() {
super.onCreate();
setSong(0);
player = new MediaPlayer();
initMediaPlayer();
}
public void initMediaPlayer(){
player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnPreparedListener(this);
player.setOnCompletionListener(this);
player.setOnErrorListener(this);
}
public void playSong(){
try{
player.reset();
Song playSong = songList.get(songPos);
long currSong = playSong.getId();
Uri trackUri = ContentUris.withAppendedId(
android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
currSong);
player.setDataSource(getApplicationContext(), trackUri);
}catch(Exception e){
Log.e("MUSIC SERVICE", "Error setting data source", e);
}
player.prepareAsync();
}
I had to change the onDestroy method on:
#Override
protected void onDestroy() {
stopService(playIntent);
musicService = null;
super.onDestroy();
}

Android Media Player Null Pointer Exception

I know what a null pointer exception is i have tried using
MediaPlayer mp = new MediaPlayer();
and
public int check()
{
if(mp!=null)
{
return 1;
}
else
{
return 2;
}
}
doesn't helps.
This is the error im getting-
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.openaisearch.www.musicplayer/com.openaisearch.www.musicplayer.MainActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method
'boolean com.openaisearch.www.musicplayer.Music.check()' on a null
object reference
public class MainActivity extends AppCompatActivity {
ArrayList<String> mSongsList = new ArrayList<>() ;
ArrayList<Long> SongsPath = new ArrayList<>() ;
Button btnPlay;
Music mService;
SeekBar seekBar;
ListView lv;
boolean mBound = false;
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
Music.LocalBinder binder = (Music.LocalBinder) service;
mService = binder.getService();
mBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, Music.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
startService(intent);
btnPlay = (Button) findViewById(R.id.buttonPlay);
seekBar = (SeekBar) findViewById(R.id.seekBar);
lv = (ListView) findViewById(R.id.list);
getAudioList();
ArrayAdapter arrayAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,mSongsList);
lv.setAdapter(arrayAdapter);
onSongClick();
setSeekBar();
check();
}
#Override
protected void onStop() {
super.onStop();
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
public void getAudioList() {
String orderBy = MediaStore.Audio.Media.TITLE ;
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
Cursor mCursor = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media._ID }, selection, null, orderBy);
int count = mCursor.getCount();
while (mCursor.moveToNext()) {
mSongsList.add(mCursor.getString(mCursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)));
SongsPath.add(mCursor.getLong(mCursor
.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)));
}
mCursor.close();
}
public void onSongClick()
{
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mService.playSong(SongsPath.get(position));
if(btnPlay.getText() == "Play")
{
btnPlay.setText("Pause");
}
}
});
}
public void onButtonClick(View view) {
int a = mService.stopMusic();
if(a == 1)
{
btnPlay.setText("Play");
}
else if (a ==2)
{
btnPlay.setText("Pause");
}
}
public void check()
{
boolean check = mService.check();
}
public void setSeekBar()
{
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser )
{
mService.setProg(progress*1000);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
Service-
public class Music extends Service {
Long b;
MediaPlayer mp;
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
Music getService() {
return Music.this;
}
}
public void playSong(Long a) {
if (a!= b)
{ if(mp!=null)
{
mp.stop();
mp.release();
mp=null;
}
b =a;
Uri contentUri = ContentUris.withAppendedId(
android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, a);
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mp.setDataSource(getApplicationContext(), contentUri);
mp.prepare();
mp.setLooping(true);
mp.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public int stopMusic()
{
if(mp.isPlaying())
{
mp.pause();
return 1;
}
else if (mp!=null)
{
mp.start();
return 2;
}
else
{
return 0;
}
}
public void setProg(int a)
{ if(mp!=null)
{
mp.seekTo(a);
}
}
public boolean check()
{
if(mp!=null)
{
return true;
}
else
{
return false;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
You are not checking if the service has been connected to the activity or not using mbound in ur function.
public void check()
{
i f(mBound)
{
boolean check = mService.check();
}
}
You're probably getting the NPE from this line: boolean check = mService.check(); So it's mService that is null, not mp
I think you trying to bind service that is not started yet. Try to call startService(intent); before bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
Your service class should follow this format; overwrite the onCreate() method
you are getting NPE because mService is null in line: mService.check();
public class MyService extends Service {
private Binder binder;
#Override
public void onCreate() {
super.onCreate();
binder = new Binder();
}
#Override
public IBinder onBind(Intent intent) {
return binder;
}
public class Binder extends android.os.Binder {
public MyService getService() {
return MyService.this; // return instance
}
}
}

Categories