BrowseFragment.java revision a907614755847b2630561a1e5949b2b416600d97
1/*
2 * Copyright (C) 2015 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 */
16package com.example.android.supportv4.media;
17
18import android.app.Fragment;
19import android.content.ComponentName;
20import android.content.Context;
21import android.os.Bundle;
22import android.os.RemoteException;
23import android.support.v4.media.MediaBrowserCompat;
24import android.support.v4.media.session.MediaControllerCompat;
25import android.util.Log;
26import android.view.LayoutInflater;
27import android.view.View;
28import android.view.ViewGroup;
29import android.widget.AdapterView;
30import android.widget.ArrayAdapter;
31import android.widget.ImageView;
32import android.widget.ListView;
33import android.widget.TextView;
34import android.widget.Toast;
35
36import com.example.android.supportv4.R;
37
38import java.util.ArrayList;
39import java.util.List;
40
41/**
42 * A Fragment that lists all the various browsable queues available
43 * from a {@link android.service.media.MediaBrowserService}.
44 * <p/>
45 * It uses a {@link MediaBrowserCompat} to connect to the {@link MediaBrowserServiceSupport}.
46 * Once connected, the fragment subscribes to get all the children. All
47 * {@link MediaBrowserCompat.MediaItem}'s that can be browsed are shown in a ListView.
48 */
49public class BrowseFragment extends Fragment {
50
51    private static final String TAG = "BrowseFragment";
52
53    public static final String ARG_MEDIA_ID = "media_id";
54
55    public static interface FragmentDataHelper {
56        void onMediaItemSelected(MediaBrowserCompat.MediaItem item);
57    }
58
59    // The mediaId to be used for subscribing for children using the MediaBrowser.
60    private String mMediaId;
61
62    private MediaBrowserCompat mMediaBrowser;
63    private BrowseAdapter mBrowserAdapter;
64
65    private MediaBrowserCompat.SubscriptionCallback mSubscriptionCallback =
66            new MediaBrowserCompat.SubscriptionCallback() {
67
68        @Override
69        public void onChildrenLoaded(String parentId, List<MediaBrowserCompat.MediaItem> children) {
70            Log.d(TAG, "onChildrenLoaded: " + parentId);
71            mBrowserAdapter.clear();
72            mBrowserAdapter.notifyDataSetInvalidated();
73            for (MediaBrowserCompat.MediaItem item : children) {
74                mBrowserAdapter.add(item);
75            }
76            mBrowserAdapter.notifyDataSetChanged();
77        }
78
79        @Override
80        public void onError(String id) {
81            Toast.makeText(getActivity(), R.string.error_loading_media,
82                    Toast.LENGTH_LONG).show();
83        }
84    };
85
86    private MediaBrowserCompat.ConnectionCallback mConnectionCallback =
87            new MediaBrowserCompat.ConnectionCallback() {
88        @Override
89        public void onConnected() {
90            Log.d(TAG, "onConnected: session token " + mMediaBrowser.getSessionToken());
91
92            if (mMediaId == null) {
93                mMediaId = mMediaBrowser.getRoot();
94            }
95            mMediaBrowser.subscribe(mMediaId, mSubscriptionCallback);
96            if (mMediaBrowser.getSessionToken() == null) {
97                throw new IllegalArgumentException("No Session token");
98            }
99            MediaControllerCompat mediaController = null;
100            try {
101                mediaController = new MediaControllerCompat(getActivity(),
102                        mMediaBrowser.getSessionToken());
103            } catch (RemoteException e) {
104                Log.e(TAG, "Failed to create MediaController.", e);
105            }
106            ((MediaBrowserSupport) getActivity()).setMediaController(mediaController);
107        }
108
109        @Override
110        public void onConnectionFailed() {
111            Log.d(TAG, "onConnectionFailed");
112        }
113
114        @Override
115        public void onConnectionSuspended() {
116            Log.d(TAG, "onConnectionSuspended");
117            getActivity().setMediaController(null);
118        }
119    };
120
121    public static BrowseFragment newInstance(String mediaId) {
122        Bundle args = new Bundle();
123        args.putString(ARG_MEDIA_ID, mediaId);
124        BrowseFragment fragment = new BrowseFragment();
125        fragment.setArguments(args);
126        return fragment;
127    }
128
129    @Override
130    public View onCreateView(LayoutInflater inflater, ViewGroup container,
131                             Bundle savedInstanceState) {
132        View rootView = inflater.inflate(R.layout.fragment_list, container, false);
133
134        mBrowserAdapter = new BrowseAdapter(getActivity());
135
136        View controls = rootView.findViewById(R.id.controls);
137        controls.setVisibility(View.GONE);
138
139        ListView listView = (ListView) rootView.findViewById(R.id.list_view);
140        listView.setAdapter(mBrowserAdapter);
141        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
142            @Override
143            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
144                MediaBrowserCompat.MediaItem item = mBrowserAdapter.getItem(position);
145                try {
146                    FragmentDataHelper listener = (FragmentDataHelper) getActivity();
147                    listener.onMediaItemSelected(item);
148                } catch (ClassCastException ex) {
149                    Log.e(TAG, "Exception trying to cast to FragmentDataHelper", ex);
150                }
151            }
152        });
153
154        Bundle args = getArguments();
155        mMediaId = args.getString(ARG_MEDIA_ID, null);
156
157        mMediaBrowser = new MediaBrowserCompat(getActivity(),
158                new ComponentName(getActivity(), MediaBrowserServiceSupport.class),
159                mConnectionCallback, null);
160
161        return rootView;
162    }
163
164    @Override
165    public void onStart() {
166        super.onStart();
167        mMediaBrowser.connect();
168    }
169
170    @Override
171    public void onStop() {
172        super.onStop();
173        mMediaBrowser.disconnect();
174    }
175
176    // An adapter for showing the list of browsed MediaItem's
177    private static class BrowseAdapter extends ArrayAdapter<MediaBrowserCompat.MediaItem> {
178
179        public BrowseAdapter(Context context) {
180            super(context, R.layout.media_list_item, new ArrayList<MediaBrowserCompat.MediaItem>());
181        }
182
183        static class ViewHolder {
184            ImageView mImageView;
185            TextView mTitleView;
186            TextView mDescriptionView;
187        }
188
189        @Override
190        public View getView(int position, View convertView, ViewGroup parent) {
191
192            ViewHolder holder;
193
194            if (convertView == null) {
195                convertView = LayoutInflater.from(getContext())
196                        .inflate(R.layout.media_list_item, parent, false);
197                holder = new ViewHolder();
198                holder.mImageView = (ImageView) convertView.findViewById(R.id.play_eq);
199                holder.mImageView.setVisibility(View.GONE);
200                holder.mTitleView = (TextView) convertView.findViewById(R.id.title);
201                holder.mDescriptionView = (TextView) convertView.findViewById(R.id.description);
202                convertView.setTag(holder);
203            } else {
204                holder = (ViewHolder) convertView.getTag();
205            }
206
207            MediaBrowserCompat.MediaItem item = getItem(position);
208            holder.mTitleView.setText(item.getDescription().getTitle());
209            holder.mDescriptionView.setText(item.getDescription().getDescription());
210            if (item.isPlayable()) {
211                holder.mImageView.setImageDrawable(getContext().getResources()
212                        .getDrawable(R.drawable.ic_play_arrow_white_24dp));
213                holder.mImageView.setVisibility(View.VISIBLE);
214            }
215            return convertView;
216        }
217    }
218}
219