web-dev-qa-db-fra.com

Notification Android avec des boutons dessus

J'essaie de faire une notification avec 2 boutons dessus:

  • on me ramène à l'activité
  • l'autre ferme

Quelqu'un a-t-il une idée sur la façon de capturer l'événement de clic de bouton (rappelez-vous que l'activité est en pause)?

14
doronsl

Je suis content de le poster! Après avoir travaillé toute la nuit, j'ai trouvé quelque chose. Alors, on y va!

1. Créez un fichier de mise en page XML pour votre notification.

2. Créez la notification à l'aide de Notification.Builder. Après avoir ajouté tout ce que vous voulez (icônes, sons, etc.), procédez comme suit:

        //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. Créez une méthode setListeners. Dans cette méthode, vous devez écrire ceci:

    //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. Pour mes besoins, j'ai utilisé une HelperActivity qui répond aux intentions. Mais pour vous, je ne pense pas que ce soit nécessaire.

Si vous voulez le code source complet, vous pouvez le parcourir ou le télécharger depuis mon dépôt Git. Le code est destiné à un usage personnel, alors ne vous attendez pas à lire un code magnifique avec beaucoup de commentaires. https://github.com/BILLyTheLiTTle/AndroidProject_Shortcuts

TOUT CE QUI SUIT, RÉPOND À LA QUESTION DE L’ACQUISITION D’ÉVÉNEMENTS À PARTIR DE DIFFÉRENTS BOUTONS.

À propos de l'annulation de la notification, je vous redirige ici

Comment effacer une notification sous Android

N'oubliez pas d'utiliser l'identifiant que vous avez analysé selon la méthode notify lorsque vous avez appelé la notification pour la première fois.

41
LiTTle

Comme pour ICS, la question est simple à répondre car le comportement requis reflète la notification par défaut: vous pouvez close une notification en la balayant vers la droite, et vous pouvez définir quelle activité envoyer le message. utilisateur à quand il appuie simplement en utilisant 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);

code extrait de http://developer.Android.com/guide/topics/ui/notifiers/notifications.html

4
Shine

Vous pouvez simplement ajouter des boutons d'action dans votre Notification en définissant une action sur votre Notification.Builder et en définissant PendingIntent pour chaque action.

voici l'exemple de code: 

    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());
3
Tushar Purohit

Si vous souhaitez attribuer une intention spécifique à un bouton:

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

Je suppose que vous ne devez envoyer qu'une seule intention lorsque vous cliquez sur le bouton, vous devez donc ÉVITER de définir l'intention de notification principale.

notification.contentIntent = yourPendingIntent;

Sinon (si vous définissez "notification.contentIntent = waitingIntent;" comme d'habitude), les deux intentions seront appelées, ce qui pourrait ne pas correspondre à ce que vous souhaitez/l'utilisateur attend.

Si vous souhaitez toujours appuyer sur d'autres parties de la notification pour invoquer cette intention générale (ou toute autre), vous pouvez utiliser la même méthode d'attribution d'intention par vue que ci-dessus. N'oubliez pas de mettre

Android:clickable="true"

vers n'importe quelle vue pour laquelle vous souhaitez suivre onClick ().

Vous pouvez suivre ces intentions par leurs extras dans l'activité qu'ils appellent. Si vous êtes vous appelez l'activité principale/du lanceur que vous les suivez ici (car cela provient de javadoc pour cette méthode): 

@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
}
3
qubit

Il y a un exemple complet pour vous ici

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

et ensuite vous pouvez définir une méthode d'écoute: 

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

}

et voici la disposition notification_view pour personnaliser votre notification.

    <?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>
2
Amin

Pour moi, cela fonctionne beaucoup. Je vais écrire tout l'exemple. Ceci est pour Notification create

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);
}

Dans Android Menifest

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

Ceci est la classe de 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();
}
}
0
Muhaiminurabir