V
V
verbo2016-03-13 16:36:34
Android
verbo, 2016-03-13 16:36:34

It is necessary to catch button presses in Notification. Where is the mistake?

There is a service that launches notifications with two buttons: more and close. It is necessary to catch button presses and notifications. Currently implemented via BroadcastReceiver, but it only takes a value on the first passed intent. As a result, only the message "more" is displayed.
MainService.class

public class MainService extends Service{
    private NotificationManager nm;
    private final int NOTIFICATION_ID = 123;
    public String ACTION = "action_notif_ganesha";
    public final static String BROADCAST_ACTION = "com.ganesha.ganesha_v1m.ganeshaservice";
    BroadcastReceiver br;

    @Override
    public void onCreate() {
        super.onCreate();
        registerReceiver();
        nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        sendNotif("Very very very big text! Very very very big text! Very very very big text!");
        return super.onStartCommand(intent, flags, startId);
    }

    void sendNotif(String str_mess) {
        Log.i("Ganesha", "Service - sendNotif");

        Intent iMore = new Intent(MainService.BROADCAST_ACTION);
        iMore.putExtra(ACTION, "more");
        PendingIntent piMore = PendingIntent.getBroadcast(this, 0, iMore, 0);

        Intent iClose = new Intent(MainService.BROADCAST_ACTION);
        iClose.putExtra(ACTION, "close");
        PendingIntent piClose = PendingIntent.getBroadcast(this, 0, iClose, 0);

        Notification notif = new Notification.Builder(this)
                //.setContentIntent(piMore)
                //.setAutoCancel(true)
                .setTicker("Title 1")
                .setContentTitle("Title 2")
                .setContentText("")
                .setSmallIcon(R.mipmap.icon)
                .setLargeIcon(BitmapFactory.decodeResource(getApplication().getResources(), R.mipmap.icon))
                .setStyle(new Notification.BigTextStyle().bigText(str_mess))
                .addAction(R.drawable.close, "Подробнее", piMore)
                .addAction(R.drawable.close, "Закрыть", piClose)
                .setPriority(Notification.PRIORITY_MAX)
                .build();
        notif.ledARGB = 0xffffff00;
        notif.flags |= Notification.FLAG_SHOW_LIGHTS;
        notif.defaults = Notification.DEFAULT_VIBRATE;

        nm.notify(NOTIFICATION_ID, notif);
    }

    //ловим нажатие на уведомлении
    void registerReceiver(){
        br = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String code = intent.getStringExtra(ACTION);
                Log.i("Ganesha","action: "+code);
                Toast.makeText(getApplicationContext(), code, Toast.LENGTH_SHORT).show();
            }
        };

        IntentFilter filter = new IntentFilter(BROADCAST_ACTION);
        registerReceiver(br, filter);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("Ganesha", "Service - onDestroy");
        nm.cancel(NOTIFICATION_ID);
        unregisterReceiver(br);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

}

AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ganesha.ganesha_v1m">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/icon"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".activity.MainActivity" android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <activity android:name=".activity.MoreActivity"/>

        <service
            android:name=".service.MainService"
            android:enabled="true"
            android:exported="true"
            android:process=":ganeshaservice">
            <intent-filter>
                <action android:name="com.ganesha.ganesha_v1m.ganeshaservice"/>
            </intent-filter>
        </service>
    </application>
</manifest>

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
stilroof, 2016-03-14
@stilroof

You have the same request codes for PendingIntent. When creating a PendingIntent, the system looks to see if there is a similar Intent created earlier or not. If there is, use it. In your case, both Intents are the same (iMore and iClose). More precisely, intents differ in extra-data, but they are not taken into account when comparing. Therefore, when creating piClose, the iMore intent is taken, and not iClose.
How to fix: use different request codes in PendingIntent. For example, like this:

Intent iMore = new Intent(MainService.BROADCAST_ACTION);
        iMore.putExtra(ACTION, "more");
        PendingIntent piMore = PendingIntent.getBroadcast(this, 1, iMore, 0);

        Intent iClose = new Intent(MainService.BROADCAST_ACTION);
        iClose.putExtra(ACTION, "close");
        PendingIntent piClose = PendingIntent.getBroadcast(this, 2, iClose, 0);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question