通知中的音乐控制

时间:2016-11-15 12:53:56

标签: android android-notifications

按照[本教程](http://www.tutorialsface.com/2015/08/android-custom-notification-tutorial),我最终得到了通知中显示的控件,但都没有响应(除了显示作者所包含的Toasts)。

控件似乎不会以任何方式绑定到音乐服务。我尝试创建广播,直接从通知中调用服务,创建服务的新实例。我已经尝试了很多我甚至不能记住它们的东西。我见过人们问过类似的问题,但我没有尝试过任何工作。现在,我已经尝试了很多这样的事情,以至于我对自己认为自己走在正确道路上的时间/地点感到困惑。关于如何使这些控件正常运行的任何想法?

通知服务:

public class NotificationService extends Service {


@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}


@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {


    if (intent.getAction().equals(Constant.ACTION.STARTFOREGROUND_ACTION)) {
        showNotification();
        Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();



    } else if (intent.getAction().equals(Constant.ACTION.PREV_ACTION)) {
        Toast.makeText(this, "Clicked Previous", Toast.LENGTH_SHORT).show();
        Log.i("NS", "Clicked Previous");



    } else if (intent.getAction().equals(Constant.ACTION.PLAY_ACTION)) {



        Log.i("NS", "Clicked Play");
    } else if (intent.getAction().equals(Constant.ACTION.NEXT_ACTION)) {





        Toast.makeText(this, "Clicked Next", Toast.LENGTH_SHORT).show();
        Log.i("NS", "Clicked Next");
    } else if (intent.getAction().equals(
            Constant.ACTION.STOPFOREGROUND_ACTION)) {
        Log.i("NS", "Received Stop Foreground Intent");
        Toast.makeText(this, "Service Stoped", Toast.LENGTH_SHORT).show();
        stopForeground(true);
        stopSelf();
    }
    return START_STICKY;
}

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public void showNotification() {

    Notification status;

// Using RemoteViews to bind custom layouts into Notification
        RemoteViews views = new RemoteViews(getPackageName(),
                R.layout.status_bar);
        RemoteViews bigViews = new RemoteViews(getPackageName(),
                R.layout.status_bar_expanded);

// showing default album image
        views.setViewVisibility(R.id.status_bar_icon, View.VISIBLE);
        views.setViewVisibility(R.id.status_bar_album_art, View.GONE);
        bigViews.setImageViewBitmap(R.id.status_bar_album_art,
                Constant.getDefaultAlbumArt(this));

        Intent notificationIntent = new Intent(this, NotificationService.class);
        notificationIntent.setAction(Constant.ACTION.MAIN_ACTION);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                notificationIntent, 0);

        Intent previousIntent = new Intent(this, NotificationService.class);
        previousIntent.setAction(Constant.ACTION.PREV_ACTION);
        PendingIntent ppreviousIntent = PendingIntent.getService(this, 0,
                previousIntent, 0);

        Intent playIntent = new Intent(this, NotificationService.class);
        playIntent.setAction(Constant.ACTION.PLAY_ACTION);
        PendingIntent pplayIntent = PendingIntent.getService(this, 0,
                playIntent, 0);

        Intent nextIntent = new Intent(this, NotificationService.class);
        nextIntent.setAction(Constant.ACTION.NEXT_ACTION);
        PendingIntent pnextIntent = PendingIntent.getService(this, 0,
                nextIntent, 0);

        Intent closeIntent = new Intent(this, NotificationService.class);
        closeIntent.setAction(Constant.ACTION.STOPFOREGROUND_ACTION);
        PendingIntent pcloseIntent = PendingIntent.getService(this, 0,
                closeIntent, 0);

        views.setOnClickPendingIntent(R.id.status_bar_play, pplayIntent);
        bigViews.setOnClickPendingIntent(R.id.status_bar_play, pplayIntent);

        views.setOnClickPendingIntent(R.id.status_bar_next, pnextIntent);
        bigViews.setOnClickPendingIntent(R.id.status_bar_next, pnextIntent);

        views.setOnClickPendingIntent(R.id.status_bar_prev, ppreviousIntent);
        bigViews.setOnClickPendingIntent(R.id.status_bar_prev, ppreviousIntent);

        views.setOnClickPendingIntent(R.id.status_bar_collapse, pcloseIntent);
        bigViews.setOnClickPendingIntent(R.id.status_bar_collapse, pcloseIntent);

        views.setImageViewResource(R.id.status_bar_play,
                R.drawable.apollo_holo_dark_pause);
        bigViews.setImageViewResource(R.id.status_bar_play,
                R.drawable.apollo_holo_dark_pause);

        views.setTextViewText(R.id.status_bar_track_name, "Song Title");
        bigViews.setTextViewText(R.id.status_bar_track_name, "Song Title");

        views.setTextViewText(R.id.status_bar_artist_name, "Artist Name");
        bigViews.setTextViewText(R.id.status_bar_artist_name, "Artist Name");

        bigViews.setTextViewText(R.id.status_bar_album_name, "Album Name");

        status = new Notification.Builder(this).build();
        status.contentView = views;
        status.bigContentView = bigViews;
        status.flags = Notification.FLAG_ONGOING_EVENT;
        status.icon = R.drawable.ic_launcher;
        status.contentIntent = pendingIntent;
        startForeground(Constant.NOTIFICATION_ID.FOREGROUND_SERVICE, status);
    }

}

MusicService:

public class MusicService extends Service implements
    MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener,
    MediaPlayer.OnCompletionListener {

//media player
private MediaPlayer player;
//song list
private ArrayList<Song> songs;
//current position
private int songPosn;
private final IBinder musicBind = new MusicBinder();
private String songTitle="";
private static final int NOTIFY_ID=1;
private boolean shuffle=false;
private Random rand;

public void onCreate(){
    //create the service
    super.onCreate();
    songPosn=0;
    player = new MediaPlayer();

    initMusicPlayer();

    rand=new Random();
}

public void initMusicPlayer(){
    //set player properties
    player.setWakeMode(getApplicationContext(),
            PowerManager.PARTIAL_WAKE_LOCK);
    player.setAudioStreamType(AudioManager.STREAM_MUSIC);

    player.setOnPreparedListener(this);
    player.setOnCompletionListener(this);
    player.setOnErrorListener(this);
}

public void setList(ArrayList<Song> theSongs){
    songs=theSongs;
}

public class MusicBinder extends Binder {
    MusicService getService() {
        return MusicService.this;
    }
}

public void setShuffle(){
    if(shuffle) shuffle=false;
    else shuffle=true;
}

public void playSong(){
    player.reset();
    //get song
    Song playSong = songs.get(songPosn);

//get id
    long currSong = playSong.getID();
//set uri
    Uri trackUri = ContentUris.withAppendedId(
            android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            currSong);

    try{
        player.setDataSource(getApplicationContext(), trackUri);
    }
    catch(Exception e){
        Log.e("MUSIC SERVICE", "Error setting data source", e);
    }

    player.prepareAsync();

    songTitle=playSong.getTitle();
}

public void setSong(int songIndex){
    songPosn=songIndex;
}

public int getPosn(){
    return player.getCurrentPosition();
}

public int getDur(){
    return player.getDuration();
}

public boolean isPng(){
    return player.isPlaying();
}

public void pausePlayer(){
    player.pause();
}

public void seek(int posn){
    player.seekTo(posn);
}

public void go(){
    player.start();
}

public void playPrev(){
    songPosn--;
    if(songPosn<0) songPosn=songs.size()-1;
    playSong();
}

//skip to next
public void playNext(){
    if(shuffle){
        int newSong = songPosn;
        while(newSong==songPosn){
            newSong=rand.nextInt(songs.size());
        }
        songPosn=newSong;
    }
    else{
        songPosn++;
        if(songPosn>=songs.size()) songPosn=0;
    }
    playSong();
}
@Override
public void onDestroy() {
    stopForeground(true);
}

@Override
public IBinder onBind(Intent intent) {
    return musicBind;
}

@Override
public boolean onUnbind(Intent intent){
    player.stop();
    player.release();
    return false;
}

@Override
public void onCompletion(MediaPlayer mp) {
    if(player.getCurrentPosition()>0){
        mp.reset();
        playNext();
    }
}

@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
    mp.reset();
    return false;
}

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onPrepared(MediaPlayer mp) {
    //start playback
    mp.start();

    Intent onPreparedIntent = new Intent("MEDIA_PLAYER_PREPARED");
    LocalBroadcastManager.getInstance(this).sendBroadcast(onPreparedIntent);


    Intent notIntent = new Intent(this, MusicPlayer.class);
    notIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendInt = PendingIntent.getActivity(this, 0,
            notIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    Notification.Builder builder = new Notification.Builder(this);

    builder.setContentIntent(pendInt)
            .setSmallIcon(R.drawable.player_play)
            .setTicker(songTitle)
            .setOngoing(true)
            .setContentTitle("Playing")
    .setContentText(songTitle);
    Notification not = builder.build();

    Intent serviceIntent = new Intent(MusicService.this, NotificationService.class);
    serviceIntent.setAction(Constant.ACTION.STARTFOREGROUND_ACTION);
    startService(serviceIntent);
}
}

音乐播放器:

public class MusicPlayer extends AppCompatActivity implements MediaPlayerControl {

private ArrayList<Song> songList;
private ListView songView;
public MusicService musicSrv;
private Intent playIntent;
private boolean musicBound=false;
private MusicController controller;
private boolean paused=false, playbackPaused=false;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_music_player);


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

    getSongList();

    Collections.sort(songList, new Comparator<Song>(){
        public int compare(Song a, Song b){
            return a.getArtist().compareTo(b.getArtist());
        }
    });

    songAdapter songAdt = new songAdapter(this, songList);
    songView.setAdapter(songAdt);

    setController();

    FloatingActionButton fabRandom = (FloatingActionButton)findViewById(R.id.fabRandom);
    fabRandom.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

        }
    });

}

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

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

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

protected void onPause(){
    super.onPause();
    paused=true;
}

@Override
protected void onResume(){
    super.onResume();

    // Set up receiver for media player onPrepared broadcast
    LocalBroadcastManager.getInstance(this).registerReceiver(onPrepareReceiver,
            new IntentFilter("MEDIA_PLAYER_PREPARED"));


    if(paused){
        setController();
        paused=false;
    }
}

@Override
protected void onStop() {
    super.onStop();
}

private void setController(){
    //set the controller up


    if (controller == null) controller = new MusicController(this);

        controller.invalidate();


    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(findViewById(R.id.song_list));

}

@Override

public void onBackPressed() {



    moveTaskToBack(true);
    Intent intent = new Intent (getApplicationContext(), FitnessActivity.class);
    startActivity(intent);



}


// Broadcast receiver to determine when music player has been prepared
private BroadcastReceiver onPrepareReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context c, Intent i) {
        // When music player has been prepared, show controller
        controller.show(0);
    }
};

private BroadcastReceiver onNextClickedReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        musicSrv.playNext();

    }
};

//connect to the service
public 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;
    }
};

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

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_shuffle:
            musicSrv.setShuffle();
            break;
        case R.id.action_end:
            stopService(playIntent);
            musicSrv=null;
            System.exit(0);
            break;
    }
    return super.onOptionsItemSelected(item);
}

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

public void getSongList() {
    //retrieve song info
    ContentResolver musicResolver = getContentResolver();
    Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);

    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);
        int durationColumn = musicCursor.getColumnIndex
                (MediaStore.Audio.Media.DURATION);
        //add songs to list


        do {
            long thisId = musicCursor.getLong(idColumn);
            String thisTitle = musicCursor.getString(titleColumn);
            String thisArtist = musicCursor.getString(artistColumn);
            long thisDuration = musicCursor.getLong(durationColumn);
            if (thisDuration>10000){
            songList.add(new Song(thisId, thisTitle, thisArtist, thisDuration));}
        }
        while (musicCursor.moveToNext());
    }
}


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

public void onNextNotification(){

}
}

清单:

 <activity
        android:name=".MusicPlayer"
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <service android:name=".MusicService"
        />
    <service android:name=".NotificationService" />

1 个答案:

答案 0 :(得分:0)

通知服务收到您的通知操作,而不是音乐服务。编辑通知意图以定位音乐服务

Intent playIntent = new Intent(this, MusicService.class);
//... edit all of them

onStartCommand()方法移至音乐服务并分配操作

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    if (intent.getAction().equals(Constant.ACTION.PLAY_ACTION)) {
        //call play method
    }
//...etc

除了 STARTFOREGROUND_ACTIONSTOPFOREGROUND_ACTION,请将其保留在Notification Service的onStartCommand()中。同时在两个服务中插入对Intent的空检查。