In Android 9 media output controls were added to the volume selection dialog.
I would like to have a button in my app which would open these system media output controls so that the user can choose where the audio will be played.
I could find nothing about this in: Android 9 features and APIs, Behavior changes: apps targeting API level 28+ and Behavior changes: all apps
You are looking for MediaRouter API.
public class MediaRouterPlaybackActivity extends AppCompatActivity {
private MediaRouteSelector mSelector;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create a route selector for the type of routes your app supports.
mSelector = new MediaRouteSelector.Builder()
// These are the framework-supported intents
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
.build();
}
}
For further reference: https://developer.android.com/guide/topics/media/mediarouter#java
Also check Create a MediaRouteSelector section.
I did some research about this as well so I know that Android Pie is capable of this, but they haven't provided a way for us developers to do it yet (at least I haven't found a way). The CATEGORY_LIVE_AUDIO in MediaRouterSelector is also only for secondary output; you can read about it on the developer website. So if you must do it, I think the only way you can do that right now is to do a workaround programmatically:
Disconnect current device (The important of this step depends on the device; I have to do this on my Essential phone)
Use BluetoothAdapter.getBondedDevices() to get a list of paired devices.
Connect to the one you want
Try this - it works for me on Android 11:
Intent intent = new Intent("com.android.settings.panel.action.MEDIA_OUTPUT");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
Related
I'm trying to implement the fingerprint authentication and I want to make the user register a new fingerprint if He hasn't one. I know how to start an Intent to the Security Settings menu, but I can't find anywhere how to highlight the option I want the user to click. Do you think it's possible?
Thanks for your help
If you're targeting Android P and higher, you can take the user 1 step further with the specific Intent Settings.ACTION_FINGERPRINT_ENROLL.
You can use this way:
#RequiresApi(api = Build.VERSION_CODES.P)
private void startFingerprintEnrollment(#NonNull AppCompatActivity activity) {
Intent intent = new Intent(Settings.ACTION_FINGERPRINT_ENROLL);
activity.startActivityForResult(intent, REQUESTCODE_FINGERPRINT_ENROLLMENT);
}
For lower versions you can use what you're already using. Unfortunately there is no way to highlight the specific Setting row.
I try to use android's mediabrowser and sample by google works fine on phones (https://github.com/googlesamples/android-media-controller)
But on android TV it can't find any app which supported this feature
final Intent mediaBrowserIntent =
new Intent(MediaBrowserServiceCompat.SERVICE_INTERFACE);
final List<ResolveInfo> services =
packageManager.queryIntentServices(mediaBrowserIntent,
PackageManager.GET_RESOLVED_FILTER);
in services placed only current app
Could you help me get API to collect last used mediadata? I can't find any description or guide for creating TV launcher (which have access to last used or recommended media by another app)
I just wanna GET metadata like https://developer.android.com/training/tv/playback/now-playing.html
or
http://corochann.com/android-tv-application-hands-on-tutorial-11-277.html
You can query for all active media sessions using the method MediaSessionManager.getActiveSessions(notificationListnerComponentName) which will return a list of alla ctive mediacontrollers with the most active as the first item in the list.
Code sample:
MediaSessionManager mediaSessionManager = context.getSystemService(Context.MEDIA_SESSION_SERVICE);
List<MediaController> activeMediaSessionControllers = mediaSessionManager.getActiveSessions(null);
According to the system voice command docs, you can open an application with a voice command. e.g. OK Google - open foobar. Also according to the docs, this Works by default; no specific intent.
In my sample development app, this isn't working. I've tried adding a few combinations of action and category permutations to the intent-filter, but no luck so far.
I'm targeting a minimum SDK of 23, testing on a device with 6.0.1.
Should this work, and if so, what are the changes to a new empty activity project I need to enable it?
As far as I am aware, Google simply iterates over a list of installed applications and opens the corresponding application if it finds an exact match.
To test this, use the following Intent
final String PACKAGE_NAME_GOOGLE_NOW = "com.google.android.googlequicksearchbox";
final String GOOGLE_NOW_SEARCH_ACTIVITY = ".SearchActivity";
final String APP_NAME = "Open " +getString(R.string.app_name);
final Intent startMyAppIntent = new Intent(Intent.ACTION_WEB_SEARCH);
startMyAppIntent.setComponent(new ComponentName(PACKAGE_NAME_GOOGLE_NOW,
PACKAGE_NAME_GOOGLE_NOW + GOOGLE_NOW_SEARCH_ACTIVITY));
startMyAppIntent.putExtra(SearchManager.QUERY, APP_NAME);
startMyAppIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
startActivity(startMyAppIntent);
} catch (final ActivityNotFoundException e) {
e.printStackTrace();
}
If this opens your application, then it is simply a case of the phonetics of your application name, or how Google interprets your pronunciation of it.
I do think that there should be an option to add a 'phonetic app label' to the application's manifest (or some other globally available configuration file), so Google could open your application if the unique name is not common enough to generate a voice search result.
If this doesn't open your application, check that you are correctly defining your application name in the manifest as follows:
<application
android:label="#string/app_name"
Ok, so I am trying to figure at how to get an up-to-date list of available chromecast devices, I'm doing this so that my app can check when the chromecast is not in use and then open my receiver app.
I am having some unexpected behaviour from the code below:
public class MainActivity extends Activity {
...
#Override
public void onCreate(Bundle savedInstanceState) {
...
mMediaRouterCallback = new MyMediaRouterCallback();
mMediaRouter = MediaRouter.getInstance(context);
mMediaRouteSelector = new MediaRouteSelector.Builder()
.addControlCategory(CastMediaControlIntent.categoryForCast(context.getString(R.string.app_id)))
.build();
mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback,
MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
}
This adds a MediaRouter callback to the MediaRouter. I have chosen to use the active scan flag.
private class MyMediaRouterCallback extends MediaRouter.Callback {
...
#Override
public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) {
Log.d(TAG, "Description 1 " + info.getDescription());
mSelectedDevice = CastDevice.getFromBundle(info.getExtras());
Log.d(TAG, "Description 2 " + mSelectedDevice.toString());
if(info.getDescription().equals("Chromecast")) {
// code to launch chromecast receiver app here.
}
}
}
My implementation of the MediaRouter.Callback overrides onRouteAdded, it simply prints some information about the devices it has found Description 1 describes the receiver app the device is using, description 2 gives its name.
However when this code is run initially the same device is discovered twice printing:
07-05 21:01:12.270: D/MainActivity(9730): Description 1 Casting HelloText
07-05 21:01:12.280: D/MainActivity(9730): Description 2 "Downstairs"
07-05 21:01:12.280: D/MainActivity(9730): Description 1 Casting HelloText
07-05 21:01:12.280: D/MainActivity(9730): Description 2 "Downstairs"
Then periodically the onRouteAdded callback is called sometimes only listing the device once, other times listing the device twice. My understanding however is that this callback should only be called when a new route is added.
I want to find all the available devices on command, not at random intervals that I can't control, what do I need to be doing? I can't find a callback that seems to be appropriate for this situation (such as whenever devices update/change), nor can I find a way to list them without using callbacks, so I'm a bit stuck.
(I have been basing these tests of the HelloText-Android example found here https://github.com/googlecast/CastHelloText-android, also I started this (my first android project) only a couple of days ago, so I apologise if I am missing something horrendously obvious)
Thanks in advance.
Call getRoutes() to get the list of known routes at the point in time that you desire. Iterate over them. Call matchesSelector() on each to filter out those that match your desired control category.
If you are listening for "onRouteAdded()", you would also need to listen to "onRouteRemoved()" to do a correct bookkeeping; if a device is added, it can be removed and added again so if you just listen to onRouteAdded(), it may seem it is being added multiple times. Getting the list from MedaiaRoute.getRoutes() might be easier if you don't want to be notified immediately and only want to know the list at certain points on demand.
in agreement with the recent post from Android Developers http://android-developers.blogspot.pt/2013/10/getting-your-sms-apps-ready-for-kitkat.html ,I was trying to prepare my app to the new android version, but encountered a problem with the part they suggest to create a dialog to let the user set the app as the default application to handle SMS's :
Android Developers Post
public class ComposeSmsActivity extends Activity {
#Override
protected void onResume() {
super.onResume();
final String myPackageName = getPackageName();
if (!Telephony.Sms.getDefaultSmsPackage(this).equals(myPackageName)) {
// App is not default.
// Show the "not currently set as the default SMS app" interface
View viewGroup = findViewById(R.id.not_default_app);
viewGroup.setVisibility(View.VISIBLE);
// Set up a button that allows the user to change the default SMS app
Button button = (Button) findViewById(R.id.change_default_app);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent =
new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME,
myPackageName);
startActivity(intent);
}
});
} else {
// App is the default.
// Hide the "not currently set as the default SMS app" interface
View viewGroup = findViewById(R.id.not_default_app);
viewGroup.setVisibility(View.GONE);
}
}
}
the code itself in pretty much straightforward, but I'm unable to access to Telephony.Sms.getDefaultSmsPackage because it says that Telephony cannot be resolved, and I can't find any import or declaration that would fix that.
Can anyone please help?
android.provider.Telephony simply doesn't exist yet (as of API 18 - 4.3).
This class will be added in 4.4 (presumably API 19), and that blog post is highlighting the changes that you should make once the new API is released so you aren't surprised when the time comes.
From the end of the post:
To help you make the changes, we'll soon be providing the necessary SDK components for Android 4.4 that allow you to compile and test your changes on Android 4.4.
Don't forget that you should wrap this code in an API version check so you don't run into issues with older versions that don't have this class.
this change will break all the SMS blocking apps.
"Note that—beginning with Android 4.4—any attempt by your app to abort the SMS_RECEIVED_ACTION broadcast will be ignored so all apps interested have the chance to receive it."
Do you think there is a way to go around this?!
Maybe at least on Root?
Apparently there is with root access. The latest version Cerberus app claim to be doing this.
Now, if only I knew how they do it :(