【问题标题】:Event OnClick for a button in a custom notification自定义通知中按钮的事件 OnClick
【发布时间】:2011-03-29 21:29:02
【问题描述】:

我有一个带有按钮的自定义通知。要设置通知并在我的按钮上使用事件 OnClick,我使用了以下代码:

//Notification and intent of the notification 
Notification notification = new Notification(R.drawable.stat_notify_missed_call,
            "Custom Notification", System.currentTimeMillis());

Intent mainIntent = new Intent(getBaseContext(), NotificationActivity.class);
PendingIntent pendingMainIntent = PendingIntent.getActivity(getBaseContext(),
    0, mainIntent , 0);
notification.contentIntent = pendingMainIntent;

//Remoteview and intent for my button
RemoteViews notificationView = new RemoteViews(getBaseContext().getPackageName(),
    R.layout.remote_view_layout);

Intent activityIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:190"));
PendingIntent pendingLaunchIntent = PendingIntent.getActivity(getBaseContext(), 0,
            activityIntent, PendingIntent.FLAG_UPDATE_CURRENT);

notificationView.setOnClickPendingIntent(R.id.button1,
    pendingLaunchIntent);

notification.contentView = notificationView;

notificationManager.notify(CUSTOM_NOTIFICATION_ID, notification);

使用此代码,我有一个带有自定义布局的自定义通知...但我无法单击按钮!每次我尝试单击按钮时,我都会单击整个通知,因此脚本会启动“mainIntent”而不是“activityIntent”。

我在互联网上读到此代码不适用于所有终端。我已经在模拟器和 HTC Magic 上尝试过,但我总是遇到同样的问题:我无法点击按钮!

我的代码是对的吗?有人可以帮助我吗?

谢谢,

西蒙娜

【问题讨论】:

  • 即我需要在我的“androidmanifest.xml”中添加一些特殊的东西来使用远程视图中的按钮?
  • 这可能会帮助你做到这一点这里是a link

标签: android button notifications onclick


【解决方案1】:

我正在我的 MyActivity.java 类中编写代码,该类扩展了 android.app.Activity

它创建一个自定义通知,当用户单击按钮时它会发送一个broadcast。 有一个广播接收器接收broadcast

private void createDownloadNotification() {
        Intent closeButton = new Intent("Download_Cancelled");
        closeButton.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

        PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(this, 0, closeButton, 0);

        RemoteViews notificationView = new RemoteViews(getPackageName(), R.layout.widget_update_notification);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_launcher).setTicker("Ticker Text").setContent(notificationView);
        notificationView.setProgressBar(R.id.pb_progress, 100, 12, false);
        notificationView.setOnClickPendingIntent(R.id.btn_close, pendingSwitchIntent);

        notificationManager.notify(1, builder.build());

    }


public static class DownloadCancelReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {

            System.out.println("Received Cancelled Event");
        }
    }

AndroidManifest.xml注册接收者

<receiver android:name=".MainActivity$DownloadCancelReceiver" android:exported="false">
            <intent-filter>
                <action android:name="Download_Cancelled" />
            </intent-filter>
        </receiver>

由于是内部类所以必须使用$ 符号

小部件 xml 在这里

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="horizontal" >

    <Button
        android:id="@+id/btn_close"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Close Me" />

    <ProgressBar
        android:id="@+id/pb_progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

【讨论】:

  • 仅仅为了这个目的而拥有一个public static 类会打开太多的访问权限。这个类不能不是静态的吗?
  • 它是一个内部类,所以我将其设为静态。你总是可以选择不同的方法。
【解决方案2】:

看看这个

  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");
    
    //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

【讨论】:

  • 如果我不想在按钮点击时启动活动我只想执行简单的操作,比如播放/暂停歌曲。
  • 好一个。您还应该提到,当意图有额外内容时,应该使用 PendingIntent.FLAG_UPDATE_CURRENT。我认为在解释的第一行就 requestCode 增量说一下会很好。谢谢!
  • 你只是复制粘贴,应该给他点赞stackoverflow.com/a/10959343/8678995
【解决方案3】:

似乎 setOnClickPendingIntent 在集合中使用时不起作用。

所以尝试 setPendingIntentTemplate 而不是 setOnClickPendingIntent。欲了解更多信息,请点击 android 开发者链接...

Click here for More Detail - Goto Android Developer Site.

【讨论】:

    【解决方案4】:

    您需要创建服务来检测点击事件:例如创建NotificationIntentService.class并输入以下代码:

    public class NotificationIntentService extends IntentService {
    
        /**
         * Creates an IntentService.  Invoked by your subclass's constructor.
         */
        public NotificationIntentService() {
            super("notificationIntentService");
        }
    
        @Override
        protected void onHandleIntent(Intent intent) {
            switch (intent.getAction()) {
                case "left":
                    android.os.Handler leftHandler = new android.os.Handler(Looper.getMainLooper());
                    leftHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getBaseContext(),
                                    "You clicked the left button", Toast.LENGTH_LONG).show();
                        }
                    });
                    break;
                case "right":
                    android.os.Handler rightHandler = new android.os.Handler(Looper.getMainLooper());
                    rightHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getBaseContext(), "You clicked the right button", Toast.LENGTH_LONG).show();
                        }
                    });
                    break;
            }
        }
    }
    

    将此方法添加到您的活动中:

    private void sendNotification() {
    
        RemoteViews expandedView = new RemoteViews(getPackageName(), R.layout.view_expanded_notification);
        expandedView.setTextViewText(R.id.timestamp, DateUtils.formatDateTime(this, System.currentTimeMillis(), DateUtils.FORMAT_SHOW_TIME));
        expandedView.setTextViewText(R.id.notification_message, mEditText.getText());
        // adding action to left button
        Intent leftIntent = new Intent(this, NotificationIntentService.class);
        leftIntent.setAction("left");
        expandedView.setOnClickPendingIntent(R.id.left_button, PendingIntent.getService(this, 0, leftIntent, PendingIntent.FLAG_UPDATE_CURRENT));
        // adding action to right button
        Intent rightIntent = new Intent(this, NotificationIntentService.class);
        rightIntent.setAction("right");
        expandedView.setOnClickPendingIntent(R.id.right_button, PendingIntent.getService(this, 1, rightIntent, PendingIntent.FLAG_UPDATE_CURRENT));
    
        RemoteViews collapsedView = new RemoteViews(getPackageName(), R.layout.view_collapsed_notification);
        collapsedView.setTextViewText(R.id.timestamp, DateUtils.formatDateTime(this, System.currentTimeMillis(), DateUtils.FORMAT_SHOW_TIME));
    
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                // these are the three things a NotificationCompat.Builder object requires at a minimum
                .setSmallIcon(R.drawable.ic_pawprint)
                .setContentTitle(NOTIFICATION_TITLE)
                .setContentText(CONTENT_TEXT)
                // notification will be dismissed when tapped
                .setAutoCancel(true)
                // tapping notification will open MainActivity
                .setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0))
                // setting the custom collapsed and expanded views
                .setCustomContentView(collapsedView)
                .setCustomBigContentView(expandedView)
                // setting style to DecoratedCustomViewStyle() is necessary for custom views to display
                .setStyle(new android.support.v7.app.NotificationCompat.DecoratedCustomViewStyle());
    
        // retrieves android.app.NotificationManager
        NotificationManager notificationManager = (android.app.NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        notificationManager.notify(0, builder.build());
    }
    

    【讨论】:

      【解决方案5】:

      似乎 setOnClickPendingIntent 在集合内使用时不起作用:

      http://developer.android.com/reference/android/widget/RemoteViews.html#setOnClickPendingIntent(int,%20android.app.PendingIntent)

      尝试改用 setPendingIntentTemplate。

      【讨论】:

      • 错误除外 setPendingIntentTemplate 用于蜂窝(android 3.0),而我正在使用 Froyo(Android 2.2)。所以我不能在 Froyo 的通知中使用按钮?
      • 反正可能迟到了,但就是这样。按钮通知在 Gingerbread 中也不起作用,而在 Honeycomb 上,您上面的代码也应该起作用。至少在我的应用中有类似的代码。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-14
      • 1970-01-01
      • 1970-01-01
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多