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