我是Android的新手,我正在开发一款游戏应用程序,我想在后台播放音乐,音乐必须在所有活动中播放。另外,我正在从用户的设备中获取歌曲并将它们呈现在ListView中。用户在ListMusic活动中选择一首歌,然后他继续其他活动和我的目的是音乐将在后台继续。
我希望你理解这个过程,我也加入了JAVA。
现在,我遇到了这个错误:
活动com.example.summerproject.FirstActivity已泄露最初绑定的ServiceConnection com.example.summerproject.ListMusic$1@42116d20
从我的理解,问题是我不是UnBind每个活动的onDestroy()上的连接。有人知道如何解决它吗?我希望音乐能够在所有活动中继续进行,因此每次取消绑定服务可能会出现问题。
MusicService:
public class MusicService extends Service implements
MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener,
MediaPlayer.OnCompletionListener
{
private MediaPlayer player; //media player
private ArrayList<Song> valuesList; //songs List
private int songPosn; //current position
private final IBinder musicBind = new MusicBinder();
public void onCreate()
{
super.onCreate();
songPosn=0;
player= new MediaPlayer();
initMusicPlayer();
player.setOnPreparedListener(this);
player.setOnCompletionListener(this);
player.setOnErrorListener(this);
}
@Override
public IBinder onBind(Intent intent)
{
//בעת התחברות
return musicBind;
}
@Override
public boolean onUnbind(Intent intent)
{
player.stop();
player.release();
return false;
}
public void initMusicPlayer()
{
//set player properties
player.setWakeMode(getApplicationContext(),
PowerManager.PARTIAL_WAKE_LOCK);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
public void playSong()
{
if(player != null) //אם נוצר כבר
player.reset();
Song songToPlay = valuesList.get(songPosn);
long songId = songToPlay.getId();
Uri trackUri = ContentUris.withAppendedId(
android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
songId);
try{
player.setDataSource(getApplicationContext(), trackUri);
}
catch(Exception e)
{
Log.e("MUSIC SERVICE", "Error setting data source", e);
}
player.setLooping(true);
player.prepareAsync();
}
public void setList(ArrayList<Song> theSongs){
valuesList=theSongs;
}
public class MusicBinder extends Binder
{
MusicService getService()
{
return MusicService.this;
}
}
public void setSong(int songIndex)
{
songPosn=songIndex;
}
@Override
public void onPrepared(MediaPlayer mp)
{
// TODO Auto-generated method stub
mp.start();
}
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// TODO Auto-generated method stub
return false;
}
}
ListActivity(用户从此处选择歌曲):
public class ListMusic extends Activity implements OnItemClickListener
{
private static ArrayList<Song> valuesList;
private ListView list;
private MySongsAdapter songAdt;
private static MusicService MusicService;
private Intent playIntent;
private static boolean musicBound=false;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music);
list = (ListView)findViewById(R.id.song_list);
valuesList = new ArrayList<Song>();
getSongList(); //update the valuesList
songAdt = new MySongsAdapter(this, valuesList);
list.setAdapter(songAdt);
list.setOnItemClickListener(this);
}
//connect to the service
public static ServiceConnection musicConnection= new ServiceConnection()
{
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
MusicBinder binder = (MusicBinder)service;
//get service
MusicService = binder.getService();
// Toast.makeText(getApplicationContext(), "Music Service Is Not Null", Toast.LENGTH_LONG).show();
//pass list
MusicService.setList(valuesList);
musicBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
musicBound = false;
}
};
@Override
protected void onStart()
{
//
super.onStart();
Toast.makeText(getApplicationContext(), "Start", Toast.LENGTH_LONG).show();
if(playIntent ==null)
{
playIntent = new Intent(this, MusicService.class);
bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
}
}
public void songPicked(View view, int position)
{
//כאשר שיר נבחר
MusicService.setSong(position);
MusicService.playSong();
}
public void getSongList()
{
//אחזור רשימת השירים מהמכשיר
ContentResolver musicResolver = getContentResolver();
Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);
long thisId;
int titleColumn, idColumn, artistColumn;
String thisTitle, thisArtist;
if(musicCursor!=null && musicCursor.moveToFirst())
{
//get columns
titleColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.TITLE);
idColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media._ID);
artistColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.ARTIST);
//add songs to list
while (musicCursor.moveToNext())
{
thisId = musicCursor.getLong(idColumn);
thisTitle = musicCursor.getString(titleColumn);
thisArtist = musicCursor.getString(artistColumn);
valuesList.add(new Song(thisId, thisTitle, thisArtist));
}
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id)
{
//באירוע של לחיצה על שיר
songPicked(view, position);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.music, menu);
return true;
}
@Override
public boolean onOptionsItemSelected (MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id= item.getItemId();
switch(id)
{
case R.id.btnExit:
stopService(playIntent);
MusicService=null;
finish();
break;
}
return true;
}
与MainActivity的连接:
playIntent = new Intent(this, MusicService.class);
bindService(playIntent, ListMusic.musicConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
拜托,如果有人知道这是什么问题,我将不胜感激! 谢谢你的到来。
答案 0 :(得分:0)
我希望音乐能够在所有活动中继续进行,因此每次取消绑定服务可能会出现问题。
这只是一个问题,因为你这样做
@Override
public boolean onUnbind(Intent intent)
{
player.stop();
player.release();
return false;
}
现在,每次调用unbindService()
时,音乐都会停止。可以在活动的unbindService()
或onDestroy()
中调用onPause()
,但是您不应该停止播放服务中的onUnbind()
方法。< / p>
您可以为服务提供一个公共静态方法,当您需要停止音乐时,可以调用该方法:
@Override
public boolean onUnbind(Intent intent)
{
return false;
}
public static void stopPlayMusic()
{
player.stop();
player.release();
}
通过这种方式,即使某些内容与您的服务无关,音乐也会继续播放,同时还有一种方法可以停止播放音乐。为了使这项工作,您还必须使player
成为静态变量。