0

我正在尝试添加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);
}

两种方法都行不通。

构建.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 或更高版本,其他版本有效。

4

3 回答 3

1

在 Android O 中,必须将通道与通知生成器一起使用。

示例代码:

// 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();
于 2018-04-13T06:55:51.043 回答
0

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

  1. 让 Receiver 捕捉特定事件
  2. 从 Receiver 启动一个服务(前台服务)
  3. 从服务,创建通知

在开始之前,您必须有一个带有 mainactivity 和 mainactivity 布局的新示例项目。

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标签上方。而已。

现在从->您的项目资源管理器中创建一个服务,在android studio / eclipse中。右键单击它->选择new->选择service->service它将为您打开对话框并为您的服务提供适当的名称。

它将为您创建一个服务类,并为您修改 manifest.xml。你不需要为此编辑你的 manifest.xml 你看看我上面的清单文件service标签。当我创建这样的服务时,它会自动为我创建。


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

为此,再次转到项目资源管理器 -> 右键单击​​ -> new-> other-> 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-> generate-override methods并选择来创建示例覆盖函数onReceive。它将为您创建 onReceive 示例方法。您必须在其中插入上述代码如何调用您的服务(前台服务)


现在服务:

转到服务类。右键单击扩展类service-> generate->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 androids 设备近 99.8% 的设备。

于 2018-04-14T06:35:25.690 回答
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());
}
于 2018-04-13T06:45:33.953 回答