diff --git a/res/layout/renderer_fragment.xml b/res/layout/renderer_fragment.xml
index 1c2c19a..9402d01 100644
--- a/res/layout/renderer_fragment.xml
+++ b/res/layout/renderer_fragment.xml
@@ -29,10 +29,21 @@
android:layout_height="wrap_content" >
+ android:text="@string/previous" />
+
+
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 84e7f4f..9b3ee99 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7,5 +7,7 @@
Play
Pause
Do you really want to exit the renderer? Playback will be stopped.
+ Previous
+ Next
diff --git a/src/com/github/nutomic/controldlna/DeviceArrayAdapter.java b/src/com/github/nutomic/controldlna/DeviceArrayAdapter.java
index 754ef03..0853c7f 100644
--- a/src/com/github/nutomic/controldlna/DeviceArrayAdapter.java
+++ b/src/com/github/nutomic/controldlna/DeviceArrayAdapter.java
@@ -1,5 +1,7 @@
package com.github.nutomic.controldlna;
+import java.util.Collection;
+
import org.teleal.cling.model.meta.Device;
import org.teleal.cling.model.meta.LocalDevice;
import org.teleal.cling.model.meta.RemoteDevice;
@@ -121,4 +123,13 @@ public class DeviceArrayAdapter extends ArrayAdapter>
}
});
}
+
+ /**
+ * Not implemented on lower API levels.
+ */
+ @Override
+ public void addAll(Collection extends Device, ?, ?>> collection) {
+ for (Device, ?, ?> d : collection)
+ add(d);
+ }
}
diff --git a/src/com/github/nutomic/controldlna/FileArrayAdapter.java b/src/com/github/nutomic/controldlna/FileArrayAdapter.java
index 008839c..bbadfc4 100644
--- a/src/com/github/nutomic/controldlna/FileArrayAdapter.java
+++ b/src/com/github/nutomic/controldlna/FileArrayAdapter.java
@@ -1,5 +1,7 @@
package com.github.nutomic.controldlna;
+import java.util.Collection;
+
import org.teleal.cling.support.model.DIDLObject;
import android.content.Context;
@@ -27,4 +29,13 @@ public class FileArrayAdapter extends ArrayAdapter {
return convertView;
}
+ /**
+ * Not implemented on lower API levels.
+ */
+ @Override
+ public void addAll(Collection extends DIDLObject> collection) {
+ for (DIDLObject d : collection)
+ add(d);
+ }
+
}
diff --git a/src/com/github/nutomic/controldlna/MainActivity.java b/src/com/github/nutomic/controldlna/MainActivity.java
index 2c2ad83..82e0cae 100644
--- a/src/com/github/nutomic/controldlna/MainActivity.java
+++ b/src/com/github/nutomic/controldlna/MainActivity.java
@@ -1,5 +1,7 @@
package com.github.nutomic.controldlna;
+import java.util.List;
+
import org.teleal.cling.support.model.item.Item;
import android.os.Bundle;
@@ -138,7 +140,7 @@ public class MainActivity extends SherlockFragmentActivity implements
/**
* Utility function to call RendererFragment.play from ServerFragment.
*/
- public void play(Item[] playlist, int start) {
+ public void play(List- playlist, int start) {
getSupportActionBar().selectTab(getSupportActionBar().getTabAt(0));
mRendererFragment.setPlaylist(playlist, start);
}
diff --git a/src/com/github/nutomic/controldlna/RendererFragment.java b/src/com/github/nutomic/controldlna/RendererFragment.java
index 95c179c..0fb8491 100644
--- a/src/com/github/nutomic/controldlna/RendererFragment.java
+++ b/src/com/github/nutomic/controldlna/RendererFragment.java
@@ -1,5 +1,7 @@
package com.github.nutomic.controldlna;
+import java.util.Collection;
+import java.util.List;
import java.util.Map;
import org.teleal.cling.android.AndroidUpnpService;
@@ -72,7 +74,9 @@ public class RendererFragment extends Fragment implements
private boolean mPlaying = false;
- private Item[] mPlaylist;
+ private int mCurrentTrack;
+
+ private List
- mPlaylist;
/**
* ListView adapter of media renderers.
@@ -103,14 +107,14 @@ public class RendererFragment extends Fragment implements
*/
private ServiceConnection mServiceConnection= new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
+ @SuppressWarnings("unchecked")
+ public void onServiceConnected(ComponentName className, IBinder service) {
mUpnpService = (AndroidUpnpService) service;
Log.i(TAG, "Starting device search");
mUpnpService.getRegistry().addListener(mRendererAdapter);
mUpnpService.getControlPoint().search();
- for (Device, ?, ?> d : mUpnpService
- .getControlPoint().getRegistry().getDevices())
- mRendererAdapter.add(d);
+ mRendererAdapter.addAll((Collection extends Device, ?, ?>>)
+ mUpnpService.getControlPoint().getRegistry().getDevices());
}
public void onServiceDisconnected(ComponentName className) {
@@ -131,6 +135,7 @@ public class RendererFragment extends Fragment implements
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mListView = (ListView) getView().findViewById(R.id.listview);
+ mPlaylistAdapter = new FileArrayAdapter(getActivity());
mRendererAdapter = new DeviceArrayAdapter(
getActivity(), DeviceArrayAdapter.RENDERER);
mListView.setAdapter(mRendererAdapter);
@@ -141,6 +146,8 @@ public class RendererFragment extends Fragment implements
mPlayPause = (Button) getView().findViewById(R.id.playpause);
mPlayPause.setOnClickListener(this);
mPlayPause.setText(R.string.play);
+ getView().findViewById(R.id.previous).setOnClickListener(this);
+ getView().findViewById(R.id.next).setOnClickListener(this);
getActivity().getApplicationContext().bindService(
new Intent(getActivity(), AndroidUpnpServiceImpl.class),
@@ -203,8 +210,10 @@ public class RendererFragment extends Fragment implements
/**
* Sets the new playlist and starts playing it (if a renderer is selected).
*/
- public void setPlaylist(Item[] playlist, int start) {
+ public void setPlaylist(List
- playlist, int start) {
mPlaylist = playlist;
+ mPlaylistAdapter.clear();
+ mPlaylistAdapter.addAll(playlist);
playTrack(start);
}
@@ -215,11 +224,12 @@ public class RendererFragment extends Fragment implements
private void playTrack(int track) {
if (mCurrentRenderer != null) {
mListView.setAdapter(mPlaylistAdapter);
+ mCurrentTrack = track;
final Service, ?> service = mCurrentRenderer.findService(
new ServiceType("schemas-upnp-org", "AVTransport"));
DIDLParser parser = new DIDLParser();
DIDLContent didl = new DIDLContent();
- didl.addItem(mPlaylist[track]);
+ didl.addItem(mPlaylist.get(track));
String metadata;
try {
metadata = parser.generate(didl, true);
@@ -229,7 +239,7 @@ public class RendererFragment extends Fragment implements
metadata = "NO METADATA";
}
mUpnpService.getControlPoint().execute(new SetAVTransportURI(service,
- mPlaylist[track].getFirstResource().getValue(), metadata) {
+ mPlaylist.get(track).getFirstResource().getValue(), metadata) {
@SuppressWarnings("rawtypes")
@Override
public void failure(ActionInvocation invocation,
@@ -337,6 +347,8 @@ public class RendererFragment extends Fragment implements
mListView.setAdapter(mPlaylistAdapter);
mControls.setVisibility(View.VISIBLE);
}
+ else if (mListView.getAdapter() == mPlaylistAdapter)
+ playTrack(position);
}
/**
@@ -373,7 +385,7 @@ public class RendererFragment extends Fragment implements
mSubscriptionCallback.end();
mListView.setAdapter(mRendererAdapter);
- mControls.setVisibility(View.GONE);
+ mControls.setVisibility(View.GONE);
}
/**
@@ -387,6 +399,15 @@ public class RendererFragment extends Fragment implements
pause();
else
play();
+ break;
+ case R.id.previous:
+ if (mCurrentTrack != 0 && !mPlaylist.isEmpty())
+ playTrack(--mCurrentTrack);
+ break;
+ case R.id.next:
+ if (mPlaylist.size() > mCurrentTrack + 1)
+ playTrack(++mCurrentTrack);
+ break;
}
}
diff --git a/src/com/github/nutomic/controldlna/ServerFragment.java b/src/com/github/nutomic/controldlna/ServerFragment.java
index 4d13df9..ff56b90 100644
--- a/src/com/github/nutomic/controldlna/ServerFragment.java
+++ b/src/com/github/nutomic/controldlna/ServerFragment.java
@@ -1,5 +1,8 @@
package com.github.nutomic.controldlna;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import java.util.Stack;
import org.teleal.cling.android.AndroidUpnpService;
@@ -73,14 +76,14 @@ public class ServerFragment extends ListFragment implements OnBackPressedListene
*/
private ServiceConnection mServiceConnection= new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
+ @SuppressWarnings("unchecked")
+ public void onServiceConnected(ComponentName className, IBinder service) {
mUpnpService = (AndroidUpnpService) service;
Log.i(TAG, "Starting device search");
mUpnpService.getRegistry().addListener(mServerAdapter);
mUpnpService.getControlPoint().search();
- for (Device, ?, ?> d : mUpnpService
- .getControlPoint().getRegistry().getDevices())
- mServerAdapter.add(d);
+ mServerAdapter.addAll((Collection extends Device, ?, ?>>)
+ mUpnpService.getControlPoint().getRegistry().getDevices());
}
public void onServiceDisconnected(ComponentName className) {
@@ -133,11 +136,10 @@ public class ServerFragment extends ListFragment implements OnBackPressedListene
getFiles(((Container) mFileAdapter.getItem(position)).getId());
}
else {
- Item[] playlist = new Item[mFileAdapter.getCount()];
+ List
- playlist = new ArrayList
- ();
for (int i = 0; i < mFileAdapter.getCount(); i++) {
- if (mFileAdapter.getItem(i) instanceof Item) {
- playlist[i] = (Item) mFileAdapter.getItem(position);
- }
+ if (mFileAdapter.getItem(i) instanceof Item)
+ playlist.add((Item) mFileAdapter.getItem(i));
}
MainActivity activity = (MainActivity) getActivity();
activity.play(playlist, position);