NotificationCompat.Builder操作无效

时间:2018-04-11 07:42:50

标签: android-notifications notification-action

我试图在action中添加foreground service notification。但是动作点击永远不会被解雇pending intent。我尝试了两种方法。

第一种方法

服务

Intent stopActionIntent = new Intent(STOP_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MyService.this, 0, stopActionIntent,0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.addAction(0,"stop",pendingIntent);

清单

<receiver android:name="com.myproject.receivers.ServiceActionReceiver">
    <intent-filter >
        <action android:name="com.myproject.services.myservice.STOP_SERVICE"/>
    </intent-filter>
</receiver>

广播接收器

@Override
public void onReceive(Context context, Intent intent) {
    if(intent != null && intent.getAction().equals(MyService.STOP_SERVICE)){
        context.stopService(new Intent(context,MyService.class));
    }
}

但广播接收器从未打过电话。

第二种方法

服务

if(intent != null && STOP_SERVICE.equals(intent.getAction())){
    stopSelf();
    return  super.onStartCommand(intent,flags,startId);
}
else {
    Intent stopActionIntent = new Intent(this,MyService.class);
    stopActionIntent.setAction(STOP_SERVICE);
    PendingIntent pendingIntent = PendingIntent.getActivity(MyService.this, 0, stopActionIntent,0);
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
    builder.addAction(0,"stop",pendingIntent);
}

这两种方法都没有奏效。

的build.gradle

defaultConfig {
    applicationId "com.myproject.project"
    minSdkVersion 16
    targetSdkVersion 27
    versionCode 2
    versionName "1.0.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    multiDexEnabled true
}

注意:可以看到通知和操作。

修改

不适用于Android 8.0或更高版本,其他版本可以使用。

3 个答案:

答案 0 :(得分:0)

请尝试以下代码进行通知:

public void heads_up_notification() {
    Notification.Builder mBuilder = new Notification.Builder(this);
    NotificationManager nNotificationManager = (NotificationManager) getSystemService("notification");
    PendingIntent piDismiss = PendingIntent.getActivity(this, 0, new Intent(this, DirectReplyActivity.class), 0);
    Intent snoozeIntent = new Intent(this, MainActivity.class);
    snoozeIntent.setAction(NotificationCompat.CATEGORY_ALARM);
    PendingIntent piSnooze = PendingIntent.getService(this, 0, snoozeIntent, 0);
    mBuilder.setSmallIcon(C0220R.drawable.ic_launcher_background);
    mBuilder.setContentTitle("Heads up Notification");
    mBuilder.setContentText("heads up activated");
    mBuilder.setDefaults(-1);
    mBuilder.setPriority(1);
    mBuilder.addAction(C0220R.mipmap.ic_dismiss, "Dismiss", piDismiss);
    mBuilder.addAction(C0220R.mipmap.ic_stop, "Stop", piSnooze);
    nNotificationManager.notify(2, mBuilder.build());
}

答案 1 :(得分:0)

在Android O中,必须在Notification Builder中使用频道。

示例代码:

// Sets an ID for the notification, so it can be updated
int notifyID = 1; 
String CHANNEL_`enter code here`ID = "my_channel_01";// The id of the channel. 
CharSequence name = getString(R.string.channel_name);// The user-visible name of the channel.
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
// Create a notifi`enter code here`cation and set the notification channel.
Notification notification = new Notification.Builder(MainActivity.this)
        .setContentTitle("New Message")
        .setContentText("You've received new messages.")
        .setSmallIcon(R.drawable.ic_notify_status)
        .setChannelId(CHANNEL_ID)
        .build();

答案 2 :(得分:0)

@Shantanu, 你有很多问题。我建议您应该创建另一个新的示例项目,以使您的概念清晰,一旦清除,就可以在现有项目中使用它。您有多个问题,让我们一一解决 -

  1. 让接收者捕捉特定事件
  2. 来自Receiver启动服务(前台服务)
  3. 从服务中,创建通知
  4. 在开始之前,您必须拥有一个具有主动性和主要活动布局的新示例项目。

    Manifest.xml:此文件必须具有我们在应用中所需的权限。我发布了一个示例文件,我正在处理多个权限,特别是我正在调用接收器。我希望我的接收器处于唤醒状态,并在每次拨出和接听或未接来电时接听。

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    
    <uses-permission android:name="android.permission.VIBRATE" />
    
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.WRITE_SMS" />
    
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
    
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    
        <service
            android:name=".WatchMan"
            android:enabled="true"
            android:exported="true" />
    
        <receiver
            android:name=".Receiver"
            android:enabled="true"
            android:exported="true">
    
            <intent-filter>
                <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>
        </receiver>
    
        <activity android:name=".developer_activity" />
        <activity android:name=".WhiteListActivity" />
        <activity android:name=".Contacts"></activity>
    </application>
    

    请勿按原样复制上述文件,只需查看权限的放置位置和方式。如果您复制整个文件,它将无法正常工作。只需将您的权限置于application标记之上即可。多数民众赞成。

    现在从&gt;创建服务你的项目浏览器,在android studio / eclipse中。右键单击它 - &gt;选择new - &gt;选择service - &gt; service它将为您打开对话框并为您的服务指定适当的名称。

    它将为您创建一个服务类,并且还将为您修改manifest.xml。您无需编辑 的manifest.xml 您可以查看我上面的清单文件service标记。当我创建这样的服务时,它会自动为我创建。

    现在如何在android系统中触发时创建用于捕获特定事件的接收器:

    再次goto项目资源管理器 - &gt;右键单击 - &gt; new - &gt; other - &gt; broadcast receiver。它还会为您打开一个对话框并为您的接收器命名。 您再次无需手动修改清单文件。这将自动修改manifest.xml。您可以再次参考上面的清单文件。 并查看服务,并为我创建接收器..

    现在如何在新呼叫开始时调用该接收器..看看我如何放置

    <intent-filter>
        <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.PHONE_STATE" />
    </intent-filter>
    

    在接收器标签内;这意味着我的接收器将始终被调用这两个事件。

    现在Receiver.java:

    在接收器的onReceive功能中

    Log.d("RECEIVER ","\SUCCESS : ");
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
    {
        context.startForegroundService(new Intent(context, WatchMan.class));
    }
    else
    {
        context.startService(new Intent(context, WatchMan.class));
    }
    

    再次在这里..你不需要在这里手工编写代码。您可以通过右键单击扩展类BroadcastReceiver - &gt;来创建示例重写函数。 generate - override methods并选择onReceive。它将为您创建onReceive示例方法。您必须在其中插入以上代码如何调用您的服务(前台服务)

    现在服务:

    转到服务类。右键单击扩展类service - &gt; generate - &gt; override methods以及您需要的任何方法。 必须有空服务方法,oncreate,onStartCommand,onDestroy,onBind。您可以使用相同的上述创建方法再次创建样本标准方法。

    现在通知:

    服务类声明:

    NotificationManager mNotifyManager;
    NotificationCompat.Builder mBuilder;
    NotificationChannel notificationChannel;
    String NOTIFICATION_CHANNEL_ID = "2";
    
    在OnCreate方法中:

    try
        {
    
            Intent intent = new Intent(this, MainActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
    
            mNotifyManager = (NotificationManager) getApplicationContext().getSystemService(NOTIFICATION_SERVICE);
            mBuilder = new NotificationCompat.Builder(this, null);
            mBuilder.setContentTitle("App name")
                    .setContentText("Notification text..")
                    .setTicker("Notification text..")
                    .setSmallIcon(R.drawable.ic_service_success)
                    .setPriority(Notification.PRIORITY_HIGH)
                    .setDefaults(Notification.DEFAULT_ALL)
                    .setVisibility(Notification.VISIBILITY_PUBLIC)
                    .setContentIntent(pendingIntent);
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            {
    
                notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_HIGH);
    
                // Configure the notification channel.
                notificationChannel.setDescription("Channel description");
                notificationChannel.enableLights(true);
                notificationChannel.setLightColor(Color.RED);
                notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
                notificationChannel.enableVibration(true);
                notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
                mNotifyManager.createNotificationChannel(notificationChannel);
            }
    
            mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
            startForeground(2, mBuilder.build());
    
    
        }
        catch(Exception e)
        {
            Log.d("xx", "EXCEPTION IN SHOWING NOTIFICATION...\n");
            Log.e("xx", "Exception is : ", e);
        }
    

    现在,由于调用启动前景,它将开始运行您的Onstartcommand方法

    在onstartcommand中你的逻辑和代码就在那里......你是否应该实现runnable thread。这是可选的。

    您可以再次显示其他通知:

    mBuilder.setContentText("Some success or failure...");
    mBuilder.setTicker("Some success or failure...");
    mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
    startForeground(2, mBuilder.build());
    

    多数民众赞成。它应该做你想要的所有......权限,事件,接收器,服务(前台)和超过4.0到8.0的通知设备几乎99.8%的设备。