BrowserService.java revision 8470857ee43444868a38d0e760981386880d6ce2
1/* 2 * Copyright (C) 2014 Google Inc. All Rights Reserved. 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 17package com.example.android.musicservicedemo; 18 19import android.app.SearchManager; 20import android.app.Service; 21import android.content.Context; 22import android.content.Intent; 23import android.content.UriMatcher; 24import android.content.res.Resources.NotFoundException; 25import android.database.MatrixCursor; 26import android.graphics.Bitmap; 27import android.media.AudioManager; 28import android.media.MediaPlayer; 29import android.media.MediaPlayer.OnCompletionListener; 30import android.media.MediaPlayer.OnErrorListener; 31import android.media.MediaPlayer.OnPreparedListener; 32import android.media.browse.MediaBrowserItem; 33import android.media.browse.MediaBrowserService; 34import android.media.browse.MediaBrowserService.BrowserRoot; 35import android.media.session.MediaSession; 36import android.net.Uri; 37import android.net.wifi.WifiManager; 38import android.net.wifi.WifiManager.WifiLock; 39import android.os.Bundle; 40import android.os.Handler; 41import android.os.IBinder; 42import android.os.Message; 43import android.os.PowerManager; 44import android.os.RemoteException; 45import android.os.SystemClock; 46import android.util.Log; 47 48import com.example.android.musicservicedemo.browser.MusicProvider; 49import com.example.android.musicservicedemo.browser.MusicProviderTask; 50import com.example.android.musicservicedemo.browser.MusicProviderTaskListener; 51import com.example.android.musicservicedemo.browser.MusicTrack; 52 53import org.json.JSONException; 54 55import java.io.IOException; 56import java.util.ArrayList; 57import java.util.List; 58 59/** 60 * Service that implements MediaBrowserService and returns our menu hierarchy. 61 */ 62public class BrowserService extends MediaBrowserService { 63 private static final String TAG = "BrowserService"; 64 65 // URI paths for browsing music 66 public static final String BROWSE_ROOT_BASE_PATH = "browse"; 67 public static final String NOW_PLAYING_PATH = "now_playing"; 68 public static final String PIANO_BASE_PATH = "piano"; 69 public static final String VOICE_BASE_PATH = "voice"; 70 71 // Content URIs 72 public static final String AUTHORITY = "com.example.android.automotive.musicplayer"; 73 public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY); 74 public static final Uri BROWSE_URI = Uri.withAppendedPath(BASE_URI, BROWSE_ROOT_BASE_PATH); 75 76 // URI matcher constants for browsing paths 77 public static final int BROWSE_ROOT = 1; 78 public static final int NOW_PLAYING = 2; 79 public static final int PIANO = 3; 80 public static final int VOICE = 4; 81 82 // Map the the URI paths with the URI matcher constants 83 private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 84 static { 85 sUriMatcher.addURI(AUTHORITY, BROWSE_ROOT_BASE_PATH, BROWSE_ROOT); 86 sUriMatcher.addURI(AUTHORITY, NOW_PLAYING_PATH, NOW_PLAYING); 87 sUriMatcher.addURI(AUTHORITY, PIANO_BASE_PATH, PIANO); 88 sUriMatcher.addURI(AUTHORITY, VOICE_BASE_PATH, VOICE); 89 } 90 91 // Media metadata that will be provided for a media container 92 public static final String[] MEDIA_CONTAINER_PROJECTION = { 93 "uri", 94 "title", 95 "subtitle", 96 "image_uri", 97 "supported_actions" 98 }; 99 100 // MusicProvider will download the music catalog 101 private MusicProvider mMusicProvider; 102 103 private MediaSession mSession; 104 105 @Override 106 public void onCreate() { 107 super.onCreate(); 108 109 mSession = new MediaSession(this, "com.example.android.musicservicedemo.BrowserService"); 110 setSessionToken(mSession.getSessionToken()); 111 } 112 113 @Override 114 public void onDestroy() { 115 super.onDestroy(); 116 } 117 118 @Override 119 public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) { 120 return new BrowserRoot(BROWSE_URI, null); 121 } 122 123 @Override 124 public void onLoadChildren(final Uri parentUri, 125 final Result<List<MediaBrowserItem>> result) { 126 new Handler().postDelayed(new Runnable() { 127 public void run() { 128 final ArrayList<MediaBrowserItem> list = new ArrayList(); 129 130 for (int i=0; i<10; i++) { 131 list.add(new MediaBrowserItem.Builder( 132 Uri.withAppendedPath(BASE_URI, Integer.toString(i)), 133 MediaBrowserItem.FLAG_BROWSABLE, "Title " + i) 134 .setSummary("Summary " + i) 135 .build()); 136 } 137 138 result.sendResult(list); 139 } 140 }, 2000); 141 result.detach(); 142 } 143 144 @Override 145 public void onLoadThumbnail(Uri uri, int width, int height, Result<Bitmap> result) { 146 result.sendResult(null); 147 } 148 149 /* 150 @Override 151 public void query(final Query query, final IMetadataResultHandler metadataResultHandler, 152 final IErrorHandler errorHandler) 153 throws RemoteException { 154 Log.d(TAG, "query: " + query); 155 Utils.checkNotNull(query); 156 Utils.checkNotNull(metadataResultHandler); 157 Utils.checkNotNull(errorHandler); 158 159 // Handle async response 160 new Thread(new Runnable() { 161 public void run() { 162 try { 163 // Pre-load the list of music 164 List<MusicTrack> musicTracks = getMusicList(); 165 if (musicTracks == null) { 166 notifyListenersOnPlaybackStateUpdate(getCurrentPlaybackState()); 167 errorHandler.onError(new Error(Error.UNKNOWN, 168 getString(R.string.music_error))); 169 return; 170 } 171 172 final Uri uri = query.getUri(); 173 int match = sUriMatcher.match(uri); 174 Log.d(TAG, "Queried: " + uri + "; match: " + match); 175 switch (match) { 176 case BROWSE_ROOT: 177 { 178 Log.d(TAG, "Browse_root"); 179 180 try { 181 MatrixCursor matrixCursor = mMusicProvider 182 .getRootContainerCurser(); 183 DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION, 184 matrixCursor, null); 185 186 Log.d(TAG, "on metadata response called " + holder.getCount()); 187 metadataResultHandler.onMetadataResponse(holder); 188 } catch (RemoteException e) { 189 Log.w(TAG, "Error delivering metadata in the callback.", e); 190 } 191 break; 192 } 193 case NOW_PLAYING: 194 { 195 try { 196 Log.d(TAG, "query NOW_PLAYING"); 197 MatrixCursor matrixCursor = mMusicProvider 198 .getRootItemCursor( 199 PIANO); 200 DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION, 201 matrixCursor, null); 202 Log.d(TAG, "on metadata response called " + holder.getCount()); 203 metadataResultHandler.onMetadataResponse(holder); 204 } catch (RemoteException e) { 205 Log.w(TAG, "Error querying NOW_PLAYING"); 206 } 207 break; 208 } 209 case PIANO: 210 { 211 try { 212 Log.d(TAG, "query PIANO"); 213 MatrixCursor matrixCursor = mMusicProvider 214 .getRootItemCursor( 215 PIANO); 216 DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION, 217 matrixCursor, null); 218 Log.d(TAG, "on metadata response called " + holder.getCount()); 219 metadataResultHandler.onMetadataResponse(holder); 220 } catch (RemoteException e) { 221 Log.w(TAG, "Error querying PIANO"); 222 } 223 break; 224 } 225 case VOICE: 226 { 227 try { 228 Log.d(TAG, "query VOICE"); 229 MatrixCursor matrixCursor = mMusicProvider 230 .getRootItemCursor( 231 VOICE); 232 DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION, 233 matrixCursor, null); 234 Log.d(TAG, "on metadata response called " + holder.getCount()); 235 metadataResultHandler.onMetadataResponse(holder); 236 } catch (RemoteException e) { 237 Log.w(TAG, "Error querying VOICE"); 238 } 239 break; 240 } 241 default: 242 { 243 Log.w(TAG, "Skipping unmatched URI: " + uri); 244 } 245 } 246 } catch (NotFoundException e) { 247 Log.e(TAG, "::run:", e); 248 } catch (RemoteException e) { 249 Log.e(TAG, "::run:", e); 250 } 251 } // end run 252 }).start(); 253 } 254 255 */ 256} 257