【问题标题】:Android notification with buttons on it带有按钮的 Android 通知
【发布时间】:2012-05-09 13:03:17
【问题描述】:

我正在尝试用 2 个按钮发出通知:

  • 一个人带我回到活动中
  • 另一个关闭它

有没有人知道如何捕捉按钮点击事件(记住 Activity 已暂停)?

【问题讨论】:

  • 说实话,我不喜欢你努力背后的想法,或者我不明白。 android中的普通通知在右侧有X,如果你点击它们,你会被重定向到活动。
  • 我们教他们并向他们展示 Android 开发者指南 ;)

标签: android android-notifications


【解决方案1】:

我很高兴发布它!工作了一夜之后,我发现了一些东西。所以,我们开始吧!

1.为您的通知创建一个 xml 布局文件。

2。使用 Notification.Builder 创建通知。添加您想要的所有内容(图标、声音等)后,请执行以下操作:

        //R.layout.notification_layout is from step 1

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

        setListeners(contentView);//look at step 3

        notification.contentView = contentView;

3.创建一个方法 setListeners。在这个方法中你必须这样写:

    //HelperActivity will be shown at step 4

    Intent radio=new Intent(ctx, packagename.youractivity.class);  
    radio.putExtra("AN_ACTION", "do");//if necessary

    PendingIntent pRadio = PendingIntent.getActivity(ctx, 0, radio, 0);
    //R.id.radio is a button from the layout which is created at step 2  view.setOnClickPendingIntent(R.id.radio, pRadio); 

    //Follows exactly my code!
    Intent volume=new Intent(ctx, tsapalos11598712.bill3050.shortcuts.helper.HelperActivity.class);
    volume.putExtra("DO", "volume");</p>

    //HERE is the whole trick. Look at pVolume. I used 1 instead of 0.
    PendingIntent pVolume = PendingIntent.getActivity(ctx, 1, volume, 0);
    view.setOnClickPendingIntent(R.id.volume, pVolume);

4.对于我的要求,我使用了一个响应意图的 HelperActivity。但对你来说,我认为没有必要。

如果你想要完整的源代码,你可以浏览它或者从我的 git repo 下载它。代码是供个人使用的,所以不要指望用大量的cmets来阅读华丽的代码。 https://github.com/BILLyTheLiTTle/AndroidProject_Shortcuts

以上所有内容,回答了从不同按钮捕获事件的问题。

关于取消通知我把你重定向到这里

How to clear a notification in Android

请记住在第一次调用通知时使用您在通知方法中解析的id

【讨论】:

  • 这在 ICS 4.0.4 上非常有效!您应该考虑正确格式化您的答案,以便其他用户可以很好地查看您的答案。
  • 你是对的。我应该从一开始就这样做。我希望现在更好。由于您的评论,我添加了下载源代码的链接。从现在开始,所有的读者都应该感谢你,而不是我。新年快乐,新年快乐
  • 你真好!新年快乐!!
【解决方案2】:

这里有一个完整的例子

    //Add this code to onCreate or some onclick Buttton
    NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext());
    long when = System.currentTimeMillis();
    builder.setSmallIcon(R.drawable.ic_notification);
    Intent notificationIntent = new Intent(getApplicationContext(), notificationActivity.class).putExtra("notification", "1");
    PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 1, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    builder.setContentIntent(contentIntent);
    Notification notification = builder.getNotification();
    notification.when = when;

    RemoteViews remoteViews = new RemoteViews(getApplicationContext().getPackageName(), R.layout.notification_view);
    remoteViews.setTextViewText(R.id.tvName, "New Name");
    listener(remoteViews,getApplicationContext());


    notification.contentView = remoteViews;
    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    manager.notify(1, notification);

然后你就可以定义监听方法了:

    public void listener(RemoteViews remoteViews, Context context) {
    // you have to make intetns for each action (your Buttons)
    Intent intent = new Intent("Accept");
    Intent intent2 = new Intent("Reject");

    PendingIntent pendingIntent = PendingIntent.getBroadcast(context,1,intent,0);
    PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context,1,intent2,0);

    // add actions here !
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("Accept");
    intentFilter.addAction("Reject");


    BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if(intent.getAction().equals("Accept")){
                Toast.makeText(context, "Accepted !!", Toast.LENGTH_SHORT).show();
            } else if(intent.getAction().equals("Reject")) {
                Toast.makeText(context, "Rejected !!", Toast.LENGTH_SHORT).show();
            }
        }
    };

    context.registerReceiver(receiver,intentFilter);
    remoteViews.setOnClickPendingIntent(R.id.ivRequest,pendingIntent);
    remoteViews.setOnClickPendingIntent(R.id.ivReject,pendingIntent2);

}

这里是通知视图布局,用于定制您的通知。

    <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="16dp">

<TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:text="Request from "
    />

<TextView
    android:id="@+id/tvName"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_marginStart="15dp"
    android:layout_toRightOf="@id/textView"
    android:text="Amin"
    />

<ImageView
    android:id="@+id/ivRequest"
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:layout_alignParentEnd="true"
    android:layout_centerVertical="true"
    android:src="@drawable/notification"
    />

<ImageView
    android:id="@+id/ivReject"
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:layout_marginEnd="10dp"
    android:layout_toLeftOf="@id/ivRequest"
    android:layout_centerVertical="true"
    android:src="@drawable/trash"
    />

  </RelativeLayout>

【讨论】:

  • 这个例子做了它声称的复制和粘贴(在你添加你的drawables之后)。但是,builder.setCustomContentView(remoteViews); 会比 notification.contentView = remoteViews; 好,builder.build() 由于弃用而优于 builder.getNotification()。 (您必须为这些更改重新排列代码)。
  • 是的,我从自己的 SimpleProject 复制了代码,感谢您的更新 :)
【解决方案3】:

对于 ICS,这个问题很容易回答,因为所需的行为反映了默认通知:您可以关闭将通知向右滑动,您可以定义哪个活动 在用户按下它时将其发送到,只需使用PendingIntent

// The PendingIntent to launch our activity if the user selects this
// notification.  Note the use of FLAG_CANCEL_CURRENT so that, if there
// is already an active matching pending intent, cancel it and replace
// it with the new array of Intents.
PendingIntent contentIntent = PendingIntent.getActivities(this, 0,
        makeMessageIntentStack(this, from, message), PendingIntent.FLAG_CANCEL_CURRENT);

代码取自http://developer.android.com/guide/topics/ui/notifiers/notifications.html

【讨论】:

  • 谢谢你的回答,虽然这不是我问的。我想做的是一个带有 2 个按钮的通知(已经有布局),但我在捕捉 onClick 时遇到问题事件,我希望其中一个关闭 ACTIVITY 而另一个关闭通知的默认操作。
【解决方案4】:

如果您想为按钮分配特定的意图:

views.setOnClickPendingIntent(R.id.your_button_id, pendingIntent);

我想当按钮被点击时你只需要发送一个意图,所以你必须避免设置主要的通知意图

notification.contentIntent = yourPendingIntent;

否则(如果您像往常一样设置“notification.contentIntent = pendingIntent;”)两个意图都将被调用,这可能不是您想要的/用户期望的。

如果您仍想按下通知的其他部分来调用该一般意图(或任何其他),您可以使用与上述相同的按视图分配意图的方法。别忘了设置

android:clickable="true"

到您想要跟踪 onClick() 的任何视图。

您可以通过他们调用的活动中的额外内容来跟踪这些意图。 如果调用您的主/启动器活动,那么您将在此处跟踪它们(因为它来自此方法的 javadoc):

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    Bundle data = intent.getExtras();

    if (data != null && data.containsKey(YOUR_INTENT_KEY_SOURCE_CONSTANT)) {
       // process your notification intent
    }

    // go on with smth else
}

【讨论】:

    【解决方案5】:

    您可以通过为您的Notification.Builder 设置操作并为每个操作定义PendingIntent 来简单地在您的Notification 中添加操作按钮

    下面是示例代码:

        NotificationCompat.Builder mBuilder =
                    new NotificationCompat.Builder(this)
                    .setSmallIcon(R.drawable.notification_icon)
                    .setContentTitle("My notification")
                    .setContentText("Hello World!")
           .addAction(R.drawable.action_posetive,"posetive",PendingIntent.getActivity(0,intent,0))
    .addAction(R.drawable.action_clear,"clear",PendingIntent.getActivity(0,intent,0));
            NotificationManager mNotificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            mNotificationManager.notify(0, mBuilder.build());
    

    【讨论】:

      【解决方案6】:

      对我来说,这非常有效.. 我会写下整个例子.. 这是用于通知创建

      public void createNotification2(String aMessage) {
          final int NOTIFY_ID = 11;
          String name = getString(R.string.app_name);
          String id = getString(R.string.app_name); // The user-visible name of the channel.
          String description = getString(R.string.app_name); // The user-visible description of the channel.
          NotificationCompat.Builder builder;
          if (notifManager == null) {
              notifManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
          }
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
              int importance = NotificationManager.IMPORTANCE_HIGH;
              NotificationChannel mChannel = notifManager.getNotificationChannel(id);
              if (mChannel == null) {
                  mChannel = new NotificationChannel(id, name, importance);
                  mChannel.setDescription(description);
                  mChannel.enableVibration(true);
                  mChannel.setLightColor(getColor(R.color.colorPrimaryDark));
                  mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
                  notifManager.createNotificationChannel(mChannel);
              }
          } else {
      
          }
          Intent Off_broadcastIntent = new Intent(this, Database_Update.class);
          Off_broadcastIntent.setAction("on");
          Off_broadcastIntent.putExtra("toastMessage", "1");
          PendingIntent Off_actionIntent = PendingIntent.getService(this, 0, Off_broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
      
          Intent on_broadcastIntent = new Intent(this, Database_Update.class);
          on_broadcastIntent.setAction("off");
          on_broadcastIntent.putExtra("toastMessage", "0");
          PendingIntent on_actionIntent = PendingIntent.getService(this, 0, on_broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
      
          Intent cancel_broadcastIntent = new Intent(this, Database_Update.class);
          cancel_broadcastIntent.setAction("cancel");
          cancel_broadcastIntent.putExtra("toastMessage", "close");
          PendingIntent cancel_actionIntent = PendingIntent.getService(this, 0, cancel_broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
      
          Intent content_intent = new Intent(this, Status_Page.class);
          content_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
          PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, content_intent, PendingIntent.FLAG_UPDATE_CURRENT);
      
      
          NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, id)
                  .setSmallIcon(android.R.drawable.ic_popup_reminder)
                  .setContentTitle(name)
                  .setPriority(NotificationCompat.PRIORITY_HIGH)
                  .setContentIntent(pendingIntent)
                  .setAutoCancel(false)
                  .setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400})
                  .addAction(R.drawable.block, "ON", Off_actionIntent)
                  .addAction(R.drawable.notification, "OFF", on_actionIntent)
                  .addAction(R.drawable.clear, "CLOSE", cancel_actionIntent);
          Notification notification = mBuilder.build();
          notification.flags = Notification.FLAG_NO_CLEAR|Notification.FLAG_ONGOING_EVENT;
          notifManager.notify(11, notification);
      }
      

      在 Android 清单中

      <service android:name=".Database_Update"></service>
      

      这是服务类

      public class Database_Update extends Service {
      String result="";
      
      Realm realm;
      BlockList blockList;
      @Override
      public void onCreate() {
          try {
              RealmConfiguration config = new RealmConfiguration.Builder()
                      .name("notification.realm")
                      .schemaVersion(1)
                      .deleteRealmIfMigrationNeeded()
                      .build();
              realm = Realm.getInstance(config);
      
          } catch (Exception e) {
      
              Log.d("Error Line Number", Log.getStackTraceString(e));
          }
      }
      
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
          //Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
          Log.d("SERVICE","SERVICE CHECKING");
          result=intent.getStringExtra("toastMessage");
          Log.d("SERVICE",result);
          if (realm!=null){
              Log.d("SERVICE","realm working");
          }else {
              Log.d("SERVICE","Realm not working");
          }
          blockList=realm.where(BlockList.class).equalTo("package_name", "BLOCK_ALL").findFirst();
          try {
              Log.d("SERVICE",blockList.getStatus());
          } catch (Exception e) {
              Log.d("Error Line Number", Log.getStackTraceString(e));
          }
          realm.beginTransaction();
          if (result.equals("1")){
              if (blockList==null){
                  BlockList blockList_new=realm.createObject(BlockList.class);
                  blockList_new.setPackage_name("BLOCK_ALL");
                  blockList_new.setStatus("yes");
              }else {
                  blockList.setStatus("yes");
              }
              Log.d("SERVICE","BLOCKING NOTIFICATION");
              Toast.makeText(this, "BLOCKING", Toast.LENGTH_SHORT).show();
          }else if (result.equals("0")){
              if (blockList==null){
                  BlockList blockList_new=realm.createObject(BlockList.class);
                  blockList_new.setPackage_name("BLOCK_ALL");
                  blockList_new.setStatus("no");
              }else {
                  blockList.setStatus("no");
              }
              Log.d("SERVICE","ALLOW NOTIFICATION");
              Toast.makeText(this, "ALLOW NOTIFICATION", Toast.LENGTH_SHORT).show();
          }else if (result.equals("close")){
              NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
              manager.cancel(11);
              Log.d("SERVICE","REMOVING");
              Toast.makeText(this, "CLOSED", Toast.LENGTH_SHORT).show();
          }
          realm.commitTransaction();
          return START_STICKY;
      }
      
      @Override
      public IBinder onBind(Intent intent) {
          // We don't provide binding, so return null
          return null;
      }
      
      @Override
      public void onDestroy() {
          if (realm!=null){
              realm.close();
          }
          Toast.makeText(this, "REMOVING", Toast.LENGTH_SHORT).show();
      }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-07
        • 2015-11-22
        • 2016-08-18
        • 2017-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多