BrowserService.java revision 319f9a979c1c10c0c15ca50ee20e0a05e932cbb7
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 protected BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) { 120 return new BrowserRoot(BROWSE_URI, null); 121 } 122 123 @Override 124 protected List<MediaBrowserItem> onLoadChildren(Uri parentUri) { 125 final ArrayList<MediaBrowserItem> results = new ArrayList(); 126 127 for (int i=0; i<10; i++) { 128 results.add(new MediaBrowserItem.Builder( 129 Uri.withAppendedPath(BASE_URI, Integer.toString(i)), 130 MediaBrowserItem.FLAG_BROWSABLE, "Title " + i) 131 .setSummary("Summary " + i) 132 .build()); 133 } 134 135 return results; 136 } 137 138 @Override 139 protected Bitmap onGetThumbnail(Uri uri, int width, int height) { 140 return null; 141 } 142 143 /* 144 @Override 145 public void query(final Query query, final IMetadataResultHandler metadataResultHandler, 146 final IErrorHandler errorHandler) 147 throws RemoteException { 148 Log.d(TAG, "query: " + query); 149 Utils.checkNotNull(query); 150 Utils.checkNotNull(metadataResultHandler); 151 Utils.checkNotNull(errorHandler); 152 153 // Handle async response 154 new Thread(new Runnable() { 155 public void run() { 156 try { 157 // Pre-load the list of music 158 List<MusicTrack> musicTracks = getMusicList(); 159 if (musicTracks == null) { 160 notifyListenersOnPlaybackStateUpdate(getCurrentPlaybackState()); 161 errorHandler.onError(new Error(Error.UNKNOWN, 162 getString(R.string.music_error))); 163 return; 164 } 165 166 final Uri uri = query.getUri(); 167 int match = sUriMatcher.match(uri); 168 Log.d(TAG, "Queried: " + uri + "; match: " + match); 169 switch (match) { 170 case BROWSE_ROOT: 171 { 172 Log.d(TAG, "Browse_root"); 173 174 try { 175 MatrixCursor matrixCursor = mMusicProvider 176 .getRootContainerCurser(); 177 DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION, 178 matrixCursor, null); 179 180 Log.d(TAG, "on metadata response called " + holder.getCount()); 181 metadataResultHandler.onMetadataResponse(holder); 182 } catch (RemoteException e) { 183 Log.w(TAG, "Error delivering metadata in the callback.", e); 184 } 185 break; 186 } 187 case NOW_PLAYING: 188 { 189 try { 190 Log.d(TAG, "query NOW_PLAYING"); 191 MatrixCursor matrixCursor = mMusicProvider 192 .getRootItemCursor( 193 PIANO); 194 DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION, 195 matrixCursor, null); 196 Log.d(TAG, "on metadata response called " + holder.getCount()); 197 metadataResultHandler.onMetadataResponse(holder); 198 } catch (RemoteException e) { 199 Log.w(TAG, "Error querying NOW_PLAYING"); 200 } 201 break; 202 } 203 case PIANO: 204 { 205 try { 206 Log.d(TAG, "query PIANO"); 207 MatrixCursor matrixCursor = mMusicProvider 208 .getRootItemCursor( 209 PIANO); 210 DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION, 211 matrixCursor, null); 212 Log.d(TAG, "on metadata response called " + holder.getCount()); 213 metadataResultHandler.onMetadataResponse(holder); 214 } catch (RemoteException e) { 215 Log.w(TAG, "Error querying PIANO"); 216 } 217 break; 218 } 219 case VOICE: 220 { 221 try { 222 Log.d(TAG, "query VOICE"); 223 MatrixCursor matrixCursor = mMusicProvider 224 .getRootItemCursor( 225 VOICE); 226 DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION, 227 matrixCursor, null); 228 Log.d(TAG, "on metadata response called " + holder.getCount()); 229 metadataResultHandler.onMetadataResponse(holder); 230 } catch (RemoteException e) { 231 Log.w(TAG, "Error querying VOICE"); 232 } 233 break; 234 } 235 default: 236 { 237 Log.w(TAG, "Skipping unmatched URI: " + uri); 238 } 239 } 240 } catch (NotFoundException e) { 241 Log.e(TAG, "::run:", e); 242 } catch (RemoteException e) { 243 Log.e(TAG, "::run:", e); 244 } 245 } // end run 246 }).start(); 247 } 248 249 */ 250} 251