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