diff --git a/app/src/main/java/ch/blinkenlights/android/vanilla/PlaybackActivity.java b/app/src/main/java/ch/blinkenlights/android/vanilla/PlaybackActivity.java index 73d5b583..923b8357 100644 --- a/app/src/main/java/ch/blinkenlights/android/vanilla/PlaybackActivity.java +++ b/app/src/main/java/ch/blinkenlights/android/vanilla/PlaybackActivity.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.content.BroadcastReceiver; @@ -49,6 +50,7 @@ import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.Process; +import android.util.Log; import android.view.ContextMenu; import android.view.KeyEvent; import android.view.Menu; @@ -70,6 +72,12 @@ public abstract class PlaybackActivity extends Activity View.OnClickListener, CoverView.Callback { + /** + * This constant is unavailable on Android < N. + * For newer versions the constant is {@link Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND} + */ + private static final int FLAG_RECEIVER_INCLUDE_BACKGROUND = 0x01000000; + private Action mUpAction; private Action mDownAction; @@ -733,12 +741,14 @@ public abstract class PlaybackActivity extends Activity * * @param songIntent intent containing song id as {@link Long} in its "id" extra. */ + @SuppressLint("WrongConstant") // flag is ignored on Android < 7.0 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); + requestPlugins.addFlags(FLAG_RECEIVER_INCLUDE_BACKGROUND); sendBroadcast(requestPlugins); } @@ -793,7 +803,11 @@ public abstract class PlaybackActivity extends Activity 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); + if (request.resolveActivity(getPackageManager()) != null) { + startActivity(request); + } else { + Log.e("PluginSystem", "Couldn't start plugin activity for " + request); + } } mLastRequestedCtx = null; diff --git a/app/src/main/java/ch/blinkenlights/android/vanilla/PluginUtils.java b/app/src/main/java/ch/blinkenlights/android/vanilla/PluginUtils.java index 2cd57044..97af14fe 100644 --- a/app/src/main/java/ch/blinkenlights/android/vanilla/PluginUtils.java +++ b/app/src/main/java/ch/blinkenlights/android/vanilla/PluginUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Oleg Chernovskiy + * Copyright (C) 2016-2018 Oleg Chernovskiy * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,7 +18,9 @@ package ch.blinkenlights.android.vanilla; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.widget.Toast; import java.util.List; @@ -52,16 +54,28 @@ public class PluginUtils { static final String EXTRA_PLUGIN_MAP = "ch.blinkenlights.android.vanilla.internal.extra.PLUGIN_MAP"; public static boolean checkPlugins(Context ctx) { - List resolved = ctx.getPackageManager().queryBroadcastReceivers(new Intent(ACTION_REQUEST_PLUGIN_PARAMS), 0); - if(!resolved.isEmpty()) { - // If plugin is just installed, Android will not deliver intents to its receiver - // until it's started at least one time + PackageManager pm = ctx.getPackageManager(); + List resolved = pm.queryBroadcastReceivers(new Intent(ACTION_REQUEST_PLUGIN_PARAMS), 0); + if (!resolved.isEmpty()) { + // If plugin is just installed, Android will not deliver intents + // to its receiver until it's started at least one time + boolean hasPlugins = false; for (ResolveInfo ri : resolved) { Intent awaker = new Intent(ACTION_WAKE_PLUGIN); awaker.setPackage(ri.activityInfo.packageName); - ctx.startService(awaker); + + // all plugins must have respective activity that can handle ACTION_WAKE_PLUGIN + if (awaker.resolveActivity(pm) != null) { + hasPlugins = true; + ctx.startActivity(awaker); + } else { + // need to upgrade the plugin from service-based plugin system to activity-based + CharSequence pluginName = ri.loadLabel(pm); + String error = String.format(ctx.getString(R.string.plugin_needs_upgrade), pluginName); + Toast.makeText(ctx, error, Toast.LENGTH_SHORT).show(); + } } - return true; + return hasPlugins; } return false; diff --git a/app/src/main/res/values/translatable.xml b/app/src/main/res/values/translatable.xml index e9a1b356..b8778c66 100644 --- a/app/src/main/res/values/translatable.xml +++ b/app/src/main/res/values/translatable.xml @@ -381,6 +381,7 @@ THE SOFTWARE. Neutral Plugins + Please upgrade plugin %s to the latest version Standard