1
/*
2
* Copyright (C) 2013 The Android Open Source Project
3
*
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
7
*
8
* http://www.apache.org/licenses/LICENSE-2.0
9
*
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
15
*/
16
17
package com.example.android.mediarouter.player;
18
19
import android.app.PendingIntent;
20
import android.content.ComponentName;
21
import android.content.Context;
22
import android.content.Intent;
23
import android.media.AudioManager;
24
import android.media.AudioManager.OnAudioFocusChangeListener;
25
import android.media.RemoteControlClient;
26
import android.net.Uri;
27
import android.os.Build;
28
import android.os.Bundle;
29
import android.os.Environment;
30
import android.os.Handler;
31
import android.os.SystemClock;
32
import android.support.v4.app.FragmentManager;
33
import android.support.v4.view.MenuItemCompat;
34
import android.support.v7.app.ActionBarActivity;
35
import android.support.v7.app.MediaRouteActionProvider;
36
import android.support.v7.app.MediaRouteDiscoveryFragment;
37
import android.support.v7.media.MediaControlIntent;
38
import android.support.v7.media.MediaItemStatus;
39
import android.support.v7.media.MediaRouteSelector;
40
import android.support.v7.media.MediaRouter;
41
import android.support.v7.media.MediaRouter.Callback;
42
import android.support.v7.media.MediaRouter.ProviderInfo;
43
import android.support.v7.media.MediaRouter.RouteInfo;
44
import android.util.Log;
45
import android.view.KeyEvent;
46
import android.view.Menu;
47
import android.view.MenuItem;
48
import android.view.View;
49
import android.view.View.OnClickListener;
50
import android.view.ViewGroup;
51
import android.widget.AdapterView;
52
import android.widget.AdapterView.OnItemClickListener;
53
import android.widget.ArrayAdapter;
54
import android.widget.ImageButton;
55
import android.widget.ListView;
56
import android.widget.SeekBar;
57
import android.widget.SeekBar.OnSeekBarChangeListener;
58
import android.widget.TabHost;
59
import android.widget.TabHost.OnTabChangeListener;
60
import android.widget.TabHost.TabSpec;
61
import android.widget.TextView;
62
import android.widget.Toast;
63
64
import com.example.android.mediarouter.R;
65
import com.example.android.mediarouter.provider.SampleMediaRouteProvider;
66
67
import java.io.File;
68
69
/**
70
* <h3>Media Router Support Activity</h3>
71
* <p/>
72
* <p>
73
* This demonstrates how to use the {@link MediaRouter} API to build an
74
* application that allows the user to send content to various rendering
75
* targets.
76
* </p>
77
*/
78
public class MainActivity extends ActionBarActivity {
79
private static final String TAG = "MainActivity";
80
private static final String DISCOVERY_FRAGMENT_TAG = "DiscoveryFragment";
81
82
private MediaRouter mMediaRouter;
83
private MediaRouteSelector mSelector;
84
private LibraryAdapter mLibraryItems;
85
private PlaylistAdapter mPlayListItems;
86
private TextView mInfoTextView;
87
private ListView mLibraryView;
88
private ListView mPlayListView;
89
private ImageButton mPauseResumeButton;
90
private ImageButton mStopButton;
91
private SeekBar mSeekBar;
92
private boolean mPaused;
93
private boolean mNeedResume;
94
private boolean mSeeking;
95
96
private RemoteControlClient mRemoteControlClient;
97
private ComponentName mEventReceiver;
98
private AudioManager mAudioManager;
99
private PendingIntent mMediaPendingIntent;
100
101
private final Handler mHandler = new Handler();
102
private final Runnable mUpdateSeekRunnable = new Runnable() {
103
@Override
104
public void run() {
105
updateProgress();
106
// update UI every 1 second
107
mHandler.postDelayed(this, 1000);
108
}
109
};
110
111
private final SessionManager mSessionManager = new SessionManager("app");
112
private Player mPlayer;
113
114
private final MediaRouter.Callback mMediaRouterCB = new MediaRouter.Callback() {
115
// Return a custom callback that will simply log all of the route events
116
// for demonstration purposes.
117
@Override
118
public void onRouteAdded(MediaRouter router, RouteInfo route) {
119
Log.d(TAG, "onRouteAdded: route=" + route);
120
}
121
122
@Override
123
public void onRouteChanged(MediaRouter router, RouteInfo route) {
124
Log.d(TAG, "onRouteChanged: route=" + route);
125
}
126
127
@Override
128
public void onRouteRemoved(MediaRouter router, RouteInfo route) {
129
Log.d(TAG, "onRouteRemoved: route=" + route);
130
}
131
132
@Override
133
public void onRouteSelected(MediaRouter router, RouteInfo route) {
134
Log.d(TAG, "onRouteSelected: route=" + route);
135
136
mPlayer = Player.create(MainActivity.this, route);
137
mPlayer.updatePresentation();
138
mSessionManager.setPlayer(mPlayer);
139
mSessionManager.unsuspend();
140
141
registerRemoteControlClient();
142
updateUi();
143
}
144
145
@Override
146
public void onRouteUnselected(MediaRouter router, RouteInfo route) {
147
Log.d(TAG, "onRouteUnselected: route=" + route);
148
unregisterRemoteControlClient();
149
150
PlaylistItem item = getCheckedPlaylistItem();
151
if (item != null) {
152
long pos = item.getPosition() +
153
(mPaused ? 0 : (SystemClock.elapsedRealtime() - item.getTimestamp()));
154
mSessionManager.suspend(pos);
155
}
156
mPlayer.updatePresentation();
157
mPlayer.release();
158
}
159
160
@Override
161
public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) {
162
Log.d(TAG, "onRouteVolumeChanged: route=" + route);
163
}
164
165
@Override
166
public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo route) {
167
Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route);
168
mPlayer.updatePresentation();
169
}
170
171
@Override
172
public void onProviderAdded(MediaRouter router, ProviderInfo provider) {
173
Log.d(TAG, "onRouteProviderAdded: provider=" + provider);
174
}
175
176
@Override
177
public void onProviderRemoved(MediaRouter router, ProviderInfo provider) {
178
Log.d(TAG, "onRouteProviderRemoved: provider=" + provider);
179
}
180
181
@Override
182
public void onProviderChanged(MediaRouter router, ProviderInfo provider) {
183
Log.d(TAG, "onRouteProviderChanged: provider=" + provider);
184
}
185
};
186
187
private final OnAudioFocusChangeListener mAfChangeListener = new OnAudioFocusChangeListener() {
188
@Override
189
public void onAudioFocusChange(int focusChange) {
190
if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
191
Log.d(TAG, "onAudioFocusChange: LOSS_TRANSIENT");
192
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
193
Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_GAIN");
194
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
195
Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_LOSS");
196
}
197
}
198
};
199
200
@Override
201
protected void onCreate(Bundle savedInstanceState) {
202
// Be sure to call the super class.
203
super.onCreate(savedInstanceState);
204
if (savedInstanceState != null) {
205
mPlayer = (Player) savedInstanceState.getSerializable("mPlayer");
206
}
207
208
// Get the media router service.
209
mMediaRouter = MediaRouter.getInstance(this);
210
211
// Create a route selector for the type of routes that we care about.
212
mSelector =
213
new MediaRouteSelector.Builder().addControlCategory(MediaControlIntent
214
.CATEGORY_LIVE_AUDIO).addControlCategory(MediaControlIntent
215
.CATEGORY_LIVE_VIDEO).addControlCategory(MediaControlIntent
216
.CATEGORY_REMOTE_PLAYBACK).addControlCategory(SampleMediaRouteProvider
217
.CATEGORY_SAMPLE_ROUTE).build();
218
219
// Add a fragment to take care of media route discovery.
220
// This fragment automatically adds or removes a callback whenever the activity
221
// is started or stopped.
222
FragmentManager fm = getSupportFragmentManager();
223
DiscoveryFragment fragment =
224
(DiscoveryFragment) fm.findFragmentByTag(DISCOVERY_FRAGMENT_TAG);
225
if (fragment == null) {
226
fragment = new DiscoveryFragment(mMediaRouterCB);
227
fragment.setRouteSelector(mSelector);
228
fm.beginTransaction().add(fragment, DISCOVERY_FRAGMENT_TAG).commit();
229
} else {
230
fragment.setCallback(mMediaRouterCB);
231
fragment.setRouteSelector(mSelector);
232
}
233
234
// Populate an array adapter with streaming media items.
235
String[] mediaNames = getResources().getStringArray(R.array.media_names);
236
String[] mediaUris = getResources().getStringArray(R.array.media_uris);
237
mLibraryItems = new LibraryAdapter();
238
for (int i = 0; i < mediaNames.length; i++) {
239
mLibraryItems.add(new MediaItem(
240
"[streaming] " + mediaNames[i], Uri.parse(mediaUris[i]), "video/mp4"));
241
}
242
243
// Scan local external storage directory for media files.
244
File externalDir = Environment.getExternalStorageDirectory();
245
if (externalDir != null) {
246
File list[] = externalDir.listFiles();
247
if (list != null) {
248
for (int i = 0; i < list.length; i++) {
249
String filename = list[i].getName();
250
if (filename.matches(".*\\.(m4v|mp4)")) {
251
mLibraryItems.add(new MediaItem(
252
"[local] " + filename, Uri.fromFile(list[i]), "video/mp4"));
253
}
254
}
255
}
256
}
257
258
mPlayListItems = new PlaylistAdapter();
259
260
// Initialize the layout.
261
setContentView(R.layout.sample_media_router);
262
263
TabHost tabHost = (TabHost) findViewById(R.id.tabHost);
264
tabHost.setup();
265
String tabName = getResources().getString(R.string.library_tab_text);
266
TabSpec spec1 = tabHost.newTabSpec(tabName);
267
spec1.setContent(R.id.tab1);
268
spec1.setIndicator(tabName);
269
270
tabName = getResources().getString(R.string.playlist_tab_text);
271
TabSpec spec2 = tabHost.newTabSpec(tabName);
272
spec2.setIndicator(tabName);
273
spec2.setContent(R.id.tab2);
274
275
tabName = getResources().getString(R.string.statistics_tab_text);
276
TabSpec spec3 = tabHost.newTabSpec(tabName);
277
spec3.setIndicator(tabName);
278
spec3.setContent(R.id.tab3);
279
280
tabHost.addTab(spec1);
281
tabHost.addTab(spec2);
282
tabHost.addTab(spec3);
283
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
284
@Override
285
public void onTabChanged(String arg0) {
286
updateUi();
287
}
288
});
289
290
mLibraryView = (ListView) findViewById(R.id.media);
291
mLibraryView.setAdapter(mLibraryItems);
292
mLibraryView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
293
mLibraryView.setOnItemClickListener(new OnItemClickListener() {
294
@Override
295
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
296
updateButtons();
297
}
298
});
299
300
mPlayListView = (ListView) findViewById(R.id.playlist);
301
mPlayListView.setAdapter(mPlayListItems);
302
mPlayListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
303
mPlayListView.setOnItemClickListener(new OnItemClickListener() {
304
@Override
305
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
306
updateButtons();
307
}
308
});
309
310
mInfoTextView = (TextView) findViewById(R.id.info);
311
312
mPauseResumeButton = (ImageButton) findViewById(R.id.pause_resume_button);
313
mPauseResumeButton.setOnClickListener(new OnClickListener() {
314
@Override
315
public void onClick(View v) {
316
mPaused = !mPaused;
317
if (mPaused) {
318
mSessionManager.pause();
319
} else {
320
mSessionManager.resume();
321
}
322
}
323
});
324
325
mStopButton = (ImageButton) findViewById(R.id.stop_button);
326
mStopButton.setOnClickListener(new OnClickListener() {
327
@Override
328
public void onClick(View v) {
329
mPaused = false;
330
mSessionManager.stop();
331
}
332
});
333
334
mSeekBar = (SeekBar) findViewById(R.id.seekbar);
335
mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
336
@Override
337
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
338
PlaylistItem item = getCheckedPlaylistItem();
339
if (fromUser && item != null && item.getDuration() > 0) {
340
long pos = progress * item.getDuration() / 100;
341
mSessionManager.seek(item.getItemId(), pos);
342
item.setPosition(pos);
343
item.setTimestamp(SystemClock.elapsedRealtime());
344
}
345
}
346
347
@Override
348
public void onStartTrackingTouch(SeekBar seekBar) {
349
mSeeking = true;
350
}
351
352
@Override
353
public void onStopTrackingTouch(SeekBar seekBar) {
354
mSeeking = false;
355
updateUi();
356
}
357
});
358
359
// Schedule Ui update
360
mHandler.postDelayed(mUpdateSeekRunnable, 1000);
361
362
// Build the PendingIntent for the remote control client
363
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
364
mEventReceiver =
365
new ComponentName(getPackageName(), SampleMediaButtonReceiver.class.getName());
366
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
367
mediaButtonIntent.setComponent(mEventReceiver);
368
mMediaPendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0);
369
370
// Create and register the remote control client
371
registerRemoteControlClient();
372
373
// Set up playback manager and player
374
mPlayer = Player.create(MainActivity.this, mMediaRouter.getSelectedRoute());
375
mSessionManager.setPlayer(mPlayer);
376
mSessionManager.setCallback(new SessionManager.Callback() {
377
@Override
378
public void onStatusChanged() {
379
updateUi();
380
}
381
382
@Override
383
public void onItemChanged(PlaylistItem item) {
384
}
385
});
386
387
updateUi();
388
}
389
390
private void registerRemoteControlClient() {
391
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
392
// Create the RCC and register with AudioManager and MediaRouter
393
mAudioManager.requestAudioFocus(mAfChangeListener, AudioManager.STREAM_MUSIC,
394
AudioManager.AUDIOFOCUS_GAIN);
395
mAudioManager.registerMediaButtonEventReceiver(mEventReceiver);
396
mRemoteControlClient = new RemoteControlClient(mMediaPendingIntent);
397
mAudioManager.registerRemoteControlClient(mRemoteControlClient);
398
mMediaRouter.addRemoteControlClient(mRemoteControlClient);
399
SampleMediaButtonReceiver.setActivity(MainActivity.this);
400
mRemoteControlClient.setTransportControlFlags(RemoteControlClient
401
.FLAG_KEY_MEDIA_PLAY_PAUSE);
402
mRemoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING);
403
}
404
}
405
406
private void unregisterRemoteControlClient() {
407
// Unregister the RCC with AudioManager and MediaRouter
408
if (mRemoteControlClient != null) {
409
mRemoteControlClient.setTransportControlFlags(0);
410
mAudioManager.abandonAudioFocus(mAfChangeListener);
411
mAudioManager.unregisterMediaButtonEventReceiver(mEventReceiver);
412
mAudioManager.unregisterRemoteControlClient(mRemoteControlClient);
413
mMediaRouter.removeRemoteControlClient(mRemoteControlClient);
414
SampleMediaButtonReceiver.setActivity(null);
415
mRemoteControlClient = null;
416
}
417
}
418
419
public boolean handleMediaKey(KeyEvent event) {
420
if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
421
switch (event.getKeyCode()) {
422
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: {
423
Log.d(TAG, "Received Play/Pause event from RemoteControlClient");
424
mPaused = !mPaused;
425
if (mPaused) {
426
mSessionManager.pause();
427
} else {
428
mSessionManager.resume();
429
}
430
return true;
431
}
432
case KeyEvent.KEYCODE_MEDIA_PLAY: {
433
Log.d(TAG, "Received Play event from RemoteControlClient");
434
if (mPaused) {
435
mPaused = false;
436
mSessionManager.resume();
437
}
438
return true;
439
}
440
case KeyEvent.KEYCODE_MEDIA_PAUSE: {
441
Log.d(TAG, "Received Pause event from RemoteControlClient");
442
if (!mPaused) {
443
mPaused = true;
444
mSessionManager.pause();
445
}
446
return true;
447
}
448
case KeyEvent.KEYCODE_MEDIA_STOP: {
449
Log.d(TAG, "Received Stop event from RemoteControlClient");
450
mPaused = false;
451
mSessionManager.stop();
452
return true;
453
}
454
default:
455
break;
456
}
457
}
458
return false;
459
}
460
461
@Override
462
public boolean onKeyDown(int keyCode, KeyEvent event) {
463
return handleMediaKey(event) || super.onKeyDown(keyCode, event);
464
}
465
466
@Override
467
public boolean onKeyUp(int keyCode, KeyEvent event) {
468
return handleMediaKey(event) || super.onKeyUp(keyCode, event);
469
}
470
471
@Override
472
public void onStart() {
473
// Be sure to call the super class.
474
super.onStart();
475
}
476
477
@Override
478
public void onPause() {
479
// pause media player for local playback case only
480
if (!mPlayer.isRemotePlayback() && !mPaused) {
481
mNeedResume = true;
482
mSessionManager.pause();
483
}
484
super.onPause();
485
}
486
487
@Override
488
public void onResume() {
489
// resume media player for local playback case only
490
if (!mPlayer.isRemotePlayback() && mNeedResume) {
491
mSessionManager.resume();
492
mNeedResume = false;
493
}
494
super.onResume();
495
}
496
497
@Override
498
public void onDestroy() {
499
// Unregister the remote control client
500
unregisterRemoteControlClient();
501
502
mPaused = false;
503
mSessionManager.stop();
504
mPlayer.release();
505
super.onDestroy();
506
}
507
508
@Override
509
public boolean onCreateOptionsMenu(Menu menu) {
510
// Be sure to call the super class.
511
super.onCreateOptionsMenu(menu);
512
513
// Inflate the menu and configure the media router action provider.
514
getMenuInflater().inflate(R.menu.sample_media_router_menu, menu);
515
516
MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);
517
MediaRouteActionProvider mediaRouteActionProvider =
518
(MediaRouteActionProvider) MenuItemCompat.getActionProvider(mediaRouteMenuItem);
519
mediaRouteActionProvider.setRouteSelector(mSelector);
520
521
// Return true to show the menu.
522
return true;
523
}
524
525
private void updateProgress() {
526
// Estimate content position from last status time and elapsed time.
527
// (Note this might be slightly out of sync with remote side, however
528
// it avoids frequent polling the MRP.)
529
int progress = 0;
530
PlaylistItem item = getCheckedPlaylistItem();
531
if (item != null) {
532
int state = item.getState();
533
long duration = item.getDuration();
534
if (duration <= 0) {
535
if (state == MediaItemStatus.PLAYBACK_STATE_PLAYING ||
536
state == MediaItemStatus.PLAYBACK_STATE_PAUSED) {
537
mSessionManager.updateStatus();
538
}
539
} else {
540
long position = item.getPosition();
541
long timeDelta =
542
mPaused ? 0 : (SystemClock.elapsedRealtime() - item.getTimestamp());
543
progress = (int) (100.0 * (position + timeDelta) / duration);
544
}
545
}
546
mSeekBar.setProgress(progress);
547
}
548
549
private void updateUi() {
550
updatePlaylist();
551
updateRouteDescription();
552
updateButtons();
553
}
554
555
private void updatePlaylist() {
556
mPlayListItems.clear();
557
for (PlaylistItem item : mSessionManager.getPlaylist()) {
558
mPlayListItems.add(item);
559
}
560
mPlayListView.invalidate();
561
}
562
563
564
private void updateRouteDescription() {
565
RouteInfo route = mMediaRouter.getSelectedRoute();
566
mInfoTextView.setText(
567
"Currently selected route:" + "\nName: " + route.getName() + "\nProvider: " +
568
route.getProvider().getPackageName() + "\nDescription: " +
569
route.getDescription() + "\nStatistics: " +
570
mSessionManager.getStatistics());
571
}
572
573
private void updateButtons() {
574
MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute();
575
// show pause or resume icon depending on current state
576
mPauseResumeButton.setImageResource(
577
mPaused ? R.drawable.ic_action_play : R.drawable.ic_action_pause);
578
// disable pause/resume/stop if no session
579
mPauseResumeButton.setEnabled(mSessionManager.hasSession());
580
mStopButton.setEnabled(mSessionManager.hasSession());
581
// only enable seek bar when duration is known
582
PlaylistItem item = getCheckedPlaylistItem();
583
mSeekBar.setEnabled(item != null && item.getDuration() > 0);
584
if (mRemoteControlClient != null) {
585
mRemoteControlClient.setPlaybackState(mPaused ? RemoteControlClient.PLAYSTATE_PAUSED :
586
RemoteControlClient.PLAYSTATE_PLAYING);
587
}
588
}
589
590
private PlaylistItem getCheckedPlaylistItem() {
591
int count = mPlayListView.getCount();
592
int index = mPlayListView.getCheckedItemPosition();
593
if (count > 0) {
594
if (index < 0 || index >= count) {
595
index = 0;
596
mPlayListView.setItemChecked(0, true);
597
}
598
return mPlayListItems.getItem(index);
599
}
600
return null;
601
}
602
603
public static final class DiscoveryFragment extends MediaRouteDiscoveryFragment {
604
private static final String TAG = "DiscoveryFragment";
605
private Callback mCallback;
606
607
public DiscoveryFragment() {
608
mCallback = null;
609
}
610
611
public DiscoveryFragment(Callback cb) {
612
mCallback = cb;
613
}
614
615
public void setCallback(Callback cb) {
616
mCallback = cb;
617
}
618
619
@Override
620
public Callback onCreateCallback() {
621
return mCallback;
622
}
623
624
@Override
625
public int onPrepareCallbackFlags() {
626
// Add the CALLBACK_FLAG_UNFILTERED_EVENTS flag to ensure that we will
627
// observe and log all route events including those that are for routes
628
// that do not match our selector. This is only for demonstration purposes
629
// and should not be needed by most applications.
630
return super.onPrepareCallbackFlags() | MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS;
631
}
632
}
633
634
private static final class MediaItem {
635
public final String mName;
636
public final Uri mUri;
637
public final String mMime;
638
639
public MediaItem(String name, Uri uri, String mime) {
640
mName = name;
641
mUri = uri;
642
mMime = mime;
643
}
644
645
@Override
646
public String toString() {
647
return mName;
648
}
649
}
650
651
private final class LibraryAdapter extends ArrayAdapter<MediaItem> {
652
public LibraryAdapter() {
653
super(MainActivity.this, R.layout.media_item);
654
}
655
656
@Override
657
public View getView(int position, View convertView, ViewGroup parent) {
658
final View v;
659
if (convertView == null) {
660
v = getLayoutInflater().inflate(R.layout.media_item, null);
661
} else {
662
v = convertView;
663
}
664
665
final MediaItem item = getItem(position);
666
667
TextView tv = (TextView) v.findViewById(R.id.item_text);
668
tv.setText(item.mName);
669
670
ImageButton b = (ImageButton) v.findViewById(R.id.item_action);
671
b.setImageResource(R.drawable.ic_suggestions_add);
672
b.setTag(item);
673
b.setOnClickListener(new OnClickListener() {
674
@Override
675
public void onClick(View v) {
676
if (item != null) {
677
mSessionManager.add(item.mUri, item.mMime);
678
Toast.makeText(MainActivity.this, R.string.playlist_item_added_text,
679
Toast.LENGTH_SHORT).show();
680
}
681
}
682
});
683
684
return v;
685
}
686
}
687
688
private final class PlaylistAdapter extends ArrayAdapter<PlaylistItem> {
689
public PlaylistAdapter() {
690
super(MainActivity.this, R.layout.media_item);
691
}
692
693
@Override
694
public View getView(int position, View convertView, ViewGroup parent) {
695
final View v;
696
if (convertView == null) {
697
v = getLayoutInflater().inflate(R.layout.media_item, null);
698
} else {
699
v = convertView;
700
}
701
702
final PlaylistItem item = getItem(position);
703
704
TextView tv = (TextView) v.findViewById(R.id.item_text);
705
tv.setText(item.toString());
706
707
ImageButton b = (ImageButton) v.findViewById(R.id.item_action);
708
b.setImageResource(R.drawable.ic_suggestions_delete);
709
b.setTag(item);
710
b.setOnClickListener(new OnClickListener() {
711
@Override
712
public void onClick(View v) {
713
if (item != null) {
714
mSessionManager.remove(item.getItemId());
715
Toast.makeText(MainActivity.this, R.string.playlist_item_removed_text,
716
Toast.LENGTH_SHORT).show();
717
}
718
}
719
});
720
721
return v;
722
}
723
}
724
}