Skip to content

Most visited

Recently visited

navigation
MediaBrowserService / src / com.example.android.mediabrowserservice /

QueueFragment.java

1
/*
2
 * Copyright (C) 2014 The Android Open Source Project
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package com.example.android.mediabrowserservice;
17
 
18
import android.app.Fragment;
19
import android.content.ComponentName;
20
import android.media.browse.MediaBrowser;
21
import android.media.session.MediaController;
22
import android.media.session.MediaSession;
23
import android.media.session.PlaybackState;
24
import android.os.Bundle;
25
import android.view.LayoutInflater;
26
import android.view.View;
27
import android.view.ViewGroup;
28
import android.widget.AdapterView;
29
import android.widget.ImageButton;
30
import android.widget.ListView;
31
 
32
import com.example.android.mediabrowserservice.utils.LogHelper;
33
 
34
import java.util.List;
35
 
36
/**
37
 * A class that shows the Media Queue to the user.
38
 */
39
public class QueueFragment extends Fragment {
40
 
41
    private static final String TAG = LogHelper.makeLogTag(QueueFragment.class.getSimpleName());
42
 
43
    private ImageButton mSkipNext;
44
    private ImageButton mSkipPrevious;
45
    private ImageButton mPlayPause;
46
 
47
    private MediaBrowser mMediaBrowser;
48
    private MediaController.TransportControls mTransportControls;
49
    private MediaController mMediaController;
50
    private PlaybackState mPlaybackState;
51
 
52
    private QueueAdapter mQueueAdapter;
53
 
54
    private MediaBrowser.ConnectionCallback mConnectionCallback =
55
            new MediaBrowser.ConnectionCallback() {
56
        @Override
57
        public void onConnected() {
58
            LogHelper.d(TAG, "onConnected: session token ", mMediaBrowser.getSessionToken());
59
 
60
            if (mMediaBrowser.getSessionToken() == null) {
61
                throw new IllegalArgumentException("No Session token");
62
            }
63
 
64
            mMediaController = new MediaController(getActivity(),
65
                    mMediaBrowser.getSessionToken());
66
            mTransportControls = mMediaController.getTransportControls();
67
            mMediaController.registerCallback(mSessionCallback);
68
 
69
            getActivity().setMediaController(mMediaController);
70
            mPlaybackState = mMediaController.getPlaybackState();
71
 
72
            List<MediaSession.QueueItem> queue = mMediaController.getQueue();
73
            if (queue != null) {
74
                mQueueAdapter.clear();
75
                mQueueAdapter.notifyDataSetInvalidated();
76
                mQueueAdapter.addAll(queue);
77
                mQueueAdapter.notifyDataSetChanged();
78
            }
79
            onPlaybackStateChanged(mPlaybackState);
80
        }
81
 
82
        @Override
83
        public void onConnectionFailed() {
84
            LogHelper.d(TAG, "onConnectionFailed");
85
        }
86
 
87
        @Override
88
        public void onConnectionSuspended() {
89
            LogHelper.d(TAG, "onConnectionSuspended");
90
            mMediaController.unregisterCallback(mSessionCallback);
91
            mTransportControls = null;
92
            mMediaController = null;
93
            getActivity().setMediaController(null);
94
        }
95
    };
96
 
97
    // Receive callbacks from the MediaController. Here we update our state such as which queue
98
    // is being shown, the current title and description and the PlaybackState.
99
    private MediaController.Callback mSessionCallback = new MediaController.Callback() {
100
 
101
        @Override
102
        public void onSessionDestroyed() {
103
            LogHelper.d(TAG, "Session destroyed. Need to fetch a new Media Session");
104
        }
105
 
106
        @Override
107
        public void onPlaybackStateChanged(PlaybackState state) {
108
            if (state == null) {
109
                return;
110
            }
111
            LogHelper.d(TAG, "Received playback state change to state ", state.getState());
112
            mPlaybackState = state;
113
            QueueFragment.this.onPlaybackStateChanged(state);
114
        }
115
 
116
        @Override
117
        public void onQueueChanged(List<MediaSession.QueueItem> queue) {
118
            LogHelper.d(TAG, "onQueueChanged ", queue);
119
            if (queue != null) {
120
                mQueueAdapter.clear();
121
                mQueueAdapter.notifyDataSetInvalidated();
122
                mQueueAdapter.addAll(queue);
123
                mQueueAdapter.notifyDataSetChanged();
124
            }
125
        }
126
    };
127
 
128
    public static QueueFragment newInstance() {
129
        return new QueueFragment();
130
    }
131
 
132
    @Override
133
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
134
                             Bundle savedInstanceState) {
135
        View rootView = inflater.inflate(R.layout.fragment_list, container, false);
136
 
137
        mSkipPrevious = (ImageButton) rootView.findViewById(R.id.skip_previous);
138
        mSkipPrevious.setEnabled(false);
139
        mSkipPrevious.setOnClickListener(mButtonListener);
140
 
141
        mSkipNext = (ImageButton) rootView.findViewById(R.id.skip_next);
142
        mSkipNext.setEnabled(false);
143
        mSkipNext.setOnClickListener(mButtonListener);
144
 
145
        mPlayPause = (ImageButton) rootView.findViewById(R.id.play_pause);
146
        mPlayPause.setEnabled(true);
147
        mPlayPause.setOnClickListener(mButtonListener);
148
 
149
        mQueueAdapter = new QueueAdapter(getActivity());
150
 
151
        ListView mListView = (ListView) rootView.findViewById(R.id.list_view);
152
        mListView.setAdapter(mQueueAdapter);
153
        mListView.setFocusable(true);
154
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
155
            @Override
156
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
157
                MediaSession.QueueItem item = mQueueAdapter.getItem(position);
158
                mTransportControls.skipToQueueItem(item.getQueueId());
159
            }
160
        });
161
 
162
        mMediaBrowser = new MediaBrowser(getActivity(),
163
                new ComponentName(getActivity(), MusicService.class),
164
                mConnectionCallback, null);
165
 
166
        return rootView;
167
    }
168
 
169
    @Override
170
    public void onResume() {
171
        super.onResume();
172
        if (mMediaBrowser != null) {
173
            mMediaBrowser.connect();
174
        }
175
    }
176
 
177
    @Override
178
    public void onPause() {
179
        super.onPause();
180
        if (mMediaController != null) {
181
            mMediaController.unregisterCallback(mSessionCallback);
182
        }
183
        if (mMediaBrowser != null) {
184
            mMediaBrowser.disconnect();
185
        }
186
    }
187
 
188
 
189
    private void onPlaybackStateChanged(PlaybackState state) {
190
        LogHelper.d(TAG, "onPlaybackStateChanged ", state);
191
        if (state == null) {
192
            return;
193
        }
194
        mQueueAdapter.setActiveQueueItemId(state.getActiveQueueItemId());
195
        mQueueAdapter.notifyDataSetChanged();
196
        boolean enablePlay = false;
197
        StringBuilder statusBuilder = new StringBuilder();
198
        switch (state.getState()) {
199
            case PlaybackState.STATE_PLAYING:
200
                statusBuilder.append("playing");
201
                enablePlay = false;
202
                break;
203
            case PlaybackState.STATE_PAUSED:
204
                statusBuilder.append("paused");
205
                enablePlay = true;
206
                break;
207
            case PlaybackState.STATE_STOPPED:
208
                statusBuilder.append("ended");
209
                enablePlay = true;
210
                break;
211
            case PlaybackState.STATE_ERROR:
212
                statusBuilder.append("error: ").append(state.getErrorMessage());
213
                break;
214
            case PlaybackState.STATE_BUFFERING:
215
                statusBuilder.append("buffering");
216
                break;
217
            case PlaybackState.STATE_NONE:
218
                statusBuilder.append("none");
219
                enablePlay = false;
220
                break;
221
            case PlaybackState.STATE_CONNECTING:
222
                statusBuilder.append("connecting");
223
                break;
224
            default:
225
                statusBuilder.append(mPlaybackState);
226
        }
227
        statusBuilder.append(" -- At position: ").append(state.getPosition());
228
        LogHelper.d(TAG, statusBuilder.toString());
229
 
230
        if (enablePlay) {
231
            mPlayPause.setImageDrawable(
232
                    getActivity().getDrawable(R.drawable.ic_play_arrow_white_24dp));
233
        } else {
234
            mPlayPause.setImageDrawable(getActivity().getDrawable(R.drawable.ic_pause_white_24dp));
235
        }
236
 
237
        mSkipPrevious.setEnabled((state.getActions() & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0);
238
        mSkipNext.setEnabled((state.getActions() & PlaybackState.ACTION_SKIP_TO_NEXT) != 0);
239
 
240
        LogHelper.d(TAG, "Queue From MediaController *** Title " +
241
                mMediaController.getQueueTitle() + "\n: Queue: " + mMediaController.getQueue() +
242
                "\n Metadata " + mMediaController.getMetadata());
243
    }
244
 
245
    private View.OnClickListener mButtonListener = new View.OnClickListener() {
246
        @Override
247
        public void onClick(View v) {
248
            final int state = mPlaybackState == null ?
249
                    PlaybackState.STATE_NONE : mPlaybackState.getState();
250
            switch (v.getId()) {
251
                case R.id.play_pause:
252
                    LogHelper.d(TAG, "Play button pressed, in state " + state);
253
                    if (state == PlaybackState.STATE_PAUSED ||
254
                            state == PlaybackState.STATE_STOPPED ||
255
                            state == PlaybackState.STATE_NONE) {
256
                        playMedia();
257
                    } else if (state == PlaybackState.STATE_PLAYING) {
258
                        pauseMedia();
259
                    }
260
                    break;
261
                case R.id.skip_previous:
262
                    LogHelper.d(TAG, "Start button pressed, in state " + state);
263
                    skipToPrevious();
264
                    break;
265
                case R.id.skip_next:
266
                    skipToNext();
267
                    break;
268
            }
269
        }
270
    };
271
 
272
    private void playMedia() {
273
        if (mTransportControls != null) {
274
            mTransportControls.play();
275
        }
276
    }
277
 
278
    private void pauseMedia() {
279
        if (mTransportControls != null) {
280
            mTransportControls.pause();
281
        }
282
    }
283
 
284
    private void skipToPrevious() {
285
        if (mTransportControls != null) {
286
            mTransportControls.skipToPrevious();
287
        }
288
    }
289
 
290
    private void skipToNext() {
291
        if (mTransportControls != null) {
292
            mTransportControls.skipToNext();
293
        }
294
    }
295
}