Add "plugins" menu option in full playback view (#559)
- refactor plugin querying in a way that now any library activity can utilize it - Make doc more thorough - Hopefully fix empty plugin list bug (flag was added to wrong intent)
This commit is contained in:
parent
2b07abdc8b
commit
2bc17ec2dd
@ -29,8 +29,6 @@ import java.util.ArrayList;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
@ -40,13 +38,10 @@ import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.TableRow;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
|
||||
@ -308,6 +303,7 @@ public class FullPlaybackActivity extends SlidingPlaybackActivity
|
||||
menu.add(0, MENU_ENQUEUE_GENRE, 30, R.string.enqueue_current_genre);
|
||||
menu.add(0, MENU_ADD_TO_PLAYLIST, 30, R.string.add_to_playlist);
|
||||
menu.add(0, MENU_SHARE, 30, R.string.share);
|
||||
menu.add(0, MENU_PLUGINS, 30, R.string.plugins);
|
||||
mFavorites = menu.add(0, MENU_SONG_FAVORITE, 0, R.string.add_to_favorites).setIcon(R.drawable.btn_rating_star_off_mtrl_alpha).setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||
|
||||
// ensure that mFavorites is updated
|
||||
@ -383,6 +379,11 @@ public class FullPlaybackActivity extends SlidingPlaybackActivity
|
||||
dialog.create().show();
|
||||
}
|
||||
break;
|
||||
case MENU_PLUGINS:
|
||||
Intent songIntent = new Intent();
|
||||
songIntent.putExtra("id", song.id);
|
||||
queryPluginsForIntent(songIntent);
|
||||
break;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
@ -26,20 +26,14 @@ package ch.blinkenlights.android.vanilla;
|
||||
import ch.blinkenlights.android.medialibrary.MediaLibrary;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.PaintDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
@ -60,10 +54,6 @@ import android.widget.TextView;
|
||||
import android.widget.SearchView;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
@ -143,19 +133,6 @@ public class LibraryActivity
|
||||
* The last used action from the menu. Used with ACTION_LAST_USED.
|
||||
*/
|
||||
private int mLastAction = ACTION_PLAY;
|
||||
/**
|
||||
* Holds last intent that was passed to the context menu
|
||||
*/
|
||||
private Intent mLastRequestedCtx;
|
||||
/**
|
||||
* Plugin descriptions and packages.
|
||||
* Keys are plugin names, values are their packages
|
||||
*/
|
||||
private Map<String, ApplicationInfo> mPlugins = new HashMap<>();
|
||||
/**
|
||||
* Broadcast receiver for plugin collecting
|
||||
*/
|
||||
private BroadcastReceiver mPluginInfoReceiver;
|
||||
/**
|
||||
* The pager adapter that manages each media ListView.
|
||||
*/
|
||||
@ -189,7 +166,6 @@ public class LibraryActivity
|
||||
mViewPager = pager;
|
||||
|
||||
SharedPreferences settings = PlaybackService.getSettings(this);
|
||||
mPluginInfoReceiver = new PluginBroadcastReceiver();
|
||||
|
||||
mBottomBarControls = (BottomBarControls)findViewById(R.id.bottombar_controls);
|
||||
mBottomBarControls.setOnClickListener(this);
|
||||
@ -213,43 +189,6 @@ public class LibraryActivity
|
||||
bindControlButtons();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows plugin selection dialog. Be sure that {@link #mLastRequestedCtx} is initialized
|
||||
* and {@link #mPlugins} are populated before calling this.
|
||||
*
|
||||
* @see PluginBroadcastReceiver
|
||||
*/
|
||||
private void showPluginMenu() {
|
||||
Set<String> pluginNames = mPlugins.keySet();
|
||||
final String[] pNamesArr = pluginNames.toArray(new String[pluginNames.size()]);
|
||||
new AlertDialog.Builder(this)
|
||||
.setItems(pNamesArr, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
long id = mLastRequestedCtx.getLongExtra("id", LibraryAdapter.INVALID_ID);
|
||||
Song resolved = MediaUtils.getSongByTypeId(LibraryActivity.this, MediaUtils.TYPE_SONG, id);
|
||||
if (resolved != null) {
|
||||
ApplicationInfo selected = mPlugins.get(pNamesArr[which]);
|
||||
Intent request = new Intent(PluginUtils.ACTION_LAUNCH_PLUGIN);
|
||||
request.setPackage(selected.packageName);
|
||||
request.putExtra(PluginUtils.EXTRA_PARAM_URI, Uri.fromFile(new File(resolved.path)));
|
||||
request.putExtra(PluginUtils.EXTRA_PARAM_SONG_TITLE, resolved.title);
|
||||
request.putExtra(PluginUtils.EXTRA_PARAM_SONG_ARTIST, resolved.artist);
|
||||
request.putExtra(PluginUtils.EXTRA_PARAM_SONG_ALBUM, resolved.album);
|
||||
startService(request);
|
||||
}
|
||||
|
||||
mLastRequestedCtx = null;
|
||||
}
|
||||
})
|
||||
.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
mLastRequestedCtx = null;
|
||||
}
|
||||
}).create().show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestart()
|
||||
{
|
||||
@ -267,18 +206,6 @@ public class LibraryActivity
|
||||
updateHeaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
registerReceiver(mPluginInfoReceiver, new IntentFilter(PluginUtils.ACTION_HANDLE_PLUGIN_PARAMS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
unregisterReceiver(mPluginInfoReceiver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the tab order and update the tab bars if needed.
|
||||
*/
|
||||
@ -776,12 +703,7 @@ public class LibraryActivity
|
||||
break;
|
||||
}
|
||||
case CTX_MENU_PLUGINS: {
|
||||
// obtain list of plugins anew - some plugins may be installed/deleted
|
||||
mPlugins.clear();
|
||||
mLastRequestedCtx = intent;
|
||||
Intent requestPlugins = new Intent(PluginUtils.ACTION_REQUEST_PLUGIN_PARAMS);
|
||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
||||
sendBroadcast(requestPlugins);
|
||||
queryPluginsForIntent(intent);
|
||||
break;
|
||||
}
|
||||
case CTX_MENU_MORE_FROM_ARTIST: {
|
||||
@ -1004,21 +926,4 @@ public class LibraryActivity
|
||||
handler.sendMessage(mHandler.obtainMessage(MSG_SAVE_PAGE, position, 0));
|
||||
}
|
||||
}
|
||||
|
||||
private class PluginBroadcastReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
List<ResolveInfo> resolved = getPackageManager().queryBroadcastReceivers(new Intent(PluginUtils.ACTION_REQUEST_PLUGIN_PARAMS), 0);
|
||||
if (PluginUtils.ACTION_HANDLE_PLUGIN_PARAMS.equals(intent.getAction())) {
|
||||
// plugin answered, store it in the map
|
||||
String pluginName = intent.getStringExtra(PluginUtils.EXTRA_PARAM_PLUGIN_NAME);
|
||||
ApplicationInfo info = intent.getParcelableExtra(PluginUtils.EXTRA_PARAM_PLUGIN_APP);
|
||||
mPlugins.put(pluginName, info);
|
||||
|
||||
if (mPlugins.size() == resolved.size()) { // got all plugins
|
||||
showPluginMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,13 +25,24 @@ package ch.blinkenlights.android.vanilla;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
@ -75,6 +86,19 @@ public abstract class PlaybackActivity extends Activity
|
||||
* The looper for the worker thread.
|
||||
*/
|
||||
protected Looper mLooper;
|
||||
/**
|
||||
* Broadcast receiver for plugin collecting
|
||||
*/
|
||||
private BroadcastReceiver mPluginInfoReceiver;
|
||||
/**
|
||||
* Holds last intent that was passed to the context menu
|
||||
*/
|
||||
private Intent mLastRequestedCtx;
|
||||
/**
|
||||
* Plugin descriptions and packages.
|
||||
* Keys are plugin names, values are their packages
|
||||
*/
|
||||
private Map<String, ApplicationInfo> mPlugins = new HashMap<>();
|
||||
|
||||
protected CoverView mCoverView;
|
||||
protected ImageButton mPlayPauseButton;
|
||||
@ -92,6 +116,8 @@ public abstract class PlaybackActivity extends Activity
|
||||
|
||||
PlaybackService.addTimelineCallback(this);
|
||||
|
||||
mPluginInfoReceiver = new PluginBroadcastReceiver();
|
||||
|
||||
setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
|
||||
HandlerThread thread = new HandlerThread(getClass().getName(), Process.THREAD_PRIORITY_LOWEST);
|
||||
@ -138,6 +164,7 @@ public abstract class PlaybackActivity extends Activity
|
||||
public void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
registerReceiver(mPluginInfoReceiver, new IntentFilter(PluginUtils.ACTION_HANDLE_PLUGIN_PARAMS));
|
||||
if (PlaybackService.hasInstance()) {
|
||||
PlaybackService service = PlaybackService.get(this);
|
||||
service.userActionTriggered();
|
||||
@ -145,6 +172,11 @@ public abstract class PlaybackActivity extends Activity
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
unregisterReceiver(mPluginInfoReceiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event)
|
||||
@ -375,7 +407,8 @@ public abstract class PlaybackActivity extends Activity
|
||||
static final int MENU_EMPTY_QUEUE = 16;
|
||||
static final int MENU_ADD_TO_PLAYLIST = 17;
|
||||
static final int MENU_SHARE = 18;
|
||||
static final int MENU_GO_HOME= 19;
|
||||
static final int MENU_GO_HOME = 19;
|
||||
static final int MENU_PLUGINS = 20; // used in FullPlaybackActivity
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
@ -661,4 +694,80 @@ public abstract class PlaybackActivity extends Activity
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends broadcast query that wakes plugins are queries them for info.
|
||||
* Answers are later processed in {@link PluginBroadcastReceiver}
|
||||
*
|
||||
* @param songIntent intent containing song id as {@link Long} in its "id" extra.
|
||||
*/
|
||||
protected void queryPluginsForIntent(Intent songIntent) {
|
||||
// obtain list of plugins anew - some plugins may be installed/deleted
|
||||
mPlugins.clear();
|
||||
mLastRequestedCtx = songIntent;
|
||||
Intent requestPlugins = new Intent(PluginUtils.ACTION_REQUEST_PLUGIN_PARAMS);
|
||||
requestPlugins.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
||||
sendBroadcast(requestPlugins);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast receiver that handles return intents from queried plugins.
|
||||
* Answered ones are stored in {@link #mPlugins}.
|
||||
* Shows plugin menu once all queried plugins have answered.
|
||||
*
|
||||
* @see #showPluginMenu()
|
||||
*/
|
||||
private class PluginBroadcastReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
List<ResolveInfo> resolved = getPackageManager().queryBroadcastReceivers(new Intent(PluginUtils.ACTION_REQUEST_PLUGIN_PARAMS), 0);
|
||||
if (PluginUtils.ACTION_HANDLE_PLUGIN_PARAMS.equals(intent.getAction())) {
|
||||
// plugin answered, store it in the map
|
||||
String pluginName = intent.getStringExtra(PluginUtils.EXTRA_PARAM_PLUGIN_NAME);
|
||||
ApplicationInfo info = intent.getParcelableExtra(PluginUtils.EXTRA_PARAM_PLUGIN_APP);
|
||||
mPlugins.put(pluginName, info);
|
||||
|
||||
if (mPlugins.size() == resolved.size()) { // got all plugins
|
||||
showPluginMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows plugin selection dialog. Be sure that {@link #mLastRequestedCtx} is initialized
|
||||
* and {@link #mPlugins} are populated before calling this.
|
||||
*
|
||||
* @see PluginBroadcastReceiver
|
||||
*/
|
||||
private void showPluginMenu() {
|
||||
Set<String> pluginNames = mPlugins.keySet();
|
||||
final String[] pNamesArr = pluginNames.toArray(new String[pluginNames.size()]);
|
||||
new AlertDialog.Builder(this)
|
||||
.setItems(pNamesArr, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
long id = mLastRequestedCtx.getLongExtra("id", LibraryAdapter.INVALID_ID);
|
||||
Song resolved = MediaUtils.getSongByTypeId(PlaybackActivity.this, MediaUtils.TYPE_SONG, id);
|
||||
if (resolved != null) {
|
||||
ApplicationInfo selected = mPlugins.get(pNamesArr[which]);
|
||||
Intent request = new Intent(PluginUtils.ACTION_LAUNCH_PLUGIN);
|
||||
request.setPackage(selected.packageName);
|
||||
request.putExtra(PluginUtils.EXTRA_PARAM_URI, Uri.fromFile(new File(resolved.path)));
|
||||
request.putExtra(PluginUtils.EXTRA_PARAM_SONG_TITLE, resolved.title);
|
||||
request.putExtra(PluginUtils.EXTRA_PARAM_SONG_ARTIST, resolved.artist);
|
||||
request.putExtra(PluginUtils.EXTRA_PARAM_SONG_ALBUM, resolved.album);
|
||||
startService(request);
|
||||
}
|
||||
|
||||
mLastRequestedCtx = null;
|
||||
}
|
||||
})
|
||||
.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
mLastRequestedCtx = null;
|
||||
}
|
||||
}).create().show();
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user