Android 如何将媒体控制器按钮放在通知栏上?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12526228/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 10:53:30  来源:igfitidea点击:

How to put media controller button on notification bar?

androidmediacontrollerandroid-music-player

提问by Leap Bun

I am creating a music player application. I want to show the media controller on notification bar while my application is running in background. It looks like Google player.

我正在创建一个音乐播放器应用程序。我想在我的应用程序在后台运行时在通知栏上显示媒体控制器。它看起来像谷歌播放器。

enter image description here

enter image description here

How to do this?

这该怎么做?

采纳答案by Roadies

For getting media player controller in your app simply follow this:

要在您的应用程序中获取媒体播放器控制器,只需按照以下步骤操作:

Call this method in your MainActivity

在您的 MainActivity 中调用此方法

public void showNotification(View view){
        new MyNotification(this);
        finish();
    }

Create a new MynotificationClass

创建一个新的 MynotificationClass

public class MyNotification extends Notification {

private Context ctx;
private NotificationManager mNotificationManager;

@SuppressLint("NewApi")
public MyNotification(Context ctx){
    super();
    this.ctx=ctx;
    String ns = Context.NOTIFICATION_SERVICE;
    mNotificationManager = (NotificationManager) ctx.getSystemService(ns);
    CharSequence tickerText = "Shortcuts";
    long when = System.currentTimeMillis();
    Notification.Builder builder = new Notification.Builder(ctx);
    @SuppressWarnings("deprecation")
    Notification notification=builder.getNotification();
    notification.when=when;
    notification.tickerText=tickerText;
    notification.icon=R.drawable.ic_launcher;

    RemoteViews contentView=new RemoteViews(ctx.getPackageName(), R.layout.messageview);

    //set the button listeners
    setListeners(contentView);

    notification.contentView = contentView;
    notification.flags |= Notification.FLAG_ONGOING_EVENT;
    CharSequence contentTitle = "From Shortcuts";
    mNotificationManager.notify(548853, notification);
}

public void setListeners(RemoteViews view){
    //radio listener
    Intent radio=new Intent(ctx,HelperActivity.class);
    radio.putExtra("DO", "radio");
    PendingIntent pRadio = PendingIntent.getActivity(ctx, 0, radio, 0);
    view.setOnClickPendingIntent(R.id.radio, pRadio);

    //volume listener
    Intent volume=new Intent(ctx, HelperActivity.class);
    volume.putExtra("DO", "volume");
    PendingIntent pVolume = PendingIntent.getActivity(ctx, 1, volume, 0);
    view.setOnClickPendingIntent(R.id.volume, pVolume);

    //reboot listener
    Intent reboot=new Intent(ctx, HelperActivity.class);
    reboot.putExtra("DO", "reboot");
    PendingIntent pReboot = PendingIntent.getActivity(ctx, 5, reboot, 0);
    view.setOnClickPendingIntent(R.id.reboot, pReboot);

    //top listener
    Intent top=new Intent(ctx, HelperActivity.class);
    top.putExtra("DO", "top");
    PendingIntent pTop = PendingIntent.getActivity(ctx, 3, top, 0);
    view.setOnClickPendingIntent(R.id.top, pTop);*/

    //app listener
    Intent app=new Intent(ctx, com.example.demo.HelperActivity.class);
    app.putExtra("DO", "app");
    PendingIntent pApp = PendingIntent.getActivity(ctx, 4, app, 0);
    view.setOnClickPendingIntent(R.id.btn1, pApp);
}

}

Create a HelperActivity class

创建一个 HelperActivity 类

public class HelperActivity extends Activity {

private HelperActivity ctx;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    ctx = this;
    String action = (String) getIntent().getExtras().get("DO");
    if (action.equals("radio")) {
        //Your code
    } else if (action.equals("volume")) {
        //Your code
    } else if (action.equals("reboot")) {
        //Your code
    } else if (action.equals("top")) {
        //Your code
    } else if (action.equals("app")) {
        //Your code
    }

    if (!action.equals("reboot"))
        finish();
}

@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
}
}

XML layout for Notificationlayout.xml

Notificationlayout.xml 的 XML 布局

<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<TextView
    android:id="@+id/msglbl"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="test" />

<TextView
    android:id="@+id/message"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@+id/msglbl" />

<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="play" android:layout_margin="10dp"/>

</RelativeLayout>

回答by Gilco

Here is the example above done correctly to the new API

这是上面对新 API 正确完成的示例

In your main, when you want to start a notification instantiate the class:

在您的主要内容中,当您想要启动通知时,请实例化该类:

NotificationPanel nPanel = new NotificationPanel(MyActivity);

And when you want to cancel notification: (as it is an onGoing notification)

当你想取消通知时:(因为它是一个正在进行的通知)

nPanel.notificationCancel();    

Then create the class for the notification caller:

然后为通知调用者创建类:

public class NotificationPanel {

private Context parent;
private NotificationManager nManager;
private NotificationCompat.Builder nBuilder;
private RemoteViews remoteView;

public NotificationPanel(Context parent) {
    // TODO Auto-generated constructor stub
    this.parent = parent;
    nBuilder = new NotificationCompat.Builder(parent)
    .setContentTitle("Parking Meter")
    .setSmallIcon(R.drawable.ic_launcher)
    .setOngoing(true);

    remoteView = new RemoteViews(parent.getPackageName(), R.layout.notificationview);

    //set the button listeners
    setListeners(remoteView);
    nBuilder.setContent(remoteView);

    nManager = (NotificationManager) parent.getSystemService(Context.NOTIFICATION_SERVICE);
    nManager.notify(2, nBuilder.build());
}

public void setListeners(RemoteViews view){
    //listener 1
    Intent volume = new Intent(parent,NotificationReturnSlot.class);
    volume.putExtra("DO", "volume");
    PendingIntent btn1 = PendingIntent.getActivity(parent, 0, volume, 0);
    view.setOnClickPendingIntent(R.id.btn1, btn1);

    //listener 2
    Intent stop = new Intent(parent, NotificationReturnSlot.class);
    stop.putExtra("DO", "stop");
    PendingIntent btn2 = PendingIntent.getActivity(parent, 1, stop, 0);
    view.setOnClickPendingIntent(R.id.btn2, btn2);
}

public void notificationCancel() {
    nManager.cancel(2);
}
}    

Then add the return class that accept the pending intent:

然后添加接受挂起意图的返回类:

public class NotificationReturnSlot extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    String action = (String) getIntent().getExtras().get("DO");
    if (action.equals("volume")) {
        Log.i("NotificationReturnSlot", "volume");
        //Your code
     } else if (action.equals("stopNotification")) {
         //Your code
        Log.i("NotificationReturnSlot", "stopNotification");
     }
     finish();
    }
}

Then you need to make a XML file for the button. This is a simple one:

然后您需要为按钮制作一个 XML 文件。这是一个简单的:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >

<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:text="volume" />

<Button
    android:id="@+id/btn2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:text="Stop" />

<TextView
    android:id="@+id/message"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@+id/msglbl" />

Last and not least, the Manifest file:

最后,同样重要的是,Manifest 文件:

   <activity android:name=".NotificationReturnSlot"
        android:launchMode="singleTask"
        android:taskAffinity=""
        android:excludeFromRecents="true"/>

回答by Gilco

Return/send data from notification to your original Activity; the changes needed for the Example above:

从通知返回/发送数据到您的原始活动;上述示例所需的更改:

NotificationPanel nPanel = new NotificationPanel(MyActivity)

How to use the Notification Button to resume the same Stack and Activity that created the Notification:

如何使用通知按钮恢复创建通知的相同堆栈和活动:

1) Make sure the Activity is not Destroyed (optional), change the Back button to put the task in the back and not destroy it:

1) 确保 Activity 没有被销毁(可选),更改后退按钮将任务放在后面而不是销毁它:

@Override    
void onBackPressed() {
   Log.d("onBackPressed", "onBackPressed Called");
   moveTaskToBack(true);
}

2) In the Menifest add this to the Activity:

2) 在 Menifest 中将此添加到活动中:

android:launchMode="singleTop"

3) Add those flags for your Intent Instance: (volume is the Intent instance)

3)为您的意图实例添加这些标志:(卷是意图实例)

Intent volume = new Intent(....);
....
volume.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
volume.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

and as well you can add the following (optional):

您还可以添加以下内容(可选):

volume.setAction(Intent.ACTION_MAIN);
volume.addCategory(Intent.CATEGORY_LAUNCHER)

4) In the PendingIntent instance don't use any flags:

4) 在 PendingIntent 实例中不要使用任何标志:

PendingIntent btn1 = PendingIntent.getActivity(parent, 0, volume, 0);

5) And catch the intent in your Activity with onNewIntent(Intent intent) call back:

5) 并通过 onNewIntent(Intent intent) 回调捕捉您的 Activity 中的意图:

@Override
protected void onNewIntent(Intent intent) {
    // TODO Auto-generated method stub
    super.onNewIntent(intent);
    setIntent(intent);
    Log.i("onNewIntent", intent.toString());    // DEBUG - very useful
    if (intent.getExtras() != null) {   // As the Intent we send back has extras, if it don't, it is a different Intent. it is possible to use TRY {} CATCH{} for this as well to find if Extras is NULL.
        String tmp;
        tmp = intent.getExtras().getString("DO");
        if (tmp != null) {  
            if (tmp.equals("volume"))
                Log.i("onNewIntent", "Volume");
            else if (tmp.equals("stop"))
                Log.i("onNewIntent", "Stop");
            else
                Log.i("onNewIntent", "Didnt capture the extras of the Intent - " + tmp);
        } else {
            Log.i("onNewIntent", "No new Intent");
        }
    }
}

回答by Julian Shen

You need to create a RemoteView and show it as a notification.

您需要创建一个 RemoteView 并将其显示为通知。

Please refer to the follow document

请参考以下文档

Status Notifications(Creating a Custom Notification Layout)

状态通知(创建自定义通知布局)