无法在Fragment中使用MusicService播放音乐

时间:2015-03-02 06:31:37

标签: android-activity android-fragments android-listview illegalstateexception mediacontroller

我有一个片段,它为我提供了存储在手机上的所有歌曲的列表视图。当我点击列表中的特定歌曲时,我应该可以使用MusicService播放它。

当选择特定的抽屉项目时,在ActionBarActivity中初始化此片段(menu2_Fragment)。请参阅以下代码:

@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)

播放音乐功能在片段内部未实现时可正常工作,而是在Activity内部实现。有没有人见过这样的错误?

1 个答案:

答案 0 :(得分:1)

这意味着您没有在片段布局中声明andoid:onClick="songPicked"。 而且我知道你是来自tutsplus :)。