{"action":"created","comment":{"url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/pulls/comments/36030898","id":36030898,"diff_hunk":"@@ -0,0 +1,535 @@\n+package com.n8.spotifystreamer.playback;\n+\n+import android.app.KeyguardManager;\n+import android.app.Notification;\n+import android.app.NotificationManager;\n+import android.app.PendingIntent;\n+import android.app.Service;\n+import android.content.BroadcastReceiver;\n+import android.content.Context;\n+import android.content.Intent;\n+import android.content.IntentFilter;\n+import android.graphics.Bitmap;\n+import android.media.AudioManager;\n+import android.media.MediaPlayer;\n+import android.net.wifi.WifiManager;\n+import android.os.IBinder;\n+import android.os.PowerManager;\n+import android.preference.PreferenceManager;\n+import android.support.v7.app.NotificationCompat;\n+import android.util.Log;\n+import android.widget.ImageView;\n+\n+import com.n8.spotifystreamer.BusProvider;\n+import com.n8.spotifystreamer.ImageUtils;\n+import com.n8.spotifystreamer.MainActivity;\n+import com.n8.spotifystreamer.R;\n+import com.n8.spotifystreamer.events.NextTrackEvent;\n+import com.n8.spotifystreamer.events.PlaybackProgressEvent;\n+import com.n8.spotifystreamer.events.PlaybackServiceStateBroadcastEvent;\n+import com.n8.spotifystreamer.events.PlaybackServiceStateRequestEvent;\n+import com.n8.spotifystreamer.events.PrevTrackEvent;\n+import com.n8.spotifystreamer.events.SeekbarChangedEvent;\n+import com.n8.spotifystreamer.events.TrackPausedEvent;\n+import com.n8.spotifystreamer.events.TrackPlaybackCompleteEvent;\n+import com.n8.spotifystreamer.events.TrackStartedEvent;\n+import com.squareup.otto.Subscribe;\n+import com.squareup.picasso.Callback;\n+import com.squareup.picasso.Picasso;\n+\n+import java.io.IOException;\n+\n+public class PlaybackService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer\n+    .OnBufferingUpdateListener, MediaPlayer.OnErrorListener, AudioManager.OnAudioFocusChangeListener, MediaPlayer.OnCompletionListener {\n+\n+  private static final String TAG = PlaybackService.class.getSimpleName();\n+\n+  public static final String KEY_PLAYLIST = \"key_playlist\";\n+\n+  public static final String KEY_TRACK_INDEX = \"key_track_index\";\n+\n+  public static final String ACTION_PLAY = \"com.n8.spotifystreamer.PLAY\";\n+\n+  public static final String ACTION_PAUSE = \"com.n8.spotifystreamer.PAUSE\";\n+\n+  public static final String ACTION_STOP = \"com.n8.spotifystreamer.STOP\";\n+\n+  public static final String ACTION_NEXT = \"com.n8.spotifystreamer.NEXT\";\n+\n+  public static final String ACTION_PREVIOUS = \"com.n8.spotifystreamer.PREVIOUS\";\n+\n+  public static final String TAG_WIFI_LOCK = \"mylock\";\n+\n+  private static final int NOTIFICATION_ID = 001;\n+\n+  public static final int PROGRESS_REPORTING_DELAY = 1000;\n+\n+  private MediaPlayer mMediaPlayer;\n+\n+  private WifiManager.WifiLock mWifiLock;\n+\n+  private TopTracksPlaylist mTopTracksPlaylist;\n+\n+  private int mTrackIndex;\n+\n+  private Bitmap mNotificationImage;\n+\n+  private boolean mLockScreenControlsEnabled;\n+\n+  private BroadcastReceiver mLockScreenReceiver;\n+\n+  private Thread mProgressMonitorThread;\n+\n+  @Override\n+  public void onCreate() {\n+    super.onCreate();\n+    BusProvider.getInstance().register(this);\n+\n+    mLockScreenReceiver = new BroadcastReceiver() {\n+      @Override\n+      public void onReceive(Context context, Intent intent) {\n+        KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);\n+        boolean locked = km.inKeyguardRestrictedInputMode();\n+\n+        mLockScreenControlsEnabled = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean(getString\n+            (R.string.pref_enable_notification_media_controls_key), false);\n+\n+        if (locked) {\n+          if (mMediaPlayer == null) {\n+            return;\n+          }\n+\n+          if (mMediaPlayer.isPlaying()) {\n+            showPauseNotification(mLockScreenControlsEnabled);\n+          } else {\n+            showPlayNotification(mLockScreenControlsEnabled);\n+          }\n+        } else {\n+          if (mMediaPlayer == null) {\n+            return;\n+          }\n+\n+          if (mMediaPlayer.isPlaying()) {\n+            showPauseNotification(true);\n+          } else {\n+            showPlayNotification(true);\n+          }\n+        }\n+      }\n+    };\n+\n+    registerReceiver(mLockScreenReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));\n+    registerReceiver(mLockScreenReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));\n+    registerReceiver(mLockScreenReceiver, new IntentFilter(Intent.ACTION_USER_PRESENT));\n+  }\n+\n+  @Override\n+  public void onDestroy() {\n+    BusProvider.getInstance().unregister(this);\n+    unregisterReceiver(mLockScreenReceiver);\n+    cleanupMediaPlayer();\n+    cleanupWifiLock();\n+  }\n+\n+  @Override\n+  public IBinder onBind(Intent intent) {\n+    return null;\n+  }\n+\n+  @Override\n+  public void onTaskRemoved(Intent rootIntent) {\n+    super.onTaskRemoved(rootIntent);\n+    stop();\n+  }\n+\n+  @Override\n+  public int onStartCommand(Intent intent, int flags, int startId) {\n+    Log.d(TAG, \"onStartCommand\");\n+\n+    if (intent != null ) {\n+      String action = intent.getAction();\n+      Log.d(TAG, action);\n+\n+      if (action != null) {\n+        if (action.equals(ACTION_PLAY)) {\n+          handlePlayIntent(intent);\n+        } else if (action.equals(ACTION_PAUSE)) {\n+          pause();\n+        } else if (action.equals(ACTION_STOP)) {\n+          stop();\n+        } else if (action.equals(ACTION_NEXT)) {\n+          next();\n+        } else if (action.equals(ACTION_PREVIOUS)) {\n+          prev();\n+        }\n+      }\n+    }\n+\n+    return START_STICKY;\n+  }\n+\n+  @Override\n+  public void onPrepared(MediaPlayer mp) {\n+    play();\n+  }\n+\n+  @Override\n+  public void onBufferingUpdate(MediaPlayer mp, int percent) {\n+\n+  }\n+\n+  @Override\n+  public void onCompletion(MediaPlayer mp) {\n+    complete();\n+  }\n+\n+  @Override\n+  public boolean onError(MediaPlayer mp, int what, int extra) {\n+    return false;\n+  }\n+\n+  // http://developer.android.com/guide/topics/media/mediaplayer.html#preparingasync\n+  @Override\n+  public void onAudioFocusChange(int focusChange) {\n+    switch (focusChange) {\n+      case AudioManager.AUDIOFOCUS_GAIN:\n+        // resume playback\n+        if (mMediaPlayer == null) {\n+          initMediaPlayer();\n+        }\n+        else if (!mMediaPlayer.isPlaying()) {\n+          mMediaPlayer.start();\n+        }\n+        mMediaPlayer.setVolume(1.0f, 1.0f);\n+        break;\n+\n+      case AudioManager.AUDIOFOCUS_LOSS:\n+        // Lost focus for an unbounded amount of time: stop playback and release media player\n+        stop();\n+        cleanupMediaPlayer();\n+        break;\n+\n+      case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:\n+        // Lost focus for a short time, but we have to stop playback. We don't release the media player because playback is\n+        // likely to resume\n+        pause();\n+        break;\n+\n+      case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:\n+        // Lost focus for a short time, but it's ok to keep playing at an attenuated level\n+        if (mMediaPlayer.isPlaying()) {\n+          mMediaPlayer.setVolume(0.1f, 0.1f);\n+        }\n+        break;\n+    }\n+  }\n+\n+  @Subscribe\n+  public void onPlaybackServiceStateRequestEventReceived(PlaybackServiceStateRequestEvent event) {\n+    BusProvider.getInstance().post(new PlaybackServiceStateBroadcastEvent(mMediaPlayer));\n+  }\n+\n+  @Subscribe\n+  public void onSeekbarChangedEventReceived(SeekbarChangedEvent event) {\n+    if (mMediaPlayer != null) {\n+      mMediaPlayer.seekTo(event.getProgress());\n+    }\n+  }\n+\n+  private void initMediaPlayer() {\n+    if (mMediaPlayer == null) {\n+      mMediaPlayer = new MediaPlayer();\n+      mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);\n+      mMediaPlayer.setOnPreparedListener(this);\n+      mMediaPlayer.setOnBufferingUpdateListener(this);\n+      mMediaPlayer.setOnErrorListener(this);\n+      mMediaPlayer.setOnCompletionListener(this);\n+\n+      // Set wake lock to ensue cpu doesn't sleep while playing.\n+      // Is managed by media player so when music is paused or stopped, the lock is removed\n+      mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);\n+\n+      // Get a wifi lock that we can set when music is playing\n+      cleanupWifiLock();\n+      mWifiLock = ((WifiManager) getSystemService(WIFI_SERVICE)).createWifiLock(WifiManager.WIFI_MODE_FULL, TAG_WIFI_LOCK);\n+    }else{\n+      mNotificationImage = null;\n+      mMediaPlayer.reset();\n+    }\n+\n+    try {\n+      String url = mTopTracksPlaylist.getTrackUrls().get(mTrackIndex);\n+      if (url == null) {\n+        return;\n+      }\n+\n+      mMediaPlayer.setDataSource(url);\n+      mMediaPlayer.prepareAsync();\n+    } catch (IOException e) {\n+      Log.d(TAG, \"Failed to prepare media playter \" + e.getMessage());\n+    }\n+  }\n+\n+  private void cleanupMediaPlayer(){\n+    if (mMediaPlayer != null) {\n+      mMediaPlayer.release();\n+    }\n+    mMediaPlayer = null;\n+  }\n+\n+  private void cleanupWifiLock(){\n+    if (mWifiLock != null && mWifiLock.isHeld()) {\n+      mWifiLock.release();\n+    }\n+    mWifiLock = null;\n+  }\n+\n+  private void handlePlayIntent(Intent intent) {\n+    Log.d(TAG, \"handlePlayIntent()\");\n+\n+    if (mMediaPlayer != null) {\n+      play();\n+      return;\n+    }\n+\n+    // Check for new playlist info.  If it exists in the bundle, update the service's members\n+    //\n+    TopTracksPlaylist playlist = intent.getParcelableExtra(KEY_PLAYLIST);\n+    if (playlist != null) {\n+      mTopTracksPlaylist = playlist;\n+      mTrackIndex = intent.getIntExtra(KEY_TRACK_INDEX, 0);\n+      mNotificationImage = null;\n+      initMediaPlayer();\n+    }\n+  }\n+\n+  private void play(){\n+    AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);\n+    int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);\n+\n+    if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {\n+      Log.d(TAG, \"Failed to get audio focus\");\n+    } else {\n+      mWifiLock.acquire();\n+      showPlayNotification(true);\n+      mMediaPlayer.start();\n+      BusProvider.getInstance().post(\n+          new TrackStartedEvent(\n+              mTopTracksPlaylist.getTrackName(mTrackIndex),\n+              mTopTracksPlaylist.getTrackAlbumName(mTrackIndex),\n+              mTopTracksPlaylist.getArtistName(),\n+              mTopTracksPlaylist.getTrackThumbnailUrl(mTrackIndex),\n+              mMediaPlayer.getDuration()\n+          )\n+      );\n+\n+      mProgressMonitorThread = new Thread(){\n+        @Override\n+        public void run() {\n+          while (mMediaPlayer.getCurrentPosition() < mMediaPlayer.getDuration()) {\n+            if (isInterrupted()) {\n+              Log.d(TAG, \"Interrupted while monitoring progress\");\n+              return;\n+            }\n+\n+            BusProvider.getInstance().post(new PlaybackProgressEvent(mMediaPlayer.getCurrentPosition()));\n+            try {\n+              sleep(PROGRESS_REPORTING_DELAY);\n+            } catch (InterruptedException e) {\n+              Log.d(TAG, \"Failed to sleep while monitoring progress. \" + e.getMessage());\n+            }\n+          }\n+        }\n+      };\n+      mProgressMonitorThread.start();\n+\n+    }\n+  }\n+\n+  private void pause(){\n+    Log.d(TAG, \"pause()\");\n+    if (mWifiLock.isHeld()) {\n+      mWifiLock.release();\n+    }\n+\n+    if (mMediaPlayer.isPlaying()) {\n+      mMediaPlayer.pause();\n+      mProgressMonitorThread.interrupt();\n+      BusProvider.getInstance().post(new TrackPausedEvent());\n+    }\n+\n+    stopForeground(false);\n+    showPauseNotification(true);\n+  }\n+\n+  private void next() {\n+    if (mTrackIndex < mTopTracksPlaylist.size() - 1) {\n+      mTrackIndex++;\n+      initMediaPlayer();\n+\n+      BusProvider.getInstance().post(new NextTrackEvent(mTrackIndex));\n+    }\n+  }\n+\n+  private void prev(){\n+    if (mTrackIndex > 0) {\n+      mTrackIndex--;\n+      initMediaPlayer();\n+","path":"app/src/main/java/com/n8/spotifystreamer/playback/PlaybackService.java","position":378,"original_position":378,"commit_id":"953c0b99b67214e255eed68ae1e0ed7c968492db","original_commit_id":"953c0b99b67214e255eed68ae1e0ed7c968492db","user":{"login":"n8ebel","id":3383930,"avatar_url":"https://avatars.githubusercontent.com/u/3383930?v=3","gravatar_id":"","url":"https://api.github.com/users/n8ebel","html_url":"https://github.com/n8ebel","followers_url":"https://api.github.com/users/n8ebel/followers","following_url":"https://api.github.com/users/n8ebel/following{/other_user}","gists_url":"https://api.github.com/users/n8ebel/gists{/gist_id}","starred_url":"https://api.github.com/users/n8ebel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/n8ebel/subscriptions","organizations_url":"https://api.github.com/users/n8ebel/orgs","repos_url":"https://api.github.com/users/n8ebel/repos","events_url":"https://api.github.com/users/n8ebel/events{/privacy}","received_events_url":"https://api.github.com/users/n8ebel/received_events","type":"User","site_admin":false},"body":"should stop monitoring progress","created_at":"2015-08-01T05:35:27Z","updated_at":"2015-08-01T05:35:27Z","html_url":"https://github.com/n8ebel/android_nanodegre_spotify_streamer/pull/35#discussion_r36030898","pull_request_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/pulls/35","_links":{"self":{"href":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/pulls/comments/36030898"},"html":{"href":"https://github.com/n8ebel/android_nanodegre_spotify_streamer/pull/35#discussion_r36030898"},"pull_request":{"href":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/pulls/35"}}},"pull_request":{"url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/pulls/35","id":41396671,"html_url":"https://github.com/n8ebel/android_nanodegre_spotify_streamer/pull/35","diff_url":"https://github.com/n8ebel/android_nanodegre_spotify_streamer/pull/35.diff","patch_url":"https://github.com/n8ebel/android_nanodegre_spotify_streamer/pull/35.patch","issue_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/issues/35","number":35,"state":"open","locked":false,"title":"Implements track playback and control","user":{"login":"n8ebel","id":3383930,"avatar_url":"https://avatars.githubusercontent.com/u/3383930?v=3","gravatar_id":"","url":"https://api.github.com/users/n8ebel","html_url":"https://github.com/n8ebel","followers_url":"https://api.github.com/users/n8ebel/followers","following_url":"https://api.github.com/users/n8ebel/following{/other_user}","gists_url":"https://api.github.com/users/n8ebel/gists{/gist_id}","starred_url":"https://api.github.com/users/n8ebel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/n8ebel/subscriptions","organizations_url":"https://api.github.com/users/n8ebel/orgs","repos_url":"https://api.github.com/users/n8ebel/repos","events_url":"https://api.github.com/users/n8ebel/events{/privacy}","received_events_url":"https://api.github.com/users/n8ebel/received_events","type":"User","site_admin":false},"body":"Fixes #34\r\nFixes #32\r\nFixes #31\r\nFixes #26 \r\nFixes #25 \r\nFixes #24 \r\nFixes #23 \r\nFixes #21 \r\nFixes #20 \r\n","created_at":"2015-08-01T05:15:10Z","updated_at":"2015-08-01T05:35:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"02a15fefe0fec65f26cbe16659e10cdc2c52becf","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/pulls/35/commits","review_comments_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/pulls/35/comments","review_comment_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/pulls/comments{/number}","comments_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/issues/35/comments","statuses_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/statuses/953c0b99b67214e255eed68ae1e0ed7c968492db","head":{"label":"n8ebel:playback","ref":"playback","sha":"953c0b99b67214e255eed68ae1e0ed7c968492db","user":{"login":"n8ebel","id":3383930,"avatar_url":"https://avatars.githubusercontent.com/u/3383930?v=3","gravatar_id":"","url":"https://api.github.com/users/n8ebel","html_url":"https://github.com/n8ebel","followers_url":"https://api.github.com/users/n8ebel/followers","following_url":"https://api.github.com/users/n8ebel/following{/other_user}","gists_url":"https://api.github.com/users/n8ebel/gists{/gist_id}","starred_url":"https://api.github.com/users/n8ebel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/n8ebel/subscriptions","organizations_url":"https://api.github.com/users/n8ebel/orgs","repos_url":"https://api.github.com/users/n8ebel/repos","events_url":"https://api.github.com/users/n8ebel/events{/privacy}","received_events_url":"https://api.github.com/users/n8ebel/received_events","type":"User","site_admin":false},"repo":{"id":37001644,"name":"android_nanodegre_spotify_streamer","full_name":"n8ebel/android_nanodegre_spotify_streamer","owner":{"login":"n8ebel","id":3383930,"avatar_url":"https://avatars.githubusercontent.com/u/3383930?v=3","gravatar_id":"","url":"https://api.github.com/users/n8ebel","html_url":"https://github.com/n8ebel","followers_url":"https://api.github.com/users/n8ebel/followers","following_url":"https://api.github.com/users/n8ebel/following{/other_user}","gists_url":"https://api.github.com/users/n8ebel/gists{/gist_id}","starred_url":"https://api.github.com/users/n8ebel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/n8ebel/subscriptions","organizations_url":"https://api.github.com/users/n8ebel/orgs","repos_url":"https://api.github.com/users/n8ebel/repos","events_url":"https://api.github.com/users/n8ebel/events{/privacy}","received_events_url":"https://api.github.com/users/n8ebel/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/n8ebel/android_nanodegre_spotify_streamer","description":"Project 1 on the Udacity Android Nanodegree","fork":false,"url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer","forks_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/forks","keys_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/keys{/key_id}","collaborators_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/teams","hooks_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/hooks","issue_events_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/issues/events{/number}","events_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/events","assignees_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/assignees{/user}","branches_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/branches{/branch}","tags_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/tags","blobs_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/git/refs{/sha}","trees_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/git/trees{/sha}","statuses_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/statuses/{sha}","languages_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/languages","stargazers_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/stargazers","contributors_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/contributors","subscribers_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/subscribers","subscription_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/subscription","commits_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/commits{/sha}","git_commits_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/git/commits{/sha}","comments_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/comments{/number}","issue_comment_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/issues/comments{/number}","contents_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/contents/{+path}","compare_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/compare/{base}...{head}","merges_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/merges","archive_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/downloads","issues_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/issues{/number}","pulls_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/pulls{/number}","milestones_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/milestones{/number}","notifications_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/labels{/name}","releases_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/releases{/id}","created_at":"2015-06-07T02:20:31Z","updated_at":"2015-06-07T02:20:46Z","pushed_at":"2015-08-01T05:15:10Z","git_url":"git://github.com/n8ebel/android_nanodegre_spotify_streamer.git","ssh_url":"git@github.com:n8ebel/android_nanodegre_spotify_streamer.git","clone_url":"https://github.com/n8ebel/android_nanodegre_spotify_streamer.git","svn_url":"https://github.com/n8ebel/android_nanodegre_spotify_streamer","homepage":null,"size":584,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":18,"forks":0,"open_issues":18,"watchers":0,"default_branch":"master"}},"base":{"label":"n8ebel:master","ref":"master","sha":"95a4abd4cdd87a4b9c3553c0dbb4c21ee46f132e","user":{"login":"n8ebel","id":3383930,"avatar_url":"https://avatars.githubusercontent.com/u/3383930?v=3","gravatar_id":"","url":"https://api.github.com/users/n8ebel","html_url":"https://github.com/n8ebel","followers_url":"https://api.github.com/users/n8ebel/followers","following_url":"https://api.github.com/users/n8ebel/following{/other_user}","gists_url":"https://api.github.com/users/n8ebel/gists{/gist_id}","starred_url":"https://api.github.com/users/n8ebel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/n8ebel/subscriptions","organizations_url":"https://api.github.com/users/n8ebel/orgs","repos_url":"https://api.github.com/users/n8ebel/repos","events_url":"https://api.github.com/users/n8ebel/events{/privacy}","received_events_url":"https://api.github.com/users/n8ebel/received_events","type":"User","site_admin":false},"repo":{"id":37001644,"name":"android_nanodegre_spotify_streamer","full_name":"n8ebel/android_nanodegre_spotify_streamer","owner":{"login":"n8ebel","id":3383930,"avatar_url":"https://avatars.githubusercontent.com/u/3383930?v=3","gravatar_id":"","url":"https://api.github.com/users/n8ebel","html_url":"https://github.com/n8ebel","followers_url":"https://api.github.com/users/n8ebel/followers","following_url":"https://api.github.com/users/n8ebel/following{/other_user}","gists_url":"https://api.github.com/users/n8ebel/gists{/gist_id}","starred_url":"https://api.github.com/users/n8ebel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/n8ebel/subscriptions","organizations_url":"https://api.github.com/users/n8ebel/orgs","repos_url":"https://api.github.com/users/n8ebel/repos","events_url":"https://api.github.com/users/n8ebel/events{/privacy}","received_events_url":"https://api.github.com/users/n8ebel/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/n8ebel/android_nanodegre_spotify_streamer","description":"Project 1 on the Udacity Android Nanodegree","fork":false,"url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer","forks_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/forks","keys_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/keys{/key_id}","collaborators_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/teams","hooks_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/hooks","issue_events_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/issues/events{/number}","events_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/events","assignees_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/assignees{/user}","branches_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/branches{/branch}","tags_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/tags","blobs_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/git/refs{/sha}","trees_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/git/trees{/sha}","statuses_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/statuses/{sha}","languages_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/languages","stargazers_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/stargazers","contributors_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/contributors","subscribers_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/subscribers","subscription_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/subscription","commits_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/commits{/sha}","git_commits_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/git/commits{/sha}","comments_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/comments{/number}","issue_comment_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/issues/comments{/number}","contents_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/contents/{+path}","compare_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/compare/{base}...{head}","merges_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/merges","archive_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/downloads","issues_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/issues{/number}","pulls_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/pulls{/number}","milestones_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/milestones{/number}","notifications_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/labels{/name}","releases_url":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/releases{/id}","created_at":"2015-06-07T02:20:31Z","updated_at":"2015-06-07T02:20:46Z","pushed_at":"2015-08-01T05:15:10Z","git_url":"git://github.com/n8ebel/android_nanodegre_spotify_streamer.git","ssh_url":"git@github.com:n8ebel/android_nanodegre_spotify_streamer.git","clone_url":"https://github.com/n8ebel/android_nanodegre_spotify_streamer.git","svn_url":"https://github.com/n8ebel/android_nanodegre_spotify_streamer","homepage":null,"size":584,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":18,"forks":0,"open_issues":18,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/pulls/35"},"html":{"href":"https://github.com/n8ebel/android_nanodegre_spotify_streamer/pull/35"},"issue":{"href":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/issues/35"},"comments":{"href":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/issues/35/comments"},"review_comments":{"href":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/pulls/35/comments"},"review_comment":{"href":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/pulls/35/commits"},"statuses":{"href":"https://api.github.com/repos/n8ebel/android_nanodegre_spotify_streamer/statuses/953c0b99b67214e255eed68ae1e0ed7c968492db"}}}}