Permalänk
Medlem

Android Mp3Player Service

Tjenare.

Jag håller på att implementera en mediaspelare för android och har stött på ett problem som jag inte lyckats lösa.
Jag har lyckats med att "binda" min service till min main activity. Men sedan har jag tänkt att man ska kunna visa en playlist
om man trycker på en meny knapp. Detta är inga problem utan playlist activity startas utan problem. Playlist består av en Listactivity
och tanken är att när man trycker på ett item så skickar man positionen tillbaka till huvud aktiviteten men här kraschar programmet.

Felmeddelande när applikationen kraschar:
01-08 21:06:07.385: E/AndroidRuntime(638): java.lang.RuntimeException: Unable to resume activity {com.lab2.assignment2/com.lab2.Mp3Player.Mp3Main}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { cmp=com.lab2.assignment2/com.lab2.Mp3Player.Mp3Main (has extras) }} to activity {com.lab2.assignment2/com.lab2.Mp3Player.Mp3Main}: java.lang.NullPointerException

http://i.imgur.com/dFNNN.png

Det jag funderar på är om jag ska skicka informationen direkt till min service, eller om jag behöver använda en broadcast receiver i Mp3Main
där jag tar emot trackIndex i onResume().

Ett annat problem som ibland uppstår är: "Has leaked service connection that was originally bound here".
Någon som vet vad detta kan beror på? uppstår när man försöker öppna applikationen efter att ha stängt den även fast musiken spelar vidare.

Tacksam för hjälp.

TracksList.java:

package com.lab2.Mp3Player; import com.lab2.assignment2.R; import java.util.ArrayList; import java.util.HashMap; import android.app.ActionBar; import android.app.Activity; import android.app.ListActivity; import android.content.Intent; import android.os.Bundle; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.SimpleAdapter; public class TracksList extends ListActivity{ public ArrayList<HashMap<String, String>> tracks = new ArrayList<HashMap<String, String>>(); @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.trackslist); ActionBar ab = getActionBar(); ab.setDisplayHomeAsUpEnabled(true); ArrayList<HashMap<String, String>> tracksInfo = new ArrayList<HashMap<String, String>>(); FetchMedia ftm = new FetchMedia(); this.tracks = ftm.getTracks(); // Fetching media from SD-card for(int i=0; i < tracks.size(); i++){ HashMap<String, String> track = tracks.get(i); tracksInfo.add(track); } ListAdapter adapter = new SimpleAdapter(this, tracksInfo, R.layout.trackslist_item, new String [] {"title"}, new int [] {R.id.trackTitle}); setListAdapter(adapter); ListView lv = getListView(); lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub int trackIndex = position; Intent it = new Intent(getApplicationContext(), Mp3Main.class); it.putExtra("trackIndex", trackIndex); setResult(Activity.RESULT_OK, it); finish(); } }); } @Override public boolean onOptionsItemSelected(MenuItem item) { // TODO Auto-generated method stub //return super.onOptionsItemSelected(item); switch(item.getItemId()){ case android.R.id.home: Intent it = new Intent(this, Mp3Main.class); it.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(it); finish(); return true; default: return super.onOptionsItemSelected(item); } } }

Dold text

Delar av Mp3Main.java:

private Mp3Service srv = null; @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.mp3main); Intent it = new Intent(main, Mp3Service.class); main.bindService(it, Mp3Connection, Context.BIND_AUTO_CREATE); .... .... .... } @Override public boolean onCreateOptionsMenu(Menu menu){ // TODO Auto-generated method stub getActionBar().setDisplayHomeAsUpEnabled(true); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.mp3_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // TODO Auto-generated method stub //return super.onOptionsItemSelected(item); Intent it; switch(item.getItemId()){ case R.id.playlist: it = new Intent(this, TracksList.class); startActivityForResult(it, 0); playlist = true; return true; case android.R.id.home: it = new Intent(this, com.lab2.MainList.MainList.class); it.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(it); return true; default: return super.onOptionsItemSelected(item); } } private void playTrack(int index) { // TODO Auto-generated method stub try { srv.playTrack(index); String track_title = srv.tracks.get(index).get("title"); title.setText(track_title); play.setImageResource(R.drawable.img_btn_pause); progressbar.setProgress(0); progressbar.setMax(100); updateProgressBar(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e){ e.printStackTrace(); } } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); // Push and Pop an empty notification ShowDummyNotification(); nf.cancel(ID); } @Override public void onBackPressed() { // TODO Auto-generated method stub super.onBackPressed(); onClose(); } @Override protected void onStop() { // TODO Auto-generated method stub super.onStop(); if(!close) showInfoNotification(); if(bound){ unbindService(Mp3Connection); bound = false; } } private void onClose() { // TODO Auto-generated method stub Mp3Service.shuffleTrack = false; Mp3Service.repeatTrack = false; Mp3Service.trackIndex = 0; close = true; srv.Stop(); finish(); } private ServiceConnection Mp3Connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub srv = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub srv = ((Mp3Service.myBinder)service).getService(); bound = true; } }; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); if(resultCode == RESULT_OK){ Mp3Service.trackIndex = data.getIntExtra("trackIndex", 0); playTrack(Mp3Service.trackIndex); playlist = false; } }

Dold text

Mp3Service:

package com.lab2.Mp3Player; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Random; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.os.Binder; import android.os.IBinder; public class Mp3Service extends Service{ private final IBinder myBinder = new myBinder(); public ArrayList<HashMap<String, String>> tracks = new ArrayList<HashMap<String, String>>(); public static int trackIndex = 0; public static boolean shuffleTrack = false; public static boolean repeatTrack = false; private FetchMedia ftm; public static MediaPlayer mp; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return myBinder; } public class myBinder extends Binder{ Mp3Service getService(){ return Mp3Service.this; } } @Override public void onCreate(){ // TODO Auto-generated method stub ftm = new FetchMedia(); tracks = ftm.getTracks(); Thread tr = new Thread(null, run, "Mp3Service"); tr.start(); } @Override public void onDestroy() { // TODO Auto-generated method stub // super.onDestroy(); // Nothing to do here.. } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub return Service.START_NOT_STICKY; } Runnable run = new Runnable(){ @Override public void run() { // TODO Auto-generated method stub mp = new MediaPlayer(); try{ mp.setOnCompletionListener(new OnCompletionListener() { /* Method called when track ends * to play next track. */ @Override public void onCompletion(MediaPlayer mp) { // TODO Auto-generated method stub if(repeatTrack) playTrack(trackIndex); else if(shuffleTrack){ Random rand = new Random(); trackIndex = rand.nextInt(tracks.size() - 1); playTrack(trackIndex); } else{ // no repeat or shuffle ON - play next song if(trackIndex < (tracks.size() - 1)){ playTrack(trackIndex + 1); trackIndex += 1; }else{ // play first song playTrack(0); trackIndex = 0; } } } }); } catch(Exception e){ } } }; public boolean isPlaying(){ return mp.isPlaying(); } public boolean shuffle(){ return shuffleTrack; } public boolean repeat(){ return repeatTrack; } public void pause(){ mp.pause(); } public void start(){ mp.start(); } public void seekTo(int progress){ mp.seekTo(progress); } public int getDuration(){ return mp.getDuration(); } public int getPosition(){ return mp.getCurrentPosition(); } public void Stop(){ mp.stop(); this.stopSelf(); } public void playTrack(int index){ try{ mp.reset(); mp.setDataSource(tracks.get(index).get("path")); mp.prepare(); mp.start(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e){ e.printStackTrace(); } catch (IOException e){ e.printStackTrace(); } } }

Dold text
Visa signatur

"This is VAR, spelled A-U-T-O"

Permalänk
Medlem

NullPointerException på rad 264 i Mp3Main

Skickades från m.sweclockers.com

Permalänk
Medlem
Skrivet av drewi:

NullPointerException på rad 264 i Mp3Main

Skickades från m.sweclockers.com

Ja det är jag väldigt medveten om, rad 264 är i onActivityResult i Mp3Main.
Problemet är att den data jag skickar från Playlist inte är null.

Så problemet som jag har förstått det är att jag inte kan Resuma Mp3Main men vet inte varför.
Någon som vet om man måste använda broadcast receiver?

Visa signatur

"This is VAR, spelled A-U-T-O"

Permalänk
Medlem
Skrivet av Kreppe:

Ja det är jag väldigt medveten om, rad 264 är i onActivityResult i Mp3Main.
Problemet är att den data jag skickar från Playlist inte är null.

Så problemet som jag har förstått det är att jag inte kan Resuma Mp3Main men vet inte varför.
Någon som vet om man måste använda broadcast receiver?

Nej rad 264 är raden "srv.playTrack(index);" i playTrack(), alltså är felet att srv är null.

onActivityResult() är på rad 337-345

Permalänk
Medlem
Skrivet av drewi:

Nej rad 264 är raden "srv.playTrack(index);" i playTrack(), alltså är felet att srv är null.

onActivityResult() är på rad 337-345

Ja du hade faktiskt rätt där Tack så hemskt mycket för det. Ett problem löst.
Det visade sig att den Int som retuneras inte är null som tidigare

Alltså är problemet något med att jag inte kan Resumera Mp3Main.
Några idéer om detta? kan posta allt ifall det är så.

Tack på förhand.

Visa signatur

"This is VAR, spelled A-U-T-O"

Permalänk
Medlem

Löste problemet med onResume vilket gjorde att hela programmet fungerade
Det var en flagga som var fel: it.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
vilket gjorde att aktiviteten poppades från stacken.

tack för hjälpen.

Visa signatur

"This is VAR, spelled A-U-T-O"