Removed trailing whitespaces, replaced space intendation with tabs.

This commit is contained in:
Felix Ableitner 2014-02-08 21:16:30 +01:00
parent 10e5f86ecf
commit 2314e895d1
14 changed files with 1428 additions and 1437 deletions

View file

@ -4,12 +4,12 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
@ -65,62 +65,62 @@ public class MainActivity extends ActionBarActivity {
/**
* Interface which allows listening to "back" button presses.
*/
public interface OnBackPressedListener {
public interface OnBackPressedListener {
boolean onBackPressed();
}
}
FragmentStatePagerAdapter mSectionsPagerAdapter =
new FragmentStatePagerAdapter(getSupportFragmentManager()) {
FragmentStatePagerAdapter mSectionsPagerAdapter =
new FragmentStatePagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
switch (position) {
case 0: return mServerFragment;
case 1: return mRouteFragment;
default: return null;
}
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0: return mServerFragment;
case 1: return mRouteFragment;
default: return null;
}
}
@Override
public int getCount() {
return 2;
}
@Override
public int getCount() {
return 2;
}
};
};
private ServerFragment mServerFragment;
private ServerFragment mServerFragment;
private RouteFragment mRouteFragment;
private RouteFragment mRouteFragment;
ViewPager mViewPager;
ViewPager mViewPager;
/**
* Initializes tab navigation. If wifi is not connected,
* shows a warning dialog.
*/
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ActionBar actionBar = getSupportActionBar();
/**
* Initializes tab navigation. If wifi is not connected,
* shows a warning dialog.
*/
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowHomeEnabled(false);
setContentView(R.layout.activity_main);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowHomeEnabled(false);
setContentView(R.layout.activity_main);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
TabListener tabListener = new ActionBar.TabListener() {
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
}
TabListener tabListener = new ActionBar.TabListener() {
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabReselected(Tab arg0, FragmentTransaction arg1) {
@ -129,111 +129,111 @@ public class MainActivity extends ActionBarActivity {
@Override
public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {
}
};
};
actionBar.addTab(actionBar.newTab()
.setText(R.string.title_server)
.setTabListener(tabListener));
actionBar.addTab(actionBar.newTab()
.setText(R.string.title_route)
.setTabListener(tabListener));
actionBar.addTab(actionBar.newTab()
.setText(R.string.title_server)
.setTabListener(tabListener));
actionBar.addTab(actionBar.newTab()
.setText(R.string.title_route)
.setTabListener(tabListener));
ConnectivityManager connManager = (ConnectivityManager)
getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo wifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final SharedPreferences prefs = getSharedPreferences("preferences.db", 0);
ConnectivityManager connManager = (ConnectivityManager)
getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo wifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final SharedPreferences prefs = getSharedPreferences("preferences.db", 0);
if (!wifi.isConnected() && !prefs.getBoolean("wifi_skip_dialog", false)) {
View checkBoxView = View.inflate(this, R.layout.dialog_wifi_disabled, null);
CheckBox checkBox = (CheckBox) checkBoxView.findViewById(R.id.dont_show_again);
checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
if (!wifi.isConnected() && !prefs.getBoolean("wifi_skip_dialog", false)) {
View checkBoxView = View.inflate(this, R.layout.dialog_wifi_disabled, null);
CheckBox checkBox = (CheckBox) checkBoxView.findViewById(R.id.dont_show_again);
checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
prefs.edit().putBoolean("wifi_skip_dialog", isChecked)
.commit();
}
});
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
prefs.edit().putBoolean("wifi_skip_dialog", isChecked)
.commit();
}
});
new AlertDialog.Builder(this)
.setView(checkBoxView)
.setTitle(R.string.warning_wifi_not_connected)
.setPositiveButton(android.R.string.ok, null)
.show();
}
new AlertDialog.Builder(this)
.setView(checkBoxView)
.setTitle(R.string.warning_wifi_not_connected)
.setPositiveButton(android.R.string.ok, null)
.show();
}
if (savedInstanceState != null) {
FragmentManager fm = getSupportFragmentManager();
mServerFragment = (ServerFragment) fm.getFragment(
savedInstanceState, ServerFragment.class.getName());
mRouteFragment = (RouteFragment) fm.getFragment(
savedInstanceState, RouteFragment.class.getName());
mViewPager.setCurrentItem(savedInstanceState.getInt("currentTab"));
}
else {
mServerFragment = new ServerFragment();
mRouteFragment = new RouteFragment();
}
onNewIntent(getIntent());
}
if (savedInstanceState != null) {
FragmentManager fm = getSupportFragmentManager();
mServerFragment = (ServerFragment) fm.getFragment(
savedInstanceState, ServerFragment.class.getName());
mRouteFragment = (RouteFragment) fm.getFragment(
savedInstanceState, RouteFragment.class.getName());
mViewPager.setCurrentItem(savedInstanceState.getInt("currentTab"));
}
else {
mServerFragment = new ServerFragment();
mRouteFragment = new RouteFragment();
}
onNewIntent(getIntent());
}
/**
* Displays the RouteFragment immediately (instead of ServerFragment).
*/
/**
* Displays the RouteFragment immediately (instead of ServerFragment).
*/
@Override
protected void onNewIntent(Intent intent) {
if (intent.getAction().equals("showRouteFragment"))
mViewPager.setCurrentItem(1);
mViewPager.setCurrentItem(1);
}
/**
* Saves fragments.
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
FragmentManager fm = getSupportFragmentManager();
fm.putFragment(outState, ServerFragment.class.getName(), mServerFragment);
fm.putFragment(outState, RouteFragment.class.getName(), mRouteFragment);
outState.putInt("currentTab", mViewPager.getCurrentItem());
}
/**
* Saves fragments.
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
FragmentManager fm = getSupportFragmentManager();
fm.putFragment(outState, ServerFragment.class.getName(), mServerFragment);
fm.putFragment(outState, RouteFragment.class.getName(), mRouteFragment);
outState.putInt("currentTab", mViewPager.getCurrentItem());
}
/**
* Forwards back press to active Fragment (unless the fragment is
* showing its root view).
*/
@Override
public void onBackPressed() {
OnBackPressedListener currentFragment = (OnBackPressedListener)
mSectionsPagerAdapter.getItem(mViewPager.getCurrentItem());
if (!currentFragment.onBackPressed())
super.onBackPressed();
}
/**
* Forwards back press to active Fragment (unless the fragment is
* showing its root view).
*/
@Override
public void onBackPressed() {
OnBackPressedListener currentFragment = (OnBackPressedListener)
mSectionsPagerAdapter.getItem(mViewPager.getCurrentItem());
if (!currentFragment.onBackPressed())
super.onBackPressed();
}
/**
* Changes volume on key press (via RouteFragment).
*/
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_VOLUME_UP:
if (event.getAction() == KeyEvent.ACTION_DOWN)
mRouteFragment.increaseVolume();
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
if (event.getAction() == KeyEvent.ACTION_DOWN)
mRouteFragment.decreaseVolume();
return true;
default:
return super.dispatchKeyEvent(event);
}
}
/**
* Changes volume on key press (via RouteFragment).
*/
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_VOLUME_UP:
if (event.getAction() == KeyEvent.ACTION_DOWN)
mRouteFragment.increaseVolume();
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
if (event.getAction() == KeyEvent.ACTION_DOWN)
mRouteFragment.decreaseVolume();
return true;
default:
return super.dispatchKeyEvent(event);
}
}
/**
* Starts playing the playlist from item start (via RouteFragment).
*/
/**
* Starts playing the playlist from item start (via RouteFragment).
*/
public void play(List<Item> playlist, int start) {
mViewPager.setCurrentItem(1);
mViewPager.setCurrentItem(1);
mRouteFragment.play(playlist, start);
}

View file

@ -4,12 +4,12 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
@ -128,172 +128,171 @@ public class RouteFragment extends MediaRouteDiscoveryFragment implements
applyColors();
if (mRestorePlaylistMode)
playlistMode(mMediaRouterPlayService.getService().getCurrentRoute());
}
}
public void onServiceDisconnected(ComponentName className) {
mMediaRouterPlayService = null;
}
};
public void onServiceDisconnected(ComponentName className) {
mMediaRouterPlayService = null;
}
};
/**
* Selects remote playback route category.
*/
public RouteFragment() {
MediaRouteSelector mSelector = new MediaRouteSelector.Builder()
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
.build();
setRouteSelector(mSelector);
/**
* Selects remote playback route category.
*/
public RouteFragment() {
MediaRouteSelector mSelector = new MediaRouteSelector.Builder()
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
.build();
setRouteSelector(mSelector);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.route_fragment, null);
return inflater.inflate(R.layout.route_fragment, null);
};
/**
* Initializes views, connects to service, adds default route.
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mRouteAdapter = new RouteAdapter(getActivity());
mRouteAdapter.add(MediaRouter.getInstance(getActivity()).getRoutes());
mRouteAdapter.remove(MediaRouter.getInstance(getActivity()).getDefaultRoute());
mPlaylistAdapter = new FileArrayAdapter(getActivity());
mRouteAdapter = new RouteAdapter(getActivity());
mRouteAdapter.add(MediaRouter.getInstance(getActivity()).getRoutes());
mRouteAdapter.remove(MediaRouter.getInstance(getActivity()).getDefaultRoute());
mPlaylistAdapter = new FileArrayAdapter(getActivity());
mListView = (ListView) getView().findViewById(R.id.listview);
mListView.setAdapter(mRouteAdapter);
mListView.setOnItemClickListener(this);
mListView = (ListView) getView().findViewById(R.id.listview);
mListView.setAdapter(mRouteAdapter);
mListView.setOnItemClickListener(this);
mListView.setOnScrollListener(this);
mListView.setEmptyView(getView().findViewById(android.R.id.empty));
mControls = getView().findViewById(R.id.controls);
mProgressBar = (SeekBar) getView().findViewById(R.id.progressBar);
mProgressBar.setOnSeekBarChangeListener(this);
mControls = getView().findViewById(R.id.controls);
mProgressBar = (SeekBar) getView().findViewById(R.id.progressBar);
mProgressBar.setOnSeekBarChangeListener(this);
mShuffle = (ImageButton) getView().findViewById(R.id.shuffle);
mShuffle.setImageResource(R.drawable.ic_action_shuffle);
mShuffle.setOnClickListener(this);
mShuffle = (ImageButton) getView().findViewById(R.id.shuffle);
mShuffle.setImageResource(R.drawable.ic_action_shuffle);
mShuffle.setOnClickListener(this);
ImageButton previous = (ImageButton) getView().findViewById(R.id.previous);
previous.setImageResource(R.drawable.ic_action_previous);
previous.setOnClickListener(this);
ImageButton previous = (ImageButton) getView().findViewById(R.id.previous);
previous.setImageResource(R.drawable.ic_action_previous);
previous.setOnClickListener(this);
ImageButton next = (ImageButton) getView().findViewById(R.id.next);
next.setImageResource(R.drawable.ic_action_next);
next.setOnClickListener(this);
ImageButton next = (ImageButton) getView().findViewById(R.id.next);
next.setImageResource(R.drawable.ic_action_next);
next.setOnClickListener(this);
mRepeat = (ImageButton) getView().findViewById(R.id.repeat);
mRepeat.setImageResource(R.drawable.ic_action_repeat);
mRepeat.setOnClickListener(this);
mRepeat = (ImageButton) getView().findViewById(R.id.repeat);
mRepeat.setImageResource(R.drawable.ic_action_repeat);
mRepeat.setOnClickListener(this);
mPlayPause = (ImageButton) getView().findViewById(R.id.playpause);
mPlayPause.setOnClickListener(this);
mPlayPause.setImageResource(R.drawable.ic_action_play);
mPlayPause = (ImageButton) getView().findViewById(R.id.playpause);
mPlayPause.setOnClickListener(this);
mPlayPause.setImageResource(R.drawable.ic_action_play);
mCurrentTimeView = (TextView) getView().findViewById(R.id.current_time);
mTotalTimeView = (TextView) getView().findViewById(R.id.total_time);
mCurrentTimeView = (TextView) getView().findViewById(R.id.current_time);
mTotalTimeView = (TextView) getView().findViewById(R.id.total_time);
getActivity().getApplicationContext().startService(
new Intent(getActivity(), MediaRouterPlayService.class));
getActivity().getApplicationContext().bindService(
new Intent(getActivity(), MediaRouterPlayService.class),
mPlayServiceConnection,
Context.BIND_AUTO_CREATE
);
getActivity().getApplicationContext().startService(
new Intent(getActivity(), MediaRouterPlayService.class));
getActivity().getApplicationContext().bindService(
new Intent(getActivity(), MediaRouterPlayService.class),
mPlayServiceConnection,
Context.BIND_AUTO_CREATE
);
if (savedInstanceState != null) {
mListView.onRestoreInstanceState(savedInstanceState.getParcelable("list_state"));
mRestorePlaylistMode = savedInstanceState.getBoolean("route_selected");
}
}
if (savedInstanceState != null) {
mListView.onRestoreInstanceState(savedInstanceState.getParcelable("list_state"));
mRestorePlaylistMode = savedInstanceState.getBoolean("route_selected");
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("route_selected", mSelectedRoute != null);
outState.putParcelable("list_state", mListView.onSaveInstanceState());
}
outState.putBoolean("route_selected", mSelectedRoute != null);
outState.putParcelable("list_state", mListView.onSaveInstanceState());
}
@Override
public void onDestroy() {
super.onDestroy();
getActivity().getApplicationContext().unbindService(mPlayServiceConnection);
}
@Override
public void onDestroy() {
super.onDestroy();
getActivity().getApplicationContext().unbindService(mPlayServiceConnection);
}
/**
* Starts active route discovery (which is automatically stopped on
* fragment stop by parent class).
*/
@Override
public int onPrepareCallbackFlags() {
return MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY
| MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN;
}
/**
* Starts active route discovery (which is automatically stopped on
* fragment stop by parent class).
*/
@Override
public int onPrepareCallbackFlags() {
return MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY
| MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN;
}
@Override
public Callback onCreateCallback() {
return new MediaRouter.Callback() {
@Override
public void onRouteAdded(MediaRouter router, RouteInfo route) {
for (int i = 0; i < mRouteAdapter.getCount(); i++) {
if (mRouteAdapter.getItem(i).getId().equals(route.getId())) {
mRouteAdapter.remove(mRouteAdapter.getItem(i));
break;
}
}
mRouteAdapter.add(route);
}
@Override
public Callback onCreateCallback() {
return new MediaRouter.Callback() {
@Override
public void onRouteAdded(MediaRouter router, RouteInfo route) {
for (int i = 0; i < mRouteAdapter.getCount(); i++)
if (mRouteAdapter.getItem(i).getId().equals(route.getId())) {
mRouteAdapter.remove(mRouteAdapter.getItem(i));
break;
}
mRouteAdapter.add(route);
}
@Override
public void onRouteChanged(MediaRouter router, RouteInfo route) {
mRouteAdapter.notifyDataSetChanged();
}
@Override
public void onRouteChanged(MediaRouter router, RouteInfo route) {
mRouteAdapter.notifyDataSetChanged();
}
@Override
public void onRouteRemoved(MediaRouter router, RouteInfo route) {
mRouteAdapter.remove(route);
if (route.equals(mSelectedRoute)) {
mPlaying = false;
onBackPressed();
}
}
@Override
public void onRouteRemoved(MediaRouter router, RouteInfo route) {
mRouteAdapter.remove(route);
if (route.equals(mSelectedRoute)) {
mPlaying = false;
onBackPressed();
}
}
@Override
public void onRouteSelected(MediaRouter router, RouteInfo route) {
}
@Override
public void onRouteSelected(MediaRouter router, RouteInfo route) {
}
@Override
public void onRouteUnselected(MediaRouter router, RouteInfo route) {
}
@Override
public void onRouteUnselected(MediaRouter router, RouteInfo route) {
}
@Override
public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) {
}
@Override
public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) {
}
@Override
public void onRoutePresentationDisplayChanged(
MediaRouter router, RouteInfo route) {
}
@Override
public void onRoutePresentationDisplayChanged(
MediaRouter router, RouteInfo route) {
}
@Override
public void onProviderAdded(MediaRouter router, ProviderInfo provider) {
}
@Override
public void onProviderAdded(MediaRouter router, ProviderInfo provider) {
}
@Override
public void onProviderRemoved(MediaRouter router, ProviderInfo provider) {
}
@Override
public void onProviderRemoved(MediaRouter router, ProviderInfo provider) {
}
@Override
public void onProviderChanged(MediaRouter router, ProviderInfo provider) {
}
};
@Override
public void onProviderChanged(MediaRouter router, ProviderInfo provider) {
}
};
}
}
/**
* Selects a route or starts playback (depending on current ListAdapter).
@ -367,25 +366,24 @@ public class RouteFragment extends MediaRouteDiscoveryFragment implements
@Override
public boolean onBackPressed() {
if (mListView.getAdapter() == mPlaylistAdapter) {
if (mPlaying) {
if (mPlaying)
new AlertDialog.Builder(getActivity())
.setMessage(R.string.exit_renderer)
.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
.setMessage(R.string.exit_renderer)
.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
mMediaRouterPlayService.getService().stop();
deviceListMode();
}
})
.setNegativeButton(android.R.string.no, null)
.show();
}
@Override
public void onClick(DialogInterface dialog,
int which) {
mMediaRouterPlayService.getService().stop();
deviceListMode();
}
})
.setNegativeButton(android.R.string.no, null)
.show();
else
deviceListMode();
return true;
return true;
}
return false;
}
@ -413,24 +411,24 @@ public class RouteFragment extends MediaRouteDiscoveryFragment implements
break;
case R.id.previous:
mPreviousTapCount++;
Handler handler = new Handler();
Runnable r = new Runnable() {
Handler handler = new Handler();
Runnable r = new Runnable() {
@Override
public void run() {
// Single tap.
mPreviousTapCount = 0;
s.play(s.getCurrentTrack());
changePlayPauseState(true);
}
};
if (mPreviousTapCount == 1)
handler.postDelayed(r, ViewConfiguration.getDoubleTapTimeout());
else if(mPreviousTapCount == 2) {
// Double tap.
mPreviousTapCount = 0;
s.playPrevious();
}
@Override
public void run() {
// Single tap.
mPreviousTapCount = 0;
s.play(s.getCurrentTrack());
changePlayPauseState(true);
}
};
if (mPreviousTapCount == 1)
handler.postDelayed(r, ViewConfiguration.getDoubleTapTimeout());
else if(mPreviousTapCount == 2) {
// Double tap.
mPreviousTapCount = 0;
s.playPrevious();
}
break;
case R.id.next:
boolean stillPlaying = s.playNext();
@ -454,10 +452,10 @@ public class RouteFragment extends MediaRouteDiscoveryFragment implements
mShuffle.setColorFilter((s.getShuffleEnabled())
? highlight
: transparent);
: transparent);
mRepeat.setColorFilter((s.getRepeatEnabled())
? highlight
: transparent);
: transparent);
}
/**
@ -512,7 +510,7 @@ public class RouteFragment extends MediaRouteDiscoveryFragment implements
changePlayPauseState(true);
} else {
Toast.makeText(getActivity(), R.string.select_route, Toast.LENGTH_SHORT)
.show();
.show();
mStartPlayingOnSelect = start;
}
}
@ -525,14 +523,14 @@ public class RouteFragment extends MediaRouteDiscoveryFragment implements
*/
private String generateTimeString(int time) {
assert(time >= 0);
int seconds = (int) time % 60;
int minutes = (int) time / 60;
int seconds = time % 60;
int minutes = time / 60;
if (minutes > 99)
return "99:99";
else
return Integer.toString(minutes) + ":" +
((seconds > 9)
? seconds
((seconds > 9)
? seconds
: "0" + Integer.toString(seconds));
}

View file

@ -4,12 +4,12 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
@ -112,210 +112,209 @@ public class ServerFragment extends ListFragment implements OnBackPressedListene
*/
private Stack<Parcelable> mListState = new Stack<Parcelable>();
protected AndroidUpnpService mUpnpService;
protected AndroidUpnpService mUpnpService;
private ServiceConnection mUpnpServiceConnection = new ServiceConnection() {
private ServiceConnection mUpnpServiceConnection = new ServiceConnection() {
/**
* Registers DeviceListener, adds known devices and starts search if requested.
*/
/**
* Registers DeviceListener, adds known devices and starts search if requested.
*/
public void onServiceConnected(ComponentName className, IBinder service) {
mUpnpService = (AndroidUpnpService) service;
mUpnpService.getRegistry().addListener(mServerAdapter);
for (Device<?, ?, ?> d : mUpnpService.getControlPoint().getRegistry().getDevices())
mServerAdapter.deviceAdded(d);
mUpnpService.getControlPoint().search();
mUpnpService = (AndroidUpnpService) service;
mUpnpService.getRegistry().addListener(mServerAdapter);
for (Device<?, ?, ?> d : mUpnpService.getControlPoint().getRegistry().getDevices())
mServerAdapter.deviceAdded(d);
mUpnpService.getControlPoint().search();
if (mRestoreServer != null) {
mCurrentServer = mUpnpService.getControlPoint().getRegistry()
.getDevice(new UDN(mRestoreServer.replace("uuid:", "")), false);
if (mCurrentServer != null) {
setListAdapter(mFileAdapter);
// Duplicate the top element because getFiles will remove it.
mListState.add(mListState.peek());
getFiles(true);
}
if (mRestoreServer != null) {
mCurrentServer = mUpnpService.getControlPoint().getRegistry()
.getDevice(new UDN(mRestoreServer.replace("uuid:", "")), false);
if (mCurrentServer != null) {
setListAdapter(mFileAdapter);
// Duplicate the top element because getFiles will remove it.
mListState.add(mListState.peek());
getFiles(true);
}
getListView().onRestoreInstanceState(mListState.peek());
}
}
getListView().onRestoreInstanceState(mListState.peek());
}
}
public void onServiceDisconnected(ComponentName className) {
mUpnpService = null;
}
};
public void onServiceDisconnected(ComponentName className) {
mUpnpService = null;
}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.server_fragment, null);
return inflater.inflate(R.layout.server_fragment, null);
};
/**
* Initializes ListView adapters, launches Cling UPNP service, registers
* wifi state change listener and restores instance state if possible.
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mFileAdapter = new FileArrayAdapter(getActivity());
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mFileAdapter = new FileArrayAdapter(getActivity());
mServerAdapter = new DeviceArrayAdapter(
getActivity(), DeviceArrayAdapter.SERVER);
setListAdapter(mServerAdapter);
getActivity().getApplicationContext().bindService(
new Intent(getActivity(), AndroidUpnpServiceImpl.class),
mUpnpServiceConnection,
Context.BIND_AUTO_CREATE
);
mServerAdapter = new DeviceArrayAdapter(
getActivity(), DeviceArrayAdapter.SERVER);
setListAdapter(mServerAdapter);
getActivity().getApplicationContext().bindService(
new Intent(getActivity(), AndroidUpnpServiceImpl.class),
mUpnpServiceConnection,
Context.BIND_AUTO_CREATE
);
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
getActivity().registerReceiver(mWifiReceiver, filter);
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
getActivity().registerReceiver(mWifiReceiver, filter);
if (savedInstanceState != null) {
mRestoreServer = savedInstanceState.getString("current_server");
mCurrentPath.addAll(savedInstanceState.getStringArrayList("path"));
mListState.addAll(savedInstanceState.getParcelableArrayList("list_state"));
} else
mListState.push(getListView().onSaveInstanceState());
}
if (savedInstanceState != null) {
mRestoreServer = savedInstanceState.getString("current_server");
mCurrentPath.addAll(savedInstanceState.getStringArrayList("path"));
mListState.addAll(savedInstanceState.getParcelableArrayList("list_state"));
} else
mListState.push(getListView().onSaveInstanceState());
}
/**
* Stores current server and path/list state stacks.
*/
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("current_server", (mCurrentServer != null)
? mCurrentServer.getIdentity().getUdn().toString()
: "");
outState.putStringArrayList("path", new ArrayList<String>(mCurrentPath));
mListState.pop();
mListState.push(getListView().onSaveInstanceState());
outState.putParcelableArrayList("list_state", new ArrayList<Parcelable>(mListState));
}
/**
* Stores current server and path/list state stacks.
*/
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("current_server", (mCurrentServer != null)
? mCurrentServer.getIdentity().getUdn().toString()
: "");
outState.putStringArrayList("path", new ArrayList<String>(mCurrentPath));
mListState.pop();
mListState.push(getListView().onSaveInstanceState());
outState.putParcelableArrayList("list_state", new ArrayList<Parcelable>(mListState));
}
@Override
public void onDestroy() {
super.onDestroy();
getActivity().getApplicationContext().unbindService(mUpnpServiceConnection);
getActivity().unregisterReceiver(mWifiReceiver);
}
@Override
public void onDestroy() {
super.onDestroy();
getActivity().getApplicationContext().unbindService(mUpnpServiceConnection);
getActivity().unregisterReceiver(mWifiReceiver);
}
/**
* Enters directory browsing mode or enters a deeper level directory.
*/
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
if (getListAdapter() == mServerAdapter)
browsingMode(mServerAdapter.getItem(position));
else if (getListAdapter() == mFileAdapter) {
if (mFileAdapter.getItem(position) instanceof Container)
getFiles(((Container) mFileAdapter.getItem(position)).getId());
else {
List<Item> playlist = new ArrayList<Item>();
for (int i = 0; i < mFileAdapter.getCount(); i++) {
if (mFileAdapter.getItem(i) instanceof Item)
playlist.add((Item) mFileAdapter.getItem(i));
}
MainActivity activity = (MainActivity) getActivity();
activity.play(playlist, position);
}
}
}
/**
* Enters directory browsing mode or enters a deeper level directory.
*/
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
if (getListAdapter() == mServerAdapter)
browsingMode(mServerAdapter.getItem(position));
else if (getListAdapter() == mFileAdapter)
if (mFileAdapter.getItem(position) instanceof Container)
getFiles(((Container) mFileAdapter.getItem(position)).getId());
else {
List<Item> playlist = new ArrayList<Item>();
for (int i = 0; i < mFileAdapter.getCount(); i++)
if (mFileAdapter.getItem(i) instanceof Item)
playlist.add((Item) mFileAdapter.getItem(i));
MainActivity activity = (MainActivity) getActivity();
activity.play(playlist, position);
}
}
/**
* Displays available servers in the ListView.
*/
private void serverMode() {
/**
* Displays available servers in the ListView.
*/
private void serverMode() {
setListAdapter(mServerAdapter);
mCurrentServer = null;
TextView emptyView = (TextView) getListView().getEmptyView();
emptyView.setText(R.string.device_list_empty);
getListView().onRestoreInstanceState(mListState.pop());
}
}
/**
* Displays files for server (starting from root).
*/
private void browsingMode(Device<?, ?, ?> server) {
/**
* Displays files for server (starting from root).
*/
private void browsingMode(Device<?, ?, ?> server) {
setListAdapter(mFileAdapter);
mCurrentServer = server;
getFiles(ROOT_DIRECTORY);
TextView emptyView = (TextView) getListView().getEmptyView();
emptyView.setText(R.string.folder_list_empty);
}
/**
* Opens a new directory and displays it.
*/
private void getFiles(String directory) {
mListState.push(getListView().onSaveInstanceState());
mCurrentPath.push(directory);
getFiles(false);
}
}
/**
* Displays the current directory on the ListView.
*
* @param restoreListState True if we are going back up the directory tree,
* which means we restore scroll position etc. This pops
* mListState.
*/
private void getFiles(final boolean restoreListState) {
if (mCurrentServer == null)
return;
/**
* Opens a new directory and displays it.
*/
private void getFiles(String directory) {
mListState.push(getListView().onSaveInstanceState());
mCurrentPath.push(directory);
getFiles(false);
}
Service<?, ?> service = mCurrentServer.findService(
new ServiceType("schemas-upnp-org", "ContentDirectory"));
mUpnpService.getControlPoint().execute(new Browse(service,
/**
* Displays the current directory on the ListView.
*
* @param restoreListState True if we are going back up the directory tree,
* which means we restore scroll position etc. This pops
* mListState.
*/
private void getFiles(final boolean restoreListState) {
if (mCurrentServer == null)
return;
Service<?, ?> service = mCurrentServer.findService(
new ServiceType("schemas-upnp-org", "ContentDirectory"));
mUpnpService.getControlPoint().execute(new Browse(service,
mCurrentPath.peek(), BrowseFlag.DIRECT_CHILDREN) {
@SuppressWarnings("rawtypes")
@Override
public void received(ActionInvocation actionInvocation,
final DIDLContent didl) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mFileAdapter.clear();
for (Container c : didl.getContainers())
mFileAdapter.add(c);
for (Item i : didl.getItems())
mFileAdapter.add(i);
if (restoreListState)
getListView().onRestoreInstanceState(mListState.pop());
else
getListView().setSelectionFromTop(0, 0);
}
});
}
@SuppressWarnings("rawtypes")
@Override
public void received(ActionInvocation actionInvocation,
final DIDLContent didl) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void updateStatus(Status status) {
public void run() {
mFileAdapter.clear();
for (Container c : didl.getContainers())
mFileAdapter.add(c);
for (Item i : didl.getItems())
mFileAdapter.add(i);
if (restoreListState)
getListView().onRestoreInstanceState(mListState.pop());
else
getListView().setSelectionFromTop(0, 0);
}
@SuppressWarnings("rawtypes")
@Override
public void failure(ActionInvocation actionInvocation,
UpnpResponse operation, String defaultMessage) {
Log.w(TAG, "Failed to load directory contents: " +
defaultMessage);
}
});
}
}
/**
* Handles back button press to traverse directories (while browsing
* directories).
*/
@Override
public void updateStatus(Status status) {
}
@SuppressWarnings("rawtypes")
@Override
public void failure(ActionInvocation actionInvocation,
UpnpResponse operation, String defaultMessage) {
Log.w(TAG, "Failed to load directory contents: " +
defaultMessage);
}
});
}
/**
* Handles back button press to traverse directories (while browsing
* directories).
*/
public boolean onBackPressed() {
if (getListAdapter() == mServerAdapter)
return false;
if (getListAdapter() == mServerAdapter)
return false;
mCurrentPath.pop();
if (mCurrentPath.empty())
@ -331,37 +330,35 @@ public class ServerFragment extends ListFragment implements OnBackPressedListene
*/
private BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
getActivity();
@Override
public void onReceive(Context context, Intent intent) {
getActivity();
ConnectivityManager connManager = (ConnectivityManager)
getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo wifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo wifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (wifi.isConnected()) {
if (mUpnpService != null) {
for (Device<?, ?, ?> d : mUpnpService.getControlPoint()
.getRegistry().getDevices())
mServerAdapter.deviceAdded(d);
mUpnpService.getControlPoint().search();
}
}
else {
for (int i = 0; i < mServerAdapter.getCount(); i++) {
Device<?, ?, ?> d = mServerAdapter.getItem(i);
UDN udn = new UDN(d.getIdentity().getUdn().toString());
if (mUpnpService.getControlPoint().getRegistry()
.getDevice(udn, false) == null) {
mServerAdapter.deviceRemoved(d);
if (d.equals(mCurrentServer)) {
mListState.setSize(2);
mCurrentPath.clear();
serverMode();
}
}
}
}
}
if (wifi.isConnected()) {
if (mUpnpService != null) {
for (Device<?, ?, ?> d : mUpnpService.getControlPoint()
.getRegistry().getDevices())
mServerAdapter.deviceAdded(d);
mUpnpService.getControlPoint().search();
}
} else
for (int i = 0; i < mServerAdapter.getCount(); i++) {
Device<?, ?, ?> d = mServerAdapter.getItem(i);
UDN udn = new UDN(d.getIdentity().getUdn().toString());
if (mUpnpService.getControlPoint().getRegistry()
.getDevice(udn, false) == null) {
mServerAdapter.deviceRemoved(d);
if (d.equals(mCurrentServer)) {
mListState.setSize(2);
mCurrentPath.clear();
serverMode();
}
}
}
}
};
}

View file

@ -4,12 +4,12 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
@ -118,7 +118,7 @@ public class MediaRouterPlayService extends Service {
if (route.equals(mCurrentRoute))
stopForeground(true);
}
};
};
/**
* Creates a notification after the icon bitmap is loaded.
@ -132,16 +132,16 @@ public class MediaRouterPlayService extends Service {
if (mCurrentTrack < mPlaylist.size()) {
title = mPlaylist.get(mCurrentTrack).getTitle();
if (mPlaylist.get(mCurrentTrack) instanceof MusicTrack) {
MusicTrack track = (MusicTrack) mPlaylist.get(mCurrentTrack);
if (track.getArtists().length > 0)
artist = track.getArtists()[0].getName();
MusicTrack track = (MusicTrack) mPlaylist.get(mCurrentTrack);
if (track.getArtists().length > 0)
artist = track.getArtists()[0].getName();
}
}
Intent intent = new Intent(MediaRouterPlayService.this, MainActivity.class);
intent.setAction("showRouteFragment");
Notification notification = new NotificationCompat.Builder(MediaRouterPlayService.this)
.setContentIntent(PendingIntent.getActivity(MediaRouterPlayService.this, 0,
intent, 0))
.setContentIntent(PendingIntent.getActivity(MediaRouterPlayService.this, 0,
intent, 0))
.setContentTitle(title)
.setContentText(artist)
.setLargeIcon(result)
@ -156,7 +156,7 @@ public class MediaRouterPlayService extends Service {
@Override
public void onCreate() {
super.onCreate();
mMediaRouter = MediaRouter.getInstance(this);
mMediaRouter = MediaRouter.getInstance(this);
pollStatus();
}
@ -174,9 +174,9 @@ public class MediaRouterPlayService extends Service {
public boolean onUnbind(Intent intent) {
new Handler().postDelayed(new Runnable() {
public void run() {
if (!mPollingStatus && !mBound)
if (!mPollingStatus && !mBound)
stopSelf();
}
}
}, 5000);
mBound = false;
return super.onUnbind(intent);
@ -189,12 +189,12 @@ public class MediaRouterPlayService extends Service {
public void selectRoute(RouteInfo route) {
mMediaRouter.removeCallback(mRouteRemovedCallback);
mMediaRouter.selectRoute(route);
MediaRouteSelector selector = new MediaRouteSelector.Builder()
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
.build();
MediaRouteSelector selector = new MediaRouteSelector.Builder()
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
.build();
mMediaRouter.addCallback(selector, mRouteRemovedCallback, 0);
mCurrentRoute = route;
mMediaRouter.addCallback(selector, mRouteRemovedCallback, 0);
mCurrentRoute = route;
}
public void sendControlRequest(Intent intent) {
@ -211,7 +211,7 @@ public class MediaRouterPlayService extends Service {
mCurrentTrack = trackNumber;
Item track = mPlaylist.get(trackNumber);
DIDLParser parser = new DIDLParser();
DIDLParser parser = new DIDLParser();
DIDLContent didl = new DIDLContent();
didl.addItem(track);
String metadata = "";
@ -222,26 +222,26 @@ public class MediaRouterPlayService extends Service {
Log.w(TAG, "Metadata generation failed", e);
}
Intent intent = new Intent(MediaControlIntent.ACTION_PLAY);
intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
intent.setData(Uri.parse(track.getFirstResource().getValue()));
intent.putExtra(MediaControlIntent.EXTRA_ITEM_METADATA, metadata);
Intent intent = new Intent(MediaControlIntent.ACTION_PLAY);
intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
intent.setData(Uri.parse(track.getFirstResource().getValue()));
intent.putExtra(MediaControlIntent.EXTRA_ITEM_METADATA, metadata);
mMediaRouter.getSelectedRoute().sendControlRequest(intent,
new ControlRequestCallback() {
@Override
public void onResult(Bundle data) {
mSessionId = data.getString(MediaControlIntent.EXTRA_SESSION_ID);
mItemId = data.getString(MediaControlIntent.EXTRA_ITEM_ID);
mPollingStatus = true;
mMediaRouter.getSelectedRoute().sendControlRequest(intent,
new ControlRequestCallback() {
@Override
public void onResult(Bundle data) {
mSessionId = data.getString(MediaControlIntent.EXTRA_SESSION_ID);
mItemId = data.getString(MediaControlIntent.EXTRA_ITEM_ID);
mPollingStatus = true;
new CreateNotificationTask().execute(mPlaylist.get(mCurrentTrack)
.getFirstPropertyValue(DIDLObject.Property.UPNP.ALBUM_ART_URI.class));
new CreateNotificationTask().execute(mPlaylist.get(mCurrentTrack)
.getFirstPropertyValue(DIDLObject.Property.UPNP.ALBUM_ART_URI.class));
if (mRouterFragment.get() != null)
mRouterFragment.get().receiveIsPlaying(mCurrentTrack);
}
});
if (mRouterFragment.get() != null)
mRouterFragment.get().receiveIsPlaying(mCurrentTrack);
}
});
}
/**
@ -251,12 +251,12 @@ public class MediaRouterPlayService extends Service {
if (mPlaylist.isEmpty())
return;
Intent intent = new Intent(MediaControlIntent.ACTION_PAUSE);
intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
Intent intent = new Intent(MediaControlIntent.ACTION_PAUSE);
intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, mSessionId);
mMediaRouter.getSelectedRoute().sendControlRequest(intent, null);
mPollingStatus = false;
stopForeground(true);
mMediaRouter.getSelectedRoute().sendControlRequest(intent, null);
mPollingStatus = false;
stopForeground(true);
}
/**
@ -266,13 +266,13 @@ public class MediaRouterPlayService extends Service {
if (mPlaylist.isEmpty())
return;
Intent intent = new Intent(MediaControlIntent.ACTION_RESUME);
intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
Intent intent = new Intent(MediaControlIntent.ACTION_RESUME);
intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, mSessionId);
mMediaRouter.getSelectedRoute().sendControlRequest(intent, null);
mPollingStatus = true;
new CreateNotificationTask().execute(mPlaylist.get(mCurrentTrack)
.getFirstPropertyValue(DIDLObject.Property.UPNP.ALBUM_ART_URI.class));
mMediaRouter.getSelectedRoute().sendControlRequest(intent, null);
mPollingStatus = true;
new CreateNotificationTask().execute(mPlaylist.get(mCurrentTrack)
.getFirstPropertyValue(DIDLObject.Property.UPNP.ALBUM_ART_URI.class));
}
/**
@ -282,25 +282,25 @@ public class MediaRouterPlayService extends Service {
if (mPlaylist.isEmpty())
return;
Intent intent = new Intent(MediaControlIntent.ACTION_STOP);
intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
Intent intent = new Intent(MediaControlIntent.ACTION_STOP);
intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, mSessionId);
mMediaRouter.getSelectedRoute().sendControlRequest(intent, null);
mPollingStatus = false;
stopForeground(true);
mMediaRouter.getSelectedRoute().sendControlRequest(intent, null);
mPollingStatus = false;
stopForeground(true);
}
public void seek(int seconds) {
if (mPlaylist.isEmpty())
return;
Intent intent = new Intent(MediaControlIntent.ACTION_SEEK);
intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
Intent intent = new Intent(MediaControlIntent.ACTION_SEEK);
intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, mSessionId);
intent.putExtra(MediaControlIntent.EXTRA_ITEM_ID, mItemId);
intent.putExtra(MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION,
(long) seconds * 1000);
mMediaRouter.getSelectedRoute().sendControlRequest(intent, null);
mMediaRouter.getSelectedRoute().sendControlRequest(intent, null);
}
/**
@ -381,23 +381,23 @@ public class MediaRouterPlayService extends Service {
i.putExtra(MediaControlIntent.EXTRA_ITEM_ID, mItemId);
mMediaRouter.getSelectedRoute().sendControlRequest(i,
new ControlRequestCallback() {
@Override
public void onResult(Bundle data) {
MediaItemStatus status = MediaItemStatus.fromBundle(data);
if (status == null)
return;
@Override
public void onResult(Bundle data) {
MediaItemStatus status = MediaItemStatus.fromBundle(data);
if (status == null)
return;
if (mRouterFragment.get() != null)
mRouterFragment.get().receivePlaybackStatus(status);
if (status.getPlaybackState() != MediaItemStatus.PLAYBACK_STATE_PENDING &&
status.getPlaybackState() != MediaItemStatus.PLAYBACK_STATE_BUFFERING &&
status.getPlaybackState() != MediaItemStatus.PLAYBACK_STATE_PLAYING)
stopForeground(true);
if (mRouterFragment.get() != null)
mRouterFragment.get().receivePlaybackStatus(status);
if (status.getPlaybackState() != MediaItemStatus.PLAYBACK_STATE_PENDING &&
status.getPlaybackState() != MediaItemStatus.PLAYBACK_STATE_BUFFERING &&
status.getPlaybackState() != MediaItemStatus.PLAYBACK_STATE_PLAYING)
stopForeground(true);
if (status.getPlaybackState() == MediaItemStatus.PLAYBACK_STATE_FINISHED)
playNext();
}
});
if (status.getPlaybackState() == MediaItemStatus.PLAYBACK_STATE_FINISHED)
playNext();
}
});
}
new Handler().postDelayed(new Runnable() {
@ -405,7 +405,7 @@ public class MediaRouterPlayService extends Service {
@Override
public void run() {
pollStatus();
}
}
}, 1000);
}
@ -440,4 +440,5 @@ public class MediaRouterPlayService extends Service {
public RouteInfo getCurrentRoute() {
return mCurrentRoute;
}
}

View file

@ -4,12 +4,12 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
@ -44,6 +44,7 @@ public class MediaRouterPlayServiceBinder extends Binder {
}
public MediaRouterPlayService getService() {
return mService;
}
return mService;
}
}

View file

@ -4,12 +4,12 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
@ -70,13 +70,16 @@ final class Provider extends MediaRouteProvider {
// Device has been added.
// param: Device device
public static final int MSG_RENDERER_ADDED = 1;
// Device has been removed.
// param: int id
public static final int MSG_RENDERER_REMOVED = 2;
// Playback status information, retrieved after RemotePlayService.MSG_GET_STATUS.
// param: bundle media_item_status
// param: int hash
public static final int MSG_STATUS_INFO = 3;
// Indicates an error in communication between RemotePlayService and renderer.
// param: String error
public static final int MSG_ERROR = 4;
@ -93,23 +96,23 @@ final class Provider extends MediaRouteProvider {
public int volumeMax;
public static final Parcelable.Creator<Device> CREATOR
= new Parcelable.Creator<Device>() {
public Device createFromParcel(Parcel in) {
return new Device(in);
}
= new Parcelable.Creator<Device>() {
public Device createFromParcel(Parcel in) {
return new Device(in);
}
public Device[] newArray(int size) {
return new Device[size];
}
};
public Device[] newArray(int size) {
return new Device[size];
}
};
private Device(Parcel in) {
id = in.readString();
name = in.readString();
description = in.readString();
volume = in.readInt();
volumeMax = in.readInt();
}
id = in.readString();
name = in.readString();
description = in.readString();
volume = in.readInt();
volumeMax = in.readInt();
}
public Device(String id, String name, String description, int volume, int volumeMax) {
this.id = id;
@ -135,267 +138,267 @@ final class Provider extends MediaRouteProvider {
}
private HashMap<String, Device> mDevices = new HashMap<String, Device>();
private HashMap<String, Device> mDevices = new HashMap<String, Device>();
private SparseArray<Pair<Intent, ControlRequestCallback>> mRequests =
new SparseArray<Pair<Intent, ControlRequestCallback>>();
private SparseArray<Pair<Intent, ControlRequestCallback>> mRequests =
new SparseArray<Pair<Intent, ControlRequestCallback>>();
IRemotePlayService mIRemotePlayService;
IRemotePlayService mIRemotePlayService;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mIRemotePlayService = IRemotePlayService.Stub.asInterface(service);
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mIRemotePlayService = IRemotePlayService.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName className) {
mIRemotePlayService = null;
}
};
public void onServiceDisconnected(ComponentName className) {
mIRemotePlayService = null;
}
};
private static final ArrayList<IntentFilter> CONTROL_FILTERS;
static {
IntentFilter f = new IntentFilter();
f.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
f.addAction(MediaControlIntent.ACTION_PLAY);
f.addAction(MediaControlIntent.ACTION_PAUSE);
f.addAction(MediaControlIntent.ACTION_SEEK);
f.addAction(MediaControlIntent.ACTION_STOP);
f.addDataScheme("http");
f.addDataScheme("https");
try {
f.addDataType("video/*");
f.addDataType("audio/*");
} catch (MalformedMimeTypeException ex) {
throw new RuntimeException(ex);
}
private static final ArrayList<IntentFilter> CONTROL_FILTERS;
static {
IntentFilter f = new IntentFilter();
f.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
f.addAction(MediaControlIntent.ACTION_PLAY);
f.addAction(MediaControlIntent.ACTION_PAUSE);
f.addAction(MediaControlIntent.ACTION_SEEK);
f.addAction(MediaControlIntent.ACTION_STOP);
f.addDataScheme("http");
f.addDataScheme("https");
try {
f.addDataType("video/*");
f.addDataType("audio/*");
} catch (MalformedMimeTypeException ex) {
throw new RuntimeException(ex);
}
CONTROL_FILTERS = new ArrayList<IntentFilter>();
CONTROL_FILTERS.add(f);
}
CONTROL_FILTERS = new ArrayList<IntentFilter>();
CONTROL_FILTERS.add(f);
}
/**
* Listens for messages about devices.
*/
static private class DeviceListener extends Handler {
* Listens for messages about devices.
*/
static private class DeviceListener extends Handler {
private final WeakReference<Provider> mService;
private final WeakReference<Provider> mService;
DeviceListener(Provider provider) {
mService = new WeakReference<Provider>(provider);
}
DeviceListener(Provider provider) {
mService = new WeakReference<Provider>(provider);
}
@Override
public void handleMessage(Message msg) {
if (mService.get() != null)
mService.get().handleMessage(msg);
}
}
@Override
public void handleMessage(Message msg) {
if (mService.get() != null)
mService.get().handleMessage(msg);
}
}
final Messenger mListener = new Messenger(new DeviceListener(this));
final Messenger mListener = new Messenger(new DeviceListener(this));
public Provider(Context context) {
super(context);
context.bindService(
new Intent(context, RemotePlayService.class),
mConnection,
Context.BIND_AUTO_CREATE
);
}
public Provider(Context context) {
super(context);
context.bindService(
new Intent(context, RemotePlayService.class),
mConnection,
Context.BIND_AUTO_CREATE
);
}
public void close() {
getContext().unbindService(mConnection);
}
@Override
public void onDiscoveryRequestChanged(MediaRouteDiscoveryRequest request) {
try {
if (request != null && request.isActiveScan())
@Override
public void onDiscoveryRequestChanged(MediaRouteDiscoveryRequest request) {
try {
if (request != null && request.isActiveScan())
mIRemotePlayService.startSearch(mListener);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
@Override
public RouteController onCreateRouteController(String routeId) {
return new RouteController(routeId);
}
@Override
public RouteController onCreateRouteController(String routeId) {
return new RouteController(routeId);
}
private void updateRoutes() {
Builder builder = new Builder();
for (Entry<String, Device> d : mDevices.entrySet()) {
MediaRouteDescriptor routeDescriptor = new MediaRouteDescriptor.Builder(
d.getValue().id,
d.getValue().name)
.setDescription(getContext().getResources()
.getString(R.string.route_description))
.addControlFilters(CONTROL_FILTERS)
.setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
.setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE)
.setVolumeMax(d.getValue().volumeMax)
.setVolume(d.getValue().volume)
.build();
builder.addRoute(routeDescriptor);
}
setDescriptor(builder.build());
}
private void updateRoutes() {
Builder builder = new Builder();
for (Entry<String, Device> d : mDevices.entrySet()) {
MediaRouteDescriptor routeDescriptor = new MediaRouteDescriptor.Builder(
d.getValue().id,
d.getValue().name)
.setDescription(getContext().getResources()
.getString(R.string.route_description))
.addControlFilters(CONTROL_FILTERS)
.setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
.setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE)
.setVolumeMax(d.getValue().volumeMax)
.setVolume(d.getValue().volume)
.build();
builder.addRoute(routeDescriptor);
}
setDescriptor(builder.build());
}
/**
* Receives and forwards device selections, volume change
* requests and control requests.
*/
private final class RouteController extends MediaRouteProvider.RouteController {
private final String mRouteId;
/**
* Receives and forwards device selections, volume change
* requests and control requests.
*/
private final class RouteController extends MediaRouteProvider.RouteController {
public RouteController(String routeId) {
mRouteId = routeId;
}
private final String mRouteId;
@Override
public void onRelease() {
}
public RouteController(String routeId) {
mRouteId = routeId;
}
@Override
public void onSelect() {
try {
@Override
public void onRelease() {
}
@Override
public void onSelect() {
try {
mIRemotePlayService.selectRenderer(mRouteId);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
@Override
public void onUnselect() {
try {
@Override
public void onUnselect() {
try {
mIRemotePlayService.unselectRenderer(mRouteId);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
@Override
public void onSetVolume(int volume) {
if (volume < 0 || volume > mDevices.get(mRouteId).volumeMax)
return;
@Override
public void onSetVolume(int volume) {
if (volume < 0 || volume > mDevices.get(mRouteId).volumeMax)
return;
try {
try {
mIRemotePlayService.setVolume(volume);
} catch (RemoteException e) {
e.printStackTrace();
}
mDevices.get(mRouteId).volume = volume;
updateRoutes();
}
mDevices.get(mRouteId).volume = volume;
updateRoutes();
}
@Override
public void onUpdateVolume(int delta) {
onSetVolume(mDevices.get(mRouteId).volume + delta);
}
@Override
public void onUpdateVolume(int delta) {
onSetVolume(mDevices.get(mRouteId).volume + delta);
}
/**
* Handles play, pause, resume, stop, seek and get_status requests for this route.
*/
@Override
public boolean onControlRequest(Intent intent, ControlRequestCallback callback) {
try {
if (intent.getAction().equals(MediaControlIntent.ACTION_PLAY)) {
String metadata = (intent.hasExtra(MediaControlIntent.EXTRA_ITEM_METADATA))
? intent.getExtras().getString(MediaControlIntent.EXTRA_ITEM_METADATA)
: null;
mIRemotePlayService.play(intent.getDataString(), metadata);
// Store in intent extras for later.
intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, mRouteId);
intent.putExtra(MediaControlIntent.EXTRA_ITEM_ID, intent.getDataString());
getItemStatus(intent, callback);
return true;
}
else if (intent.getAction().equals(MediaControlIntent.ACTION_PAUSE)) {
/**
* Handles play, pause, resume, stop, seek and get_status requests for this route.
*/
@Override
public boolean onControlRequest(Intent intent, ControlRequestCallback callback) {
try {
if (intent.getAction().equals(MediaControlIntent.ACTION_PLAY)) {
String metadata = (intent.hasExtra(MediaControlIntent.EXTRA_ITEM_METADATA))
? intent.getExtras().getString(MediaControlIntent.EXTRA_ITEM_METADATA)
: null;
mIRemotePlayService.play(intent.getDataString(), metadata);
// Store in intent extras for later.
intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, mRouteId);
intent.putExtra(MediaControlIntent.EXTRA_ITEM_ID, intent.getDataString());
getItemStatus(intent, callback);
return true;
}
else if (intent.getAction().equals(MediaControlIntent.ACTION_PAUSE)) {
mIRemotePlayService.pause(mRouteId);
return true;
}
else if (intent.getAction().equals(MediaControlIntent.ACTION_RESUME)) {
mIRemotePlayService.resume(mRouteId);
return true;
}
else if (intent.getAction().equals(MediaControlIntent.ACTION_STOP)) {
mIRemotePlayService.stop(mRouteId);
return true;
}
else if (intent.getAction().equals(MediaControlIntent.ACTION_SEEK)) {
mIRemotePlayService.seek(mRouteId,
intent.getStringExtra(
MediaControlIntent.EXTRA_ITEM_ID),
intent.getLongExtra(
MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, 0));
getItemStatus(intent, callback);
return true;
}
else if(intent.getAction().equals(MediaControlIntent.ACTION_GET_STATUS)) {
getItemStatus(intent, callback);
return true;
}
return true;
}
else if (intent.getAction().equals(MediaControlIntent.ACTION_RESUME)) {
mIRemotePlayService.resume(mRouteId);
return true;
}
else if (intent.getAction().equals(MediaControlIntent.ACTION_STOP)) {
mIRemotePlayService.stop(mRouteId);
return true;
}
else if (intent.getAction().equals(MediaControlIntent.ACTION_SEEK)) {
mIRemotePlayService.seek(mRouteId,
intent.getStringExtra(
MediaControlIntent.EXTRA_ITEM_ID),
intent.getLongExtra(
MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, 0));
getItemStatus(intent, callback);
return true;
}
else if(intent.getAction().equals(MediaControlIntent.ACTION_GET_STATUS)) {
getItemStatus(intent, callback);
return true;
}
} catch (RemoteException e) {
e.printStackTrace();
}
return false;
}
}
}
/**
* Requests status info via RemotePlayService, stores intent and callback to
* access later in handleMessage.
*/
private void getItemStatus(Intent intent, ControlRequestCallback callback)
throws RemoteException {
if (callback == null)
return;
}
Pair<Intent, ControlRequestCallback> pair =
new Pair<Intent, ControlRequestCallback>(intent, callback);
int r = new Random().nextInt();
mRequests.put(r, pair);
mIRemotePlayService.getItemStatus(
intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID),
intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID),
r);
}
/**
* Requests status info via RemotePlayService, stores intent and callback to
* access later in handleMessage.
*/
private void getItemStatus(Intent intent, ControlRequestCallback callback)
throws RemoteException {
if (callback == null)
return;
/**
* Handles device add and remove as well as sending status info requested earlier.
*/
public void handleMessage(Message msg) {
Bundle data = msg.getData();
Pair<Intent, ControlRequestCallback> pair =
new Pair<Intent, ControlRequestCallback>(intent, callback);
int r = new Random().nextInt();
mRequests.put(r, pair);
mIRemotePlayService.getItemStatus(
intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID),
intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID),
r);
}
/**
* Handles device add and remove as well as sending status info requested earlier.
*/
public void handleMessage(Message msg) {
Bundle data = msg.getData();
switch (msg.what) {
case MSG_RENDERER_ADDED:
msg.getData().setClassLoader(Device.class.getClassLoader());
Device device = (Device) data.getParcelable("device");
mDevices.put(device.id, device);
updateRoutes();
break;
case MSG_RENDERER_REMOVED:
mDevices.remove(data.getString("id"));
updateRoutes();
break;
case MSG_STATUS_INFO:
Pair<Intent, ControlRequestCallback> pair =
mRequests.get(data.getInt("hash"));
Bundle status = data.getBundle("media_item_status");
case MSG_RENDERER_ADDED:
msg.getData().setClassLoader(Device.class.getClassLoader());
Device device = (Device) data.getParcelable("device");
mDevices.put(device.id, device);
updateRoutes();
break;
case MSG_RENDERER_REMOVED:
mDevices.remove(data.getString("id"));
updateRoutes();
break;
case MSG_STATUS_INFO:
Pair<Intent, ControlRequestCallback> pair =
mRequests.get(data.getInt("hash"));
Bundle status = data.getBundle("media_item_status");
if (pair.first.hasExtra(MediaControlIntent.EXTRA_SESSION_ID)) {
status.putString(MediaControlIntent.EXTRA_SESSION_ID,
pair.first.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID));
}
if (pair.first.hasExtra(MediaControlIntent.EXTRA_ITEM_ID)) {
status.putString(MediaControlIntent.EXTRA_ITEM_ID,
pair.first.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID));
}
pair.second.onResult(status);
break;
if (pair.first.hasExtra(MediaControlIntent.EXTRA_SESSION_ID))
status.putString(MediaControlIntent.EXTRA_SESSION_ID,
pair.first.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID));
if (pair.first.hasExtra(MediaControlIntent.EXTRA_ITEM_ID))
status.putString(MediaControlIntent.EXTRA_ITEM_ID,
pair.first.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID));
pair.second.onResult(status);
break;
case MSG_ERROR:
Toast.makeText(getContext(), data.getString("error"), Toast.LENGTH_SHORT).show();
break;
}
}
}
}
}

View file

@ -4,12 +4,12 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
@ -33,11 +33,11 @@ import android.support.v7.media.MediaRouteProviderService;
public class ProviderService extends MediaRouteProviderService {
private Provider mProvider;
@Override
public MediaRouteProvider onCreateMediaRouteProvider() {
if (mProvider == null) {
if (mProvider == null)
mProvider = new Provider(this);
}
return mProvider;
}
@ -47,4 +47,5 @@ public class ProviderService extends MediaRouteProviderService {
mProvider.close();
mProvider = null;
}
}

View file

@ -4,12 +4,12 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
@ -61,7 +61,6 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
/**
* Allows UPNP playback from different apps by providing a proxy interface.
* You can communicate to this service via RemotePlayServiceBinder.
@ -73,41 +72,39 @@ public class RemotePlayService extends Service implements RegistryListener {
private static final String TAG = "RemotePlayService";
Messenger mListener;
Messenger mListener;
ConcurrentHashMap<String, Device<?, ?, ?>> mDevices =
new ConcurrentHashMap<String, Device<?, ?, ?>>();
ConcurrentHashMap<String, Device<?, ?, ?>> mDevices =
new ConcurrentHashMap<String, Device<?, ?, ?>>();
protected AndroidUpnpService mUpnpService;
protected AndroidUpnpService mUpnpService;
private ServiceConnection mUpnpServiceConnection = new ServiceConnection() {
private ServiceConnection mUpnpServiceConnection = new ServiceConnection() {
/**
* Registers DeviceListener, adds known devices and starts search if requested.
*/
/**
* Registers DeviceListener, adds known devices and starts search if requested.
*/
public void onServiceConnected(ComponentName className, IBinder service) {
mUpnpService = (AndroidUpnpService) service;
mUpnpService.getRegistry().addListener(RemotePlayService.this);
for (Device<?, ?, ?> d : mUpnpService.getControlPoint().getRegistry().getDevices()) {
if (d instanceof LocalDevice)
localDeviceAdded(mUpnpService.getRegistry(), (LocalDevice) d);
else
remoteDeviceAdded(mUpnpService.getRegistry(), (RemoteDevice) d);
}
mUpnpService.getControlPoint().search();
}
mUpnpService = (AndroidUpnpService) service;
mUpnpService.getRegistry().addListener(RemotePlayService.this);
for (Device<?, ?, ?> d : mUpnpService.getControlPoint().getRegistry().getDevices())
if (d instanceof LocalDevice)
localDeviceAdded(mUpnpService.getRegistry(), (LocalDevice) d);
else
remoteDeviceAdded(mUpnpService.getRegistry(), (RemoteDevice) d);
mUpnpService.getControlPoint().search();
}
public void onServiceDisconnected(ComponentName className) {
mUpnpService = null;
}
};
public void onServiceDisconnected(ComponentName className) {
mUpnpService = null;
}
};
/**
* All active binders. The Hashmap value is unused.
*/
WeakHashMap<RemotePlayServiceBinder, Boolean> mBinders =
new WeakHashMap<RemotePlayServiceBinder, Boolean>();
/**
* All active binders. The Hashmap value is unused.
*/
WeakHashMap<RemotePlayServiceBinder, Boolean> mBinders =
new WeakHashMap<RemotePlayServiceBinder, Boolean>();
@Override
public IBinder onBind(Intent itnent) {
@ -122,23 +119,23 @@ public class RemotePlayService extends Service implements RegistryListener {
@Override
public void onCreate() {
super.onCreate();
bindService(
new Intent(this, AndroidUpnpServiceImpl.class),
mUpnpServiceConnection,
Context.BIND_AUTO_CREATE
);
bindService(
new Intent(this, AndroidUpnpServiceImpl.class),
mUpnpServiceConnection,
Context.BIND_AUTO_CREATE
);
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(mWifiReceiver, filter);
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(mWifiReceiver, filter);
}
@Override
public void onDestroy() {
super.onDestroy();
unbindService(mUpnpServiceConnection);
unregisterReceiver(mWifiReceiver);
unbindService(mUpnpServiceConnection);
unregisterReceiver(mWifiReceiver);
}
/**
@ -146,10 +143,10 @@ public class RemotePlayService extends Service implements RegistryListener {
*/
void sendMessage(Message msg) {
try {
mListener.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
mListener.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
/**
@ -158,8 +155,8 @@ public class RemotePlayService extends Service implements RegistryListener {
*/
void sendError(String error) {
Message msg = Message.obtain(null, Provider.MSG_ERROR, 0, 0);
msg.getData().putString("error", error);
sendMessage(msg);
msg.getData().putString("error", error);
sendMessage(msg);
}
/**
@ -168,43 +165,39 @@ public class RemotePlayService extends Service implements RegistryListener {
*/
private BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connManager = (ConnectivityManager)
getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo wifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connManager = (ConnectivityManager)
getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo wifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (wifi.isConnected()) {
if (mUpnpService != null) {
for (Device<?, ?, ?> d : mUpnpService.getControlPoint().getRegistry().getDevices())
deviceAdded(d);
mUpnpService.getControlPoint().search();
}
}
else {
for (Entry<String, Device<?, ?, ?>> d : mDevices.entrySet()) {
if (mUpnpService.getControlPoint().getRegistry()
.getDevice(new UDN(d.getKey()), false) == null) {
deviceRemoved(d.getValue());
for (RemotePlayServiceBinder b : mBinders.keySet()) {
if (b.mCurrentRenderer.equals(d.getValue())) {
b.mSubscriptionCallback.end();
b.mCurrentRenderer = null;
}
}
}
}
}
}
if (wifi.isConnected()) {
if (mUpnpService != null) {
for (Device<?, ?, ?> d : mUpnpService.getControlPoint().getRegistry().getDevices())
deviceAdded(d);
mUpnpService.getControlPoint().search();
}
} else
for (Entry<String, Device<?, ?, ?>> d : mDevices.entrySet())
if (mUpnpService.getControlPoint().getRegistry()
.getDevice(new UDN(d.getKey()), false) == null) {
deviceRemoved(d.getValue());
for (RemotePlayServiceBinder b : mBinders.keySet())
if (b.mCurrentRenderer.equals(d.getValue())) {
b.mSubscriptionCallback.end();
b.mCurrentRenderer = null;
}
}
}
};
/**
* Returns a device service by name for direct queries.
*/
/**
* Returns a device service by name for direct queries.
*/
org.teleal.cling.model.meta.Service<?, ?> getService(
Device<?, ?, ?> device, String name) {
return device.findService(
new ServiceType("schemas-upnp-org", name));
new ServiceType("schemas-upnp-org", name));
}
/**
@ -221,44 +214,44 @@ public class RemotePlayService extends Service implements RegistryListener {
if (device.getType().getType().equals("MediaRenderer") &&
device instanceof RemoteDevice) {
mDevices.put(device.getIdentity().getUdn().toString(), device);
mDevices.put(device.getIdentity().getUdn().toString(), device);
try {
mUpnpService.getControlPoint().execute(new GetVolume(rc) {
try {
mUpnpService.getControlPoint().execute(new GetVolume(rc) {
@SuppressWarnings("rawtypes")
@Override
public void failure(ActionInvocation invocation,
UpnpResponse operation, String defaultMessage) {
Log.w(TAG, "Failed to get current Volume: " + defaultMessage);
sendError("Failed to get current Volume: " + defaultMessage);
}
@SuppressWarnings("rawtypes")
@Override
public void failure(ActionInvocation invocation,
UpnpResponse operation, String defaultMessage) {
Log.w(TAG, "Failed to get current Volume: " + defaultMessage);
sendError("Failed to get current Volume: " + defaultMessage);
}
@SuppressWarnings("rawtypes")
@Override
public void received(ActionInvocation invocation, int currentVolume) {
int maxVolume = 100;
if (rc.getStateVariable("Volume") != null) {
StateVariableAllowedValueRange volumeRange =
rc.getStateVariable("Volume").getTypeDetails().getAllowedValueRange();
maxVolume = (int) volumeRange.getMaximum();
}
@SuppressWarnings("rawtypes")
@Override
public void received(ActionInvocation invocation, int currentVolume) {
int maxVolume = 100;
if (rc.getStateVariable("Volume") != null) {
StateVariableAllowedValueRange volumeRange =
rc.getStateVariable("Volume").getTypeDetails().getAllowedValueRange();
maxVolume = (int) volumeRange.getMaximum();
}
Message msg = Message.obtain(null, Provider.MSG_RENDERER_ADDED, 0, 0);
msg.getData().putParcelable("device", new Provider.Device(
device.getIdentity().getUdn().toString(),
device.getDisplayString(),
device.getDetails().getManufacturerDetails().getManufacturer(),
currentVolume,
maxVolume));
sendMessage(msg);
}
});
}
catch (IllegalArgumentException e) {
e.printStackTrace();
return;
}
Message msg = Message.obtain(null, Provider.MSG_RENDERER_ADDED, 0, 0);
msg.getData().putParcelable("device", new Provider.Device(
device.getIdentity().getUdn().toString(),
device.getDisplayString(),
device.getDetails().getManufacturerDetails().getManufacturer(),
currentVolume,
maxVolume));
sendMessage(msg);
}
});
}
catch (IllegalArgumentException e) {
e.printStackTrace();
return;
}
}
}
@ -271,9 +264,9 @@ public class RemotePlayService extends Service implements RegistryListener {
Message msg = Message.obtain(null, Provider.MSG_RENDERER_REMOVED, 0, 0);
String udn = device.getIdentity().getUdn().toString();
msg.getData().putString("id", udn);
mDevices.remove(udn);
sendMessage(msg);
msg.getData().putString("id", udn);
mDevices.remove(udn);
sendMessage(msg);
}
}
@ -327,4 +320,5 @@ public class RemotePlayService extends Service implements RegistryListener {
public void remoteDeviceUpdated(Registry registry, RemoteDevice device) {
deviceUpdated(device);
}
}

View file

@ -4,12 +4,12 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
@ -69,11 +69,11 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
private static final String TAG = "RemotePlayServiceBinder";
Device<?, ?, ?> mCurrentRenderer;
Device<?, ?, ?> mCurrentRenderer;
private int mPlaybackState;
private int mPlaybackState;
private boolean mManuallyStopped;
private boolean mManuallyStopped;
SubscriptionCallback mSubscriptionCallback;
@ -86,20 +86,19 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
@Override
public void startSearch(Messenger listener)
throws RemoteException {
mRps.mListener = listener;
mRps.mListener = listener;
}
@Override
public void selectRenderer(String id) throws RemoteException {
mCurrentRenderer = mRps.mDevices.get(id);
for (RemotePlayServiceBinder b : mRps.mBinders.keySet()) {
for (RemotePlayServiceBinder b : mRps.mBinders.keySet())
if (b != this && mCurrentRenderer.equals(b.mCurrentRenderer))
b.unselectRenderer("");
}
mSubscriptionCallback = new SubscriptionCallback(
mCurrentRenderer.findService(
new ServiceType("schemas-upnp-org", "AVTransport")), 600) {
new ServiceType("schemas-upnp-org", "AVTransport")), 600) {
@SuppressWarnings("rawtypes")
@Override
@ -127,29 +126,29 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
switch (lastChange.getEventedValue(0,
AVTransportVariable.TransportState.class)
.getValue()) {
case PLAYING:
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_PLAYING;
break;
case PAUSED_PLAYBACK:
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_PAUSED;
break;
case STOPPED:
if (mManuallyStopped) {
mManuallyStopped = false;
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_CANCELED;
}
else
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_FINISHED;
break;
case TRANSITIONING:
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_PENDING;
break;
case NO_MEDIA_PRESENT:
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_ERROR;
break;
default:
}
.getValue()) {
case PLAYING:
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_PLAYING;
break;
case PAUSED_PLAYBACK:
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_PAUSED;
break;
case STOPPED:
if (mManuallyStopped) {
mManuallyStopped = false;
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_CANCELED;
}
else
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_FINISHED;
break;
case TRANSITIONING:
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_PENDING;
break;
case NO_MEDIA_PRESENT:
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_ERROR;
break;
default:
}
} catch (Exception e) {
Log.w(TAG, "Failed to parse UPNP event", e);
@ -183,27 +182,27 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
stop(sessionId);
if (mSubscriptionCallback != null)
mSubscriptionCallback.end();
mCurrentRenderer = null;
mCurrentRenderer = null;
}
/**
* Sets an absolute volume. The value is assumed to be within the valid
* volume range.
*/
* Sets an absolute volume. The value is assumed to be within the valid
* volume range.
*/
@Override
public void setVolume(int volume) throws RemoteException {
mRps.mUpnpService.getControlPoint().execute(
new SetVolume(mRps.getService(mCurrentRenderer,
"RenderingControl"), volume) {
@SuppressWarnings("rawtypes")
@Override
public void failure(ActionInvocation invocation,
UpnpResponse operation, String defaultMessage) {
Log.w(TAG, "Set volume failed: " + defaultMessage);
mRps.sendError("Set volume failed: " + defaultMessage);
}
});
@SuppressWarnings("rawtypes")
@Override
public void failure(ActionInvocation invocation,
UpnpResponse operation, String defaultMessage) {
Log.w(TAG, "Set volume failed: " + defaultMessage);
mRps.sendError("Set volume failed: " + defaultMessage);
}
});
}
/**
@ -215,36 +214,36 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_BUFFERING;
mRps.mUpnpService.getControlPoint().execute(new SetAVTransportURI(
mRps.getService(mCurrentRenderer, "AVTransport"),
uri, metadata) {
uri, metadata) {
@SuppressWarnings("rawtypes")
@Override
public void failure(ActionInvocation invocation,
UpnpResponse operation, String defaultMsg) {
Log.w(TAG, "Set URI failed: " + defaultMsg);
mRps.sendError("Set URI failed: " + defaultMsg);
}
public void failure(ActionInvocation invocation,
UpnpResponse operation, String defaultMsg) {
Log.w(TAG, "Set URI failed: " + defaultMsg);
mRps.sendError("Set URI failed: " + defaultMsg);
}
@SuppressWarnings("rawtypes")
@Override
public void success(ActionInvocation invocation) {
public void success(ActionInvocation invocation) {
mRps.mUpnpService.getControlPoint().execute(
new Play(mRps.getService(mCurrentRenderer,
"AVTransport")) {
@Override
public void success(ActionInvocation invocation) {
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_PLAYING;
}
@Override
public void success(ActionInvocation invocation) {
mPlaybackState = MediaItemStatus.PLAYBACK_STATE_PLAYING;
}
@Override
public void failure(ActionInvocation invocation,
UpnpResponse operation, String defaultMessage) {
Log.w(TAG, "Play failed: " + defaultMessage);
mRps.sendError("Play failed: " + defaultMessage);
}
});
@Override
public void failure(ActionInvocation invocation,
UpnpResponse operation, String defaultMessage) {
Log.w(TAG, "Play failed: " + defaultMessage);
mRps.sendError("Play failed: " + defaultMessage);
}
});
}
});
});
}
/**
@ -255,20 +254,20 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
mRps.mUpnpService.getControlPoint().execute(
new Pause(mRps.getService(mRps.mDevices.get(sessionId), "AVTransport")) {
@SuppressWarnings("rawtypes")
@Override
public void failure(ActionInvocation invocation,
UpnpResponse operation, String defaultMessage) {
Log.w(TAG, "Pause failed, trying stop: " + defaultMessage);
mRps.sendError("Pause failed, trying stop: " + defaultMessage);
// Sometimes stop works even though pause does not.
try {
stop(sessionId);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
@SuppressWarnings("rawtypes")
@Override
public void failure(ActionInvocation invocation,
UpnpResponse operation, String defaultMessage) {
Log.w(TAG, "Pause failed, trying stop: " + defaultMessage);
mRps.sendError("Pause failed, trying stop: " + defaultMessage);
// Sometimes stop works even though pause does not.
try {
stop(sessionId);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
@Override
@ -277,14 +276,14 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
new Play(mRps.getService(mRps.mDevices.get(sessionId),
"AVTransport")) {
@Override
@SuppressWarnings("rawtypes")
public void failure(ActionInvocation invocation,
UpnpResponse operation, String defaultMessage) {
Log.w(TAG, "Resume failed: " + defaultMessage);
mRps.sendError("Resume failed: " + defaultMessage);
}
});
@Override
@SuppressWarnings("rawtypes")
public void failure(ActionInvocation invocation,
UpnpResponse operation, String defaultMessage) {
Log.w(TAG, "Resume failed: " + defaultMessage);
mRps.sendError("Resume failed: " + defaultMessage);
}
});
}
/**
@ -294,29 +293,29 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
public void stop(String sessionId) throws RemoteException {
mManuallyStopped = true;
mRps.mUpnpService.getControlPoint().execute(
new Stop(mRps.getService(mRps.mDevices.get(sessionId), "AVTransport")) {
new Stop(mRps.getService(mRps.mDevices.get(sessionId), "AVTransport")) {
@SuppressWarnings("rawtypes")
@Override
public void failure(ActionInvocation invocation,
org.teleal.cling.model.message.UpnpResponse operation,
String defaultMessage) {
Log.w(TAG, "Stop failed: " + defaultMessage);
mRps.sendError("Stop failed: " + defaultMessage);
}
});
@SuppressWarnings("rawtypes")
@Override
public void failure(ActionInvocation invocation,
org.teleal.cling.model.message.UpnpResponse operation,
String defaultMessage) {
Log.w(TAG, "Stop failed: " + defaultMessage);
mRps.sendError("Stop failed: " + defaultMessage);
}
});
}
/**
* Seeks to the given absolute time in seconds.
*/
/**
* Seeks to the given absolute time in seconds.
*/
@Override
public void seek(String sessionId, String itemId, long milliseconds)
throws RemoteException {
mRps.mUpnpService.getControlPoint().execute(new Seek(
mRps.getService(mRps.mDevices.get(sessionId), "AVTransport"),
SeekMode.REL_TIME,
Integer.toString((int) milliseconds / 1000)) {
SeekMode.REL_TIME,
Integer.toString((int) milliseconds / 1000)) {
@SuppressWarnings("rawtypes")
@Override
@ -342,39 +341,38 @@ public class RemotePlayServiceBinder extends IRemotePlayService.Stub {
public void getItemStatus(String sessionId, final String itemId, final int requestHash)
throws RemoteException {
mRps.mUpnpService.getControlPoint().execute(new GetPositionInfo(
mRps.getService(mRps.mDevices.get(sessionId), "AVTransport")) {
mRps.getService(mRps.mDevices.get(sessionId), "AVTransport")) {
@SuppressWarnings("rawtypes")
@Override
public void failure(ActionInvocation invocation,
UpnpResponse operation, String defaultMessage) {
Log.w(TAG, "Get position failed: " + defaultMessage);
}
@SuppressWarnings("rawtypes")
@Override
public void failure(ActionInvocation invocation,
UpnpResponse operation, String defaultMessage) {
Log.w(TAG, "Get position failed: " + defaultMessage);
}
@SuppressWarnings("rawtypes")
@Override
public void received(ActionInvocation invocation, PositionInfo positionInfo) {
if (positionInfo.getTrackURI() == null)
return;
@SuppressWarnings("rawtypes")
@Override
public void received(ActionInvocation invocation, PositionInfo positionInfo) {
if (positionInfo.getTrackURI() == null)
return;
Message msg = Message.obtain(null, Provider.MSG_STATUS_INFO, 0, 0);
Builder status = null;
Message msg = Message.obtain(null, Provider.MSG_STATUS_INFO, 0, 0);
Builder status = null;
if (positionInfo.getTrackURI().equals(itemId)) {
status = new MediaItemStatus.Builder(mPlaybackState)
.setContentPosition(positionInfo.getTrackElapsedSeconds() * 1000)
.setContentDuration(positionInfo.getTrackDurationSeconds() * 1000)
.setTimestamp(positionInfo.getAbsCount());
}
else {
status = new MediaItemStatus.Builder(
MediaItemStatus.PLAYBACK_STATE_INVALIDATED);
}
if (positionInfo.getTrackURI().equals(itemId))
status = new MediaItemStatus.Builder(mPlaybackState)
.setContentPosition(positionInfo.getTrackElapsedSeconds() * 1000)
.setContentDuration(positionInfo.getTrackDurationSeconds() * 1000)
.setTimestamp(positionInfo.getAbsCount());
else
status = new MediaItemStatus.Builder(
MediaItemStatus.PLAYBACK_STATE_INVALIDATED);
msg.getData().putBundle("media_item_status", status.build().asBundle());
msg.getData().putInt("hash", requestHash);
mRps.sendMessage(msg);
}
msg.getData().putBundle("media_item_status", status.build().asBundle());
msg.getData().putInt("hash", requestHash);
mRps.sendMessage(msg);
}
});
}
};

View file

@ -4,12 +4,12 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
@ -47,7 +47,6 @@ import android.widget.TextView;
import com.github.nutomic.controldlna.R;
/**
* Displays the devices that are inserted through the RegistryListener (either
* of type RENDERER or SERVER).
@ -80,39 +79,37 @@ public class DeviceArrayAdapter extends ArrayAdapter<Device<?, ?, ?>>
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item, parent, false);
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item, parent, false);
}
TextView tv = (TextView) convertView.findViewById(R.id.title);
RemoteImageView image =
(RemoteImageView) convertView.findViewById(R.id.image);
tv.setText(getItem(position).getDetails().getFriendlyName());
TextView tv = (TextView) convertView.findViewById(R.id.title);
RemoteImageView image =
(RemoteImageView) convertView.findViewById(R.id.image);
tv.setText(getItem(position).getDetails().getFriendlyName());
if (getItem(position).hasIcons()) {
if (getItem(position).hasIcons()) {
URI uri = getItem(position).getIcons()[0].getUri();
if (getItem(position) instanceof RemoteDevice) {
if (getItem(position) instanceof RemoteDevice)
try {
RemoteDevice device = (RemoteDevice) getItem(position);
RemoteDevice device = (RemoteDevice) getItem(position);
uri = device.normalizeURI(uri).toURI();
} catch (URISyntaxException e) {
Log.w(TAG, "Failed to get device icon URI", e);
}
}
image.setImageUri(uri);
}
}
return convertView;
return convertView;
}
/**
* Adds a new device to the list if its type equals mDeviceType.
*/
public void deviceAdded(final Device<?, ?, ?> device) {
for (int i = 0; i < getCount(); i++) {
for (int i = 0; i < getCount(); i++)
if (getItem(i).equals(device))
return;
}
mActivity.runOnUiThread(new Runnable() {
@ -179,4 +176,5 @@ public class DeviceArrayAdapter extends ArrayAdapter<Device<?, ?, ?>>
@Override
public void afterShutdown() {
}
}

View file

@ -4,12 +4,12 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
@ -82,30 +82,30 @@ public class FileArrayAdapter extends ArrayAdapter<DIDLObject> {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item, parent, false);
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item, parent, false);
}
DIDLObject item = getItem(position);
TextView title = (TextView) convertView.findViewById(R.id.title);
TextView artist = (TextView) convertView.findViewById(R.id.subtitle);
artist.setText("");
RemoteImageView image = (RemoteImageView) convertView.findViewById(R.id.image);
TextView title = (TextView) convertView.findViewById(R.id.title);
TextView artist = (TextView) convertView.findViewById(R.id.subtitle);
artist.setText("");
RemoteImageView image = (RemoteImageView) convertView.findViewById(R.id.image);
if (item instanceof MusicTrack) {
MusicTrack track = (MusicTrack) item;
String trackNumber = (track.getOriginalTrackNumber() != null)
? Integer.toString(track.getOriginalTrackNumber()) + ". "
: "";
title.setText(trackNumber + item.getTitle());
if (track.getArtists().length > 0)
artist.setText(track.getArtists()[0].getName());
MusicTrack track = (MusicTrack) item;
String trackNumber = (track.getOriginalTrackNumber() != null)
? Integer.toString(track.getOriginalTrackNumber()) + ". "
: "";
title.setText(trackNumber + item.getTitle());
if (track.getArtists().length > 0)
artist.setText(track.getArtists()[0].getName());
}
else
title.setText(item.getTitle());
else
title.setText(item.getTitle());
image.setImageUri(item.getFirstPropertyValue(
DIDLObject.Property.UPNP.ALBUM_ART_URI.class));
return convertView;
return convertView;
}
/**

View file

@ -4,12 +4,12 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
@ -49,25 +49,25 @@ public class LoadImageTask extends AsyncTask<URI, Void, Bitmap> {
private static final String TAG = "LoadImageTask";
@Override
protected Bitmap doInBackground(URI... uri) {
if (uri[0] == null)
return null;
@Override
protected Bitmap doInBackground(URI... uri) {
if (uri[0] == null)
return null;
Bitmap bm = null;
try {
URLConnection conn = new URL(uri[0].toString())
.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
} catch (IOException e) {
Log.w(TAG, "Failed to load artwork image", e);
}
return bm;
}
try {
URLConnection conn = new URL(uri[0].toString())
.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
} catch (IOException e) {
Log.w(TAG, "Failed to load artwork image", e);
}
return bm;
}
}

View file

@ -4,12 +4,12 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
@ -50,13 +50,13 @@ public class RemoteImageView extends ImageView {
*/
private class AssignImageTask extends LoadImageTask {
@Override
protected void onPostExecute(Bitmap bm) {
if (bm != null)
@Override
protected void onPostExecute(Bitmap bm) {
if (bm != null)
setImageBitmap(bm);
else
else
setImageDrawable(null);
}
}
};
@ -65,12 +65,12 @@ public class RemoteImageView extends ImageView {
}
public RemoteImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
super(context, attrs);
}
public RemoteImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
super(context, attrs, defStyle);
}
/**
* Sets the URI where the image should be loaded from, loads and assigns it.

View file

@ -21,18 +21,18 @@ public class RouteAdapter extends ArrayAdapter<RouteInfo> {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item, parent, false);
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item, parent, false);
}
TextView title = (TextView) convertView.findViewById(R.id.title);
title.setText(getItem(position).getName());
TextView title = (TextView) convertView.findViewById(R.id.title);
title.setText(getItem(position).getName());
TextView subtitle = (TextView) convertView.findViewById(R.id.subtitle);
subtitle.setText(getItem(position).getDescription());
TextView subtitle = (TextView) convertView.findViewById(R.id.subtitle);
subtitle.setText(getItem(position).getDescription());
return convertView;
return convertView;
}
/**