1

這是我第一次發佈在stackoverflow上,所以請裸照我。(Android)無法使用MusicService在片段中播放音樂

我有一個片段,它給了我存儲在手機上的所有歌曲的listView。當我點擊列表中的特定歌曲時,我應該可以使用MusicService播放它。

當選擇特定的抽屜項目時,此片段(menu2_Fragment)在ActionBarActivity中初始化。請參見下面的代碼:

@Override 
public void onNavigationDrawerItemSelected(int position) { 
    Fragment objFragment = null; 

    switch(position){ 
     case 0: 
      objFragment = new menu1_Fragment(); 
      getSupportActionBar().setTitle("Scan for Users"); 
      break; 
     case 1: 
      objFragment = new menu2_Fragment(); 
      getSupportActionBar().setTitle("Your Music"); 
      // objFragment = new MyMusicFragment(); 
      break; 
     case 2: 
      objFragment = new menu3_Fragment(); 
      getSupportActionBar().setTitle("Popular Music"); 
    } 

    // update the main content by replacing fragments 
    FragmentManager fragmentManager = getSupportFragmentManager(); 
    fragmentManager.beginTransaction() 
      .replace(R.id.container, objFragment) 
      .commit(); 
} 

這是片段代碼:

package com.example.cs446.soundscope; 

import android.content.ComponentName; 
import android.content.ContentResolver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.ServiceConnection; 
import android.database.Cursor; 
import android.net.Uri; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.support.annotation.Nullable; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ListView; 
import android.widget.MediaController; 

import com.example.cs446.soundscope.Adapter.SongAdapter; 
import com.example.cs446.soundscope.data.Song; 

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.Comparator; 

/** 
* Created by val on 27/02/15. 
*/ 
public class menu2_Fragment extends Fragment implements MediaController.MediaPlayerControl{ 
    View rootview; 
    private ArrayList<Song> songList; 
    private ListView songView; 

private MusicService musicSrv; 
private Intent playIntent; 
private boolean musicBound=false; 
private MusicController controller; 

private boolean paused=false; 
private boolean playbackPaused=false; 

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ 
    rootview = inflater.inflate(R.layout.activity_main,container, false); 

    songView = (ListView)rootview.findViewById(R.id.song_list); 
    songList = new ArrayList<Song>(); 
    getSongList(); 

    //sort all of the songList by title 
    Collections.sort(songList, new Comparator<Song>() { 

     //function that does the sorting 
     @Override 
     public int compare(Song lhs, Song rhs) { 
      return lhs.getTitle().compareTo(rhs.getTitle()); 
     } 
    }); 

    SongAdapter songAdt = new SongAdapter(getActivity(),songList); 
    songView.setAdapter(songAdt); 
    setController(); 

    //startActivity(new Intent(this, MainActivity.class)); 
    return rootview; 
} 

//get the song information for your filesystem 
public void getSongList(){ 
    //use the contentResolver to retrieve the uri for the music file 
    //a cursor instance is created with the contentResolver 
    ContentResolver musicResolver = this.getActivity().getContentResolver(); 
    Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 
    Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null); 

    //store the songs into the song list array list 
    if(musicCursor!=null && musicCursor.moveToFirst()){ 
     //get columns 
     int titleColumn = musicCursor.getColumnIndex 
       (android.provider.MediaStore.Audio.Media.TITLE); 
     int idColumn = musicCursor.getColumnIndex 
       (android.provider.MediaStore.Audio.Media._ID); 
     int artistColumn = musicCursor.getColumnIndex 
       (android.provider.MediaStore.Audio.Media.ARTIST); 
     //add songs to list 
     do { 
      long thisId = musicCursor.getLong(idColumn); 
      String thisTitle = musicCursor.getString(titleColumn); 
      String thisArtist = musicCursor.getString(artistColumn); 
      songList.add(new Song(thisId, thisTitle, thisArtist)); 
     } 
     while (musicCursor.moveToNext()); 
    } 

} 

public void songPicked(View view){ 
    musicSrv.setSong(Integer.parseInt(view.getTag().toString())); 
    musicSrv.playSong(); 
    if(playbackPaused){ 
     setController(); 
     playbackPaused=false; 
    } 
    controller.show(0); 
} 

//set the controller up 
private void setController(){ 
    controller = new MusicController(getActivity()); 

    controller.setPrevNextListeners(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      playNext(); 
     } 
    }, new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      playPrev(); 
     } 
    }); 

    controller.setMediaPlayer(this); 
    controller.setAnchorView(getActivity().findViewById(R.id.song_list)); 
    controller.setEnabled(true); 
} 

@Override 
public void onStart() { 
    super.onStart(); 
    if(playIntent==null){ 
     playIntent = new Intent(getActivity(), MusicService.class); 
     this.getActivity().bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE); 
     this.getActivity().startService(playIntent); 
    } 
} 

@Override 
public void onPause(){ 
    super.onPause(); 
    paused=true; 
} 

@Override 
public void onResume(){ 
    super.onResume(); 
    if(paused){ 
     setController(); 
     paused=false; 
    } 
} 

@Override 
public void onStop() { 
    controller.hide(); 
    super.onStop(); 
} 

//connect to the service 
private ServiceConnection musicConnection = new ServiceConnection(){ 

    @Override 
    public void onServiceConnected(ComponentName name, IBinder service) { 
     MusicService.MusicBinder binder = (MusicService.MusicBinder)service; 
     //get service 
     musicSrv = binder.getService(); 
     //pass list 
     musicSrv.setList(songList); 
     musicBound = true; 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName name) { 
     musicBound = false; 
    } 
}; 

//play next 
private void playNext(){ 
    musicSrv.playNext(); 
    if(playbackPaused){ 
     setController(); 
     playbackPaused=false; 
    } 
    controller.show(0); 
} 

//play previous 
private void playPrev(){ 
    musicSrv.playPrev(); 
    if(playbackPaused){ 
     setController(); 
     playbackPaused=false; 
    } 
    controller.show(0); 
} 

@Override 
public void onDestroy() { 
    this.getActivity().stopService(playIntent); 
    musicSrv=null; 
    super.onDestroy(); 
} 

@Override 
public void start() { 
    musicSrv.go(); 
} 

@Override 
public void pause() { 
    playbackPaused=true; 
    musicSrv.pausePlayer(); 
} 

@Override 
public int getDuration() { 
    if(musicSrv!=null && musicBound && musicSrv.isPng()) 
     return musicSrv.getDur(); 
    else return 0; 
} 

@Override 
public int getCurrentPosition() { 
    if(musicSrv!=null && musicBound && musicSrv.isPng()) 
     return musicSrv.getPosn(); 
    else return 0; 
} 

@Override 
public void seekTo(int pos) { 
    musicSrv.seek(pos); 
} 

@Override 
public boolean isPlaying() { 
    if(musicSrv!=null && musicBound) 
     return musicSrv.isPng(); 
    return false; 
} 

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

}

當我在ListView一個項目點擊,而不是播放的歌曲我的應用程序崩潰,我收到以下錯誤信息:

03-02 00:46:29.142 6485-6485/com.example.cs446.soundscope E/AndroidRuntime﹕ FATAL EXCEPTION: main 
    Process: com.example.cs446.soundscope, PID: 6485 
    java.lang.IllegalStateException: Could not find a method songPicked(View) in the activity class com.example.cs446.soundscope.ListNearbyUsers for onClick handler on view class android.widget.LinearLayout 
      at android.view.View$1.onClick(View.java:3994) 
      at android.view.View.performClick(View.java:4756) 
      at android.view.View$PerformClick.run(View.java:19749) 
      at android.os.Handler.handleCallback(Handler.java:739) 
      at android.os.Handler.dispatchMessage(Handler.java:95) 
      at android.os.Looper.loop(Looper.java:135) 
      at android.app.ActivityThread.main(ActivityThread.java:5221) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:372) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 
    Caused by: java.lang.NoSuchMethodException: songPicked [class android.view.View] 
      at java.lang.Class.getMethod(Class.java:664) 
      at java.lang.Class.getMethod(Class.java:643) 
      at android.view.View$1.onClick(View.java:3987) 
            at android.view.View.performClick(View.java:4756) 
            at android.view.View$PerformClick.run(View.java:19749) 
            at android.os.Handler.handleCallback(Handler.java:739) 
            at android.os.Handler.dispatchMessage(Handler.java:95) 
            at android.os.Looper.loop(Looper.java:135) 
            at android.app.ActivityThread.main(ActivityThread.java:5221) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at java.lang.reflect.Method.invoke(Method.java:372) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 

當播放音樂功能正常工作時沒有在Fragment中實現,而是在Activity中實現。有沒有人看到過這樣的錯誤?如果是這樣,我會很感激一些指導。

對於術語中的任何誤用我表示歉意我最近開始學習android開發。

回答

1

這意味着您沒有在碎片佈局中聲明andoid:onClick="songPicked"。 我知道你是從tutsplus :)