我想将音频路由到蓝牙耳机,或类似的输出(如果已连接)。我使用mediarouter是为了这个目的,因为我知道我打算做什么。但我不能让它工作,因为它没有发现我的蓝牙耳机,虽然它配对。
我将发布我用于活动的代码。
我想问,为了这个目的,我必须使用蓝牙框架吗?因为我只想路由音频,而不是处理连接或配对蓝牙设备。
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.MenuItemCompat;
import androidx.mediarouter.app.MediaRouteActionProvider;
import androidx.mediarouter.app.MediaRouteControllerDialog;
import androidx.mediarouter.app.MediaRouteControllerDialogFragment;
import androidx.mediarouter.app.MediaRouteDialogFactory;
import androidx.mediarouter.media.MediaControlIntent;
import androidx.mediarouter.media.MediaRouteSelector;
import androidx.mediarouter.media.MediaRouter;
public class MediaRouterPlaybackActivity extends AppCompatActivity {
private MediaRouter mMediaRouter;
// Active Presentation, set to null if no secondary screen is enabled
private SamplePresentation mPresentation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.media_route);
mTextStatus = findViewById(R.id.textStatus);
Toolbar myToolbar = findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
Log.d("tag", "on create");
// Enable clicks on the 'change color' button
mButton = findViewById(R.id.button1);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showNextColor();
}
});
// BEGIN_INCLUDE(getMediaRouter)
// Get the MediaRouter service
mMediaRouter = MediaRouter.getInstance(this);
// END_INCLUDE(getMediaRouter)
}
/**
* Implementing a {@link android.media.MediaRouter.Callback} to update the displayed
* {@link android.app.Presentation} when a route is selected, unselected or the
* presentation display has changed. The provided stub implementation
* {@link android.media.MediaRouter.SimpleCallback} is extended and only
* {@link android.media.MediaRouter.SimpleCallback#onRouteSelected(android.media.MediaRouter, int, android.media.MediaRouter.RouteInfo)}
* ,
* {@link android.media.MediaRouter.SimpleCallback#onRouteUnselected(android.media.MediaRouter, int, android.media.MediaRouter.RouteInfo)}
* and
* {@link android.media.MediaRouter.SimpleCallback#onRoutePresentationDisplayChanged(android.media.MediaRouter, android.media.MediaRouter.RouteInfo)}
* are overridden to update the displayed {@link android.app.Presentation} in
* {@link #updatePresentation()}. These callbacks enable or disable the
* second screen presentation based on the routing provided by the
* {@link android.media.MediaRouter} for {@link android.media.MediaRouter#ROUTE_TYPE_LIVE_VIDEO}
* streams. @
*/
private final MediaRouter.Callback mMediaRouterCallback =
new MediaRouter.Callback() {
// BEGIN_INCLUDE(SimpleCallback)
/**
* A new route has been selected as active. Disable the current
* route and enable the new one.
*/
@Override
public void onRouteSelected(@NonNull MediaRouter router, @NonNull MediaRouter.RouteInfo route, int reason) {
Log.d("Media route", "onRouteUnselected: route=" + route);
updatePresentation();
}
/**
* The route has been unselected.
*/
@Override
public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info, int reason) {
Log.d("Media route", "onRouteUnselected: route=" + info);
updatePresentation();
}
/**
* The route's presentation display has changed. This callback
* is called when the presentation has been activated, removed
* or its properties have changed.
*/
@Override
public void onRoutePresentationDisplayChanged(MediaRouter router, MediaRouter.RouteInfo route) {
updatePresentation();
}
// END_INCLUDE(SimpleCallback)
};
/**
* Updates the displayed presentation to enable a secondary screen if it has
* been selected in the {@link android.media.MediaRouter} for the
* {@link android.media.MediaRouter#ROUTE_TYPE_LIVE_VIDEO} type. If no screen has been
* selected by the {@link android.media.MediaRouter}, the current screen is disabled.
* Otherwise a new {@link SamplePresentation} is initialized and shown on
* the secondary screen.
*/
private void updatePresentation() {
// BEGIN_INCLUDE(updatePresentationInit)
// Get the selected route for live video
MediaRouter.RouteInfo selectedRoute = mMediaRouter.getSelectedRoute();
// Get its Display if a valid route has been selected
Display selectedDisplay = selectedRoute.getPresentationDisplay();
// END_INCLUDE(updatePresentationInit)
// BEGIN_INCLUDE(updatePresentationDismiss)
/*
* Dismiss the current presentation if the display has changed or no new
* route has been selected
*/
if (mPresentation != null && mPresentation.getDisplay() != selectedDisplay) {
mPresentation.dismiss();
mPresentation = null;
mButton.setEnabled(false);
mTextStatus.setText("not connected");
}
// END_INCLUDE(updatePresentationDismiss)
// BEGIN_INCLUDE(updatePresentationNew)
/*
* Show a new presentation if the previous one has been dismissed and a
* route has been selected.
*/
if (mPresentation == null && selectedDisplay != null) {
// Initialise a new Presentation for the Display
mPresentation = new SamplePresentation(this, selectedDisplay);
mPresentation.setOnDismissListener(mOnDismissListener);
// Try to show the presentation, this might fail if the display has
// gone away in the mean time
try {
mPresentation.show();
mTextStatus.setText("test");
mButton.setEnabled(true);
showNextColor();
} catch (WindowManager.InvalidDisplayException ex) {
// Couldn't show presentation - display was already removed
mPresentation = null;
}
}
// END_INCLUDE(updatePresentationNew)
}
@Override
protected void onResume() {
super.onResume();
// BEGIN_INCLUDE(addCallback)
// Register a callback for all events related to live video devices
mMediaRouter.addCallback(
new MediaRouteSelector.Builder()
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
.build(),
mMediaRouterCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY
);
// END_INCLUDE(addCallback)
// Show the 'Not connected' status message
mButton.setEnabled(false);
mTextStatus.setText("not connected");
// Update the displays based on the currently active routes
updatePresentation();
}
@Override
protected void onPause() {
super.onPause();
// BEGIN_INCLUDE(onPause)
// Stop listening for changes to media routes.
mMediaRouter.removeCallback(mMediaRouterCallback);
// END_INCLUDE(onPause)
}
@Override
protected void onStop() {
super.onStop();
// BEGIN_INCLUDE(onStop)
// Dismiss the presentation when the activity is not visible.
if (mPresentation != null) {
mPresentation.dismiss();
mPresentation = null;
}
// BEGIN_INCLUDE(onStop)
}
/**
* Inflates the ActionBar or options menu. The menu file defines an item for
* the {@link android.app.MediaRouteActionProvider}, which is registered here for all
* live video devices using {@link android.media.MediaRouter#ROUTE_TYPE_LIVE_VIDEO}.
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
// BEGIN_INCLUDE(MediaRouteActionProvider)
// Configure the media router action provider
MenuItem mediaRouteMenuItem = menu.findItem(R.id.menu_media_route);
MediaRouteActionProvider mediaRouteActionProvider =
(MediaRouteActionProvider) MenuItemCompat.getActionProvider(mediaRouteMenuItem);
mediaRouteActionProvider.setAlwaysVisible((true));
mediaRouteActionProvider.setRouteSelector(
new MediaRouteSelector.Builder()
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
.build());
mediaRouteActionProvider.setDialogFactory(new MediaRouteDialogFactory() {
@Override
public MediaRouteControllerDialogFragment onCreateControllerDialogFragment() {
return new MediaRouteControllerDialogFragment() {
@Override
public MediaRouteControllerDialog onCreateControllerDialog(
Context context, Bundle savedInstanceState) {
MediaRouteControllerDialog mControllerDialog = new MediaRouteControllerDialog(MediaRouterPlaybackActivity.this);
return mControllerDialog;
}
};
}
});
// BEGIN_INCLUDE(MediaRouteActionProvider)
return true;
}
/**
* Listens for dismissal of the {@link SamplePresentation} and removes its
* reference.
*/
private final DialogInterface.OnDismissListener mOnDismissListener =
new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
if (dialog == mPresentation) {
mPresentation = null;
}
}
};
// Views used to display status information on the primary screen
private TextView mTextStatus;
private Button mButton;
/**
* Displays the next color on the secondary screen if it is activate.
*/
private void showNextColor() {
}
}```
I working with this example I found in android docs.
Do you might know how to solve it ?
Im not trying to use google cast only to route to bluetooth speakers or headphones.
暂无答案!
目前还没有任何答案,快来回答吧!