Switch music player to live data for syncing state
Test: build and run the app
Change-Id: I2e7a1ce5663464e82b131f76dfe5b452336457c2
diff --git a/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/BaseActivity.java b/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/BaseActivity.java
new file mode 100644
index 0000000..88b95e7
--- /dev/null
+++ b/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/BaseActivity.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.sample.musicplayer;
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+
+import com.android.support.lifecycle.ActivityLifecycleDispatcher;
+import com.android.support.lifecycle.Lifecycle;
+import com.android.support.lifecycle.LifecycleProvider;
+
+/**
+ * Temporary base activity that acts as lifecycle provider.
+ */
+public abstract class BaseActivity extends AppCompatActivity implements LifecycleProvider {
+ private final ActivityLifecycleDispatcher mDispatcher = new ActivityLifecycleDispatcher(this,
+ this);
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mDispatcher.onCreate();
+ }
+ @Override
+ protected void onResume() {
+ mDispatcher.onResume();
+ super.onResume();
+ }
+ @Override
+ protected void onPause() {
+ mDispatcher.onPause();
+ super.onPause();
+ }
+ @Override
+ protected void onStop() {
+ mDispatcher.onStop();
+ super.onStop();
+ }
+ @Override
+ protected void onDestroy() {
+ mDispatcher.onDestroy();
+ super.onDestroy();
+ }
+ @Override
+ public Lifecycle getLifecycle() {
+ return mDispatcher.getLifecycle();
+ }
+}
diff --git a/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/MainActivity.java b/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/MainActivity.java
index a1529f6..83b90cb 100644
--- a/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/MainActivity.java
+++ b/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/MainActivity.java
@@ -15,62 +15,35 @@
*/
package com.android.sample.musicplayer;
-import android.content.BroadcastReceiver;
-import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.os.Bundle;
+import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
-import android.support.v4.content.LocalBroadcastManager;
-import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.Adapter;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
import com.android.sample.musicplayer.MusicRepository.TrackMetadata;
+import com.android.sample.musicplayer.adapter.MusicTrackListAdapter;
+import com.android.support.lifecycle.LiveData;
+import com.android.support.lifecycle.Observer;
import java.util.List;
/**
* Our main activity.
*/
-public class MainActivity extends AppCompatActivity {
- private MusicRepository mMusicRepository;
-
+public class MainActivity extends BaseActivity {
private RecyclerView mRecyclerView;
- static class CustomViewHolder extends RecyclerView.ViewHolder {
- private ViewGroup mContainerView;
- private TextView mIndexView;
- private TextView mTextView;
- private TextView mArtistView;
-
- CustomViewHolder(View view) {
- super(view);
- this.mContainerView = (ViewGroup) view;
- this.mIndexView = (TextView) view.findViewById(R.id.index);
- this.mTextView = (TextView) view.findViewById(R.id.title);
- this.mArtistView = (TextView) view.findViewById(R.id.artist);
- }
- }
-
- private class ProgressReceiver extends BroadcastReceiver {
- public void onReceive(Context context, Intent intent) {
- updateFab();
- if (mRecyclerView != null) {
- mRecyclerView.getAdapter().notifyDataSetChanged();
- }
- }
- }
+ private MusicTrackListAdapter mMusicTrackListAdapter;
+ private int mCurrPlaybackState;
private void updateFab() {
final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
- switch (mMusicRepository.getState()) {
+ switch (mCurrPlaybackState) {
case MusicRepository.STATE_PLAYING:
fab.setImageResource(R.drawable.ic_pause_white_36dp);
break;
@@ -88,20 +61,37 @@
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
- mMusicRepository = MusicRepository.getInstance();
+ MusicRepository musicRepository = MusicRepository.getInstance();
+ LiveData<Integer> currentlyActiveTrackData = musicRepository.getCurrentlyActiveTrackData();
+ currentlyActiveTrackData.observe(this, new Observer<Integer>() {
+ @Override
+ public void onChanged(@Nullable Integer integer) {
+ if (mMusicTrackListAdapter != null) {
+ mMusicTrackListAdapter.setActiveTrackIndex(integer);
+ }
+ }
+ });
+ LiveData<Integer> stateData = musicRepository.getStateData();
+ stateData.observe(this, new Observer<Integer>() {
+ @Override
+ public void onChanged(@Nullable Integer integer) {
+ mCurrPlaybackState = integer;
+ updateFab();
+ }
+ });
startService(new Intent(MusicService.ACTION_INITIALIZE)
.setPackage("com.android.sample.musicplayer"));
final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
-
updateFab();
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- switch (mMusicRepository.getState()) {
+ switch (mCurrPlaybackState) {
case MusicRepository.STATE_STOPPED:
+ case MusicRepository.STATE_PAUSED:
startService(new Intent(MusicService.ACTION_PLAY).setPackage(
"com.android.sample.musicplayer"));
break;
@@ -109,49 +99,16 @@
startService(new Intent(MusicService.ACTION_PAUSE).setPackage(
"com.android.sample.musicplayer"));
break;
- case MusicRepository.STATE_PAUSED:
- startService(new Intent(MusicService.ACTION_PLAY).setPackage(
- "com.android.sample.musicplayer"));
- break;
-
}
}
});
- // The filter's action is BROADCAST_ACTION
- IntentFilter statusIntentFilter = new IntentFilter(MusicService.BROADCAST_ACTION);
- // Instantiates a new progress receiver
- ProgressReceiver progressReceiver = new ProgressReceiver();
- // Registers the receiver and its intent filters
- LocalBroadcastManager.getInstance(this).registerReceiver(
- progressReceiver, statusIntentFilter);
-
final LayoutInflater inflater = LayoutInflater.from(this);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler);
final List<TrackMetadata> tracks = MusicRepository.getInstance().getTracks();
- mRecyclerView.setAdapter(new Adapter<CustomViewHolder>() {
-
- @Override
- public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View inflated = inflater.inflate(R.layout.main_row, parent, false);
- return new CustomViewHolder(inflated);
- }
-
- @Override
- public void onBindViewHolder(CustomViewHolder holder, final int position) {
- holder.mContainerView.setSelected(
- position == mMusicRepository.getCurrentlyActiveTrack());
- holder.mIndexView.setText(Integer.toString(position + 1));
- holder.mTextView.setText(tracks.get(position).getTitle());
- holder.mArtistView.setText(tracks.get(position).getArtist());
- }
-
- @Override
- public int getItemCount() {
- return tracks.size();
- }
- });
+ mMusicTrackListAdapter = new MusicTrackListAdapter(inflater, tracks);
+ mRecyclerView.setAdapter(mMusicTrackListAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
}
}
diff --git a/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/MusicRepository.java b/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/MusicRepository.java
index cb6de7e..2ef3898 100644
--- a/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/MusicRepository.java
+++ b/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/MusicRepository.java
@@ -17,6 +17,8 @@
import android.support.annotation.RawRes;
+import com.android.support.lifecycle.LiveData;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -60,9 +62,8 @@
private List<TrackMetadata> mTracks;
- private int mCurrentlyActiveTrack = -1;
-
- private int mState = STATE_STOPPED;
+ private LiveData<Integer> mCurrentlyActiveTrackData;
+ private LiveData<Integer> mStateData;
/**
* Gets the repository instance.
@@ -85,6 +86,12 @@
mTracks.add(new TrackMetadata("Cheap Deals", "Skia", R.raw.track_07));
mTracks.add(new TrackMetadata("Don't Stop the Drilling", "Dusty Oilfield", R.raw.track_08));
mTracks.add(new TrackMetadata("Million Regressions", "Lady BreakBuild", R.raw.track_09));
+
+ mCurrentlyActiveTrackData = new LiveData<>();
+ mCurrentlyActiveTrackData.setValue(-1);
+
+ mStateData = new LiveData<>();
+ mStateData.setValue(STATE_STOPPED);
}
public List<TrackMetadata> getTracks() {
@@ -92,18 +99,26 @@
}
public int getCurrentlyActiveTrack() {
- return mCurrentlyActiveTrack;
+ return mCurrentlyActiveTrackData.getValue();
}
public void setCurrentlyActiveTrack(int currentlyActiveTrack) {
- mCurrentlyActiveTrack = currentlyActiveTrack;
+ mCurrentlyActiveTrackData.setValue(currentlyActiveTrack);
}
public int getState() {
- return mState;
+ return mStateData.getValue();
}
public void setState(int state) {
- mState = state;
+ mStateData.setValue(state);
+ }
+
+ public LiveData<Integer> getCurrentlyActiveTrackData() {
+ return this.mCurrentlyActiveTrackData;
+ }
+
+ public LiveData<Integer> getStateData() {
+ return mStateData;
}
}
diff --git a/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/MusicService.java b/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/MusicService.java
index bc2bc27..d2c724f 100644
--- a/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/MusicService.java
+++ b/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/MusicService.java
@@ -28,7 +28,6 @@
import android.os.PowerManager;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationManagerCompat;
-import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v7.app.NotificationCompat;
@@ -50,8 +49,6 @@
public static final String ACTION_NEXT = "com.android.sample.musicplayer.action.NEXT";
public static final String ACTION_PREV = "com.android.sample.musicplayer.action.PREV";
- public static final String BROADCAST_ACTION = "com.android.sample.musicplayer.status.REPORT";
-
private static final String RESOURCE_PREFIX =
"android.resource://com.android.sample.musicplayer/";
@@ -168,7 +165,6 @@
private void processInitializeRequest() {
if (mMusicRepository.getCurrentlyActiveTrack() >= 0) {
- sendBroadcast();
return;
}
mMusicRepository.setCurrentlyActiveTrack(-1);
@@ -197,8 +193,6 @@
updateNotification();
//relaxResources(false); // while paused, we always retain the MediaPlayer
// do not give up audio focus
-
- sendBroadcast();
}
}
@@ -215,8 +209,6 @@
relaxResources(true);
// service is no longer necessary. Will be started again if needed.
stopSelf();
-
- sendBroadcast();
}
}
@@ -236,11 +228,6 @@
}
}
- private void sendBroadcast() {
- Intent localIntent = new Intent(BROADCAST_ACTION);
- LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
- }
-
/**
* Releases resources used by the service for playback. This includes the "foreground service"
* status and notification, the wake locks and possibly the MediaPlayer.
@@ -271,7 +258,6 @@
if (!mMediaPlayer.isPlaying()) {
mMediaPlayer.start();
}
- sendBroadcast();
}
/**
@@ -393,6 +379,8 @@
}
private void updateNotification() {
+ // TODO - once b/33690035 is fixed, convert to have the service observe the LiveData
+ // object in our repository for the currently active track and update the notification.
TrackMetadata currTrack = mTracks.get(mMusicRepository.getCurrentlyActiveTrack());
populateNotificationBuilderContent(currTrack.getTitle()
+ " by " + currTrack.getArtist());
diff --git a/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/adapter/MusicTrackListAdapter.java b/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/adapter/MusicTrackListAdapter.java
new file mode 100644
index 0000000..de91560
--- /dev/null
+++ b/samples-flatfoot/MusicPlayer/app/src/main/java/com/android/sample/musicplayer/adapter/MusicTrackListAdapter.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.sample.musicplayer.adapter;
+
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.Adapter;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.android.sample.musicplayer.MusicRepository.TrackMetadata;
+import com.android.sample.musicplayer.R;
+
+import java.util.List;
+
+/**
+ * Adapter for the list of music tracks.
+ */
+public class MusicTrackListAdapter extends Adapter<MusicTrackListAdapter.CustomViewHolder> {
+ private final LayoutInflater mInflater;
+ private List<TrackMetadata> mTracks;
+ private int mActiveTrackIndex;
+
+ class CustomViewHolder extends RecyclerView.ViewHolder {
+ private ViewGroup mContainerView;
+ private TextView mIndexView;
+ private TextView mTextView;
+ private TextView mArtistView;
+
+ CustomViewHolder(View view) {
+ super(view);
+ this.mContainerView = (ViewGroup) view;
+ this.mIndexView = (TextView) view.findViewById(R.id.index);
+ this.mTextView = (TextView) view.findViewById(R.id.title);
+ this.mArtistView = (TextView) view.findViewById(R.id.artist);
+ }
+ }
+
+ public MusicTrackListAdapter(LayoutInflater inflater, List<TrackMetadata> tracks) {
+ mInflater = inflater;
+ mTracks = tracks;
+ }
+
+ @Override
+ public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View inflated = mInflater.inflate(R.layout.main_row, parent, false);
+ return new CustomViewHolder(inflated);
+ }
+
+ @Override
+ public void onBindViewHolder(CustomViewHolder holder, final int position) {
+ holder.mContainerView.setSelected(position == mActiveTrackIndex);
+ holder.mIndexView.setText(Integer.toString(position + 1));
+ holder.mTextView.setText(mTracks.get(position).getTitle());
+ holder.mArtistView.setText(mTracks.get(position).getArtist());
+ }
+
+ @Override
+ public int getItemCount() {
+ return mTracks.size();
+ }
+
+ public void setActiveTrackIndex(int activeTrackIndex) {
+ if (mActiveTrackIndex != activeTrackIndex) {
+ mActiveTrackIndex = activeTrackIndex;
+ notifyDataSetChanged();
+ }
+ }
+}
diff --git a/samples-flatfoot/MusicPlayer/build.gradle b/samples-flatfoot/MusicPlayer/build.gradle
index 7bf44de..5d6aefc 100644
--- a/samples-flatfoot/MusicPlayer/build.gradle
+++ b/samples-flatfoot/MusicPlayer/build.gradle
@@ -19,10 +19,10 @@
repositories {
jcenter()
maven {
- url "file://Volumes/android/ub-supportlib-flatfoot-master/out/host/gradle/frameworks/support/build/flatfoot_repo/"
+ url "file://Volumes/android/appToolkitRepository/"
}
maven {
- url "file://Volumes/android/ub-supportlib-flatfoot-master/prebuilts/fullsdk-darwin/extras/android/m2repository/"
+ url "file://Volumes/android/m2repository/"
}
}
}