It's from this morning I'm struggling with this issue (at least for me it's an issue) My scenario is the following one: I built an Android background service who is listening on a MQTT topic. When this service receives a MQTT message, it creates a notification for the user. My service is able in listening and receivng the MQTT messages. What I'm not able in doing is to display my own notification layout and click on the notification in order to view the notification detail I'm using the following software versions:
- android:
- compilesdkversion: 21
- minSdkVersione: 16
- targetSdkVersion: 21
- MQTT Client: PAHO 1.0.2
In my service when I estabilish the connection with the mqttTopic I use my own implementation of interface org.eclipse.paho.client.mqttv3.MqttCallback
I pass to this interface the service instance who received the mqtt message. In the callback I want to create a notification by using my own layout This is the code I wrote:
Involved method (currentService is the service instance)
private void notifyUser(Allarme amp) {
RemoteViews remoteView = new RemoteViews(currentService.getPackageName(), R.layout.activity_visualizza_notifica);
Intent notificationIntent = new Intent(currentService, VisualizzaNotificaActivity.class);
notificationIntent.putExtra(IConstants.NOTIFICA_DATA, amp);
PendingIntent contentIntent = PendingIntent.getActivity(currentService, (int)System.currentTimeMillis(), notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(currentService);
builder.setSmallIcon(R.mipmap.warning);
builder.setWhen(System.currentTimeMillis());
builder.setOngoing(false);
builder.setAutoCancel(false);
builder.setTicker(currentService.getString(R.string.notifica_ticker));
builder.setContentIntent(contentIntent);
builder.setContent(remoteView);
builder.setDefaults(Notification.DEFAULT_VIBRATE);
builder.setDefaults(Notification.DEFAULT_SOUND);
remoteView.setTextViewText(R.id.data_notifica_text_id, DateUtil.formatMillisDate(amp.getDataNotifica()));
remoteView.setTextViewText(R.id.data_ricezione_notifica_text_id, DateUtil.formatMillisDate(amp.getDataRicezioneNotifica()));
TipoAllarme tmp = amp.getTipoAllarme();
if (tmp != null) {
String tipoNotifica = tmp.getCodiceAllarme() + " - " + tmp.getDescrizioneAllarme();
remoteView.setTextViewText(R.id.tipo_notifica_text_id, tipoNotifica);
}
remoteView.setTextViewText(R.id.descrizione_notifica_text_id, amp.getDescrizioneAllarme());
Notification notification = builder.build();
nm.notify(IConstants.MQTT_NEW_NOTIFICATION_ARRIVED, notification);
}
activity_visualizza_notifica.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_visualizza_notifica_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/data_notifica_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:text="Ciao dalla notifica"
android:layout_toLeftOf="@+id/data_ricezione_notifica_text_id"
android:layout_toStartOf="@+id/data_ricezione_notifica_text_id"
android:ems="10" />
<TextView
android:id="@+id/data_ricezione_notifica_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:ems="10" />
<TextView
android:id="@+id/tipo_notifica_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/descrizione_notifica_text_id"
android:ems="10" />
<TextView
android:id="@+id/descrizione_notifica_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/data_notifica_text_id"
android:ems="10" />
</RelativeLayout>
VisualizzaNotificaActivity.java
public class VisualizzaNotificaActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
View theView = findViewById(R.id.id_dettaglio_notifica);
Allarme amp = (Allarme) getIntent().getExtras().get(IConstants.NOTIFICA_DATA);
TextView dataNotifica = (TextView) findViewById(R.id.dettaglio_data_notifica_text_id);
dataNotifica.setText(DateUtil.formatMillisDate(amp.getDataAllarme()));
TextView dataRicezioneNotifica = (TextView) findViewById(R.id.dettaglio_data_ricezione_notifica_text_id);
dataRicezioneNotifica.setText(DateUtil.formatMillisDate(amp.getDataRicezioneAllarme()));
TextView descrizione = (TextView) findViewById(R.id.dettaglio_descrizione_notifica_text_id);
descrizione.setText(amp.getDescrizioneAllarme());
TipoAllarmeMercePericolosa tamp = amp.getTipoAllarme();
if (tamp != null) {
TextView tipoAllarme = (TextView) findViewById(R.id.dettaglio_tipo_notifica_text_id);
tipoAllarme.setText(tamp.getCodiceAllarme() + " - " + tamp.getDescrizioneAllarme());
}
setContentView(theView);
super.onCreate(savedInstanceState);
}
}
dettaglio_notifica.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/id_dettaglio_notifica"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/dettaglio_data_notifica_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:text="Ciao dalla notifica"
android:layout_toLeftOf="@+id/dettaglio_data_ricezione_notifica_text_id"
android:layout_toStartOf="@+id/dettaglio_data_ricezione_notifica_text_id"
android:ems="10" />
<TextView
android:id="@+id/dettaglio_data_ricezione_notifica_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:ems="10" />
<TextView
android:id="@+id/dettaglio_tipo_notifica_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/dettaglio_descrizione_notifica_text_id"
android:ems="10" />
<TextView
android:id="@+id/dettaglio_descrizione_notifica_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/dettaglio_data_notifica_text_id"
android:ems="10" />
</RelativeLayout>
By executing this code, I'm able in generating the notification but:
my own notification layout is not shown; I see a fully blank notification
when i click on the notification, the VisualizzaNotificaActivity is called but in onCreate method when I call
View theView = findViewById(R.id.id_dettaglio_notifica);
it always return null
Maybe I'm missing something... but I can't find what I'm missing.... How can I show my own notification layout when I receive the mqtt message? And do I get that null in my VisualizzaNotificaActivity?
Thank you Angelo
EDIT: CHANGED IMPLEMENTATION BY USING BroadcastReceiver
I changed my service implementation by using a BroadcasterReceiver Basically I wrote this receiver:
public class AllarmiMerciPericoloseReceiver extends BroadcastReceiver {
private static final String TAG_LOG = AllarmiMerciPericoloseReceiver.class.getSimpleName();
public AllarmiMerciPericoloseReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
try
{
if( intent.getAction().equals(IConstants.MQTT_MSG_RECEIVED_MSG) )
{
AllarmeMerciPericolose amp = (AllarmeMerciPericolose)intent.getExtras().get(IConstants.NOTIFICA_DATA);
notifyUser(amp, context);
}
}
catch (Exception e)
{
Log.e(TAG_LOG, "Errore nel receiver per le notifiche "+e.getMessage(), e);
}
}
private void notifyUser(AllarmeMerciPericolose amp, Context context) {
//Preparo la view per le notifiche; si deve utilizzare una RemoteView
RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.activity_visualizza_notifica);
//Indico l'activity da richiamare quando clicco sulla notifica
Intent notificationIntent = new Intent(context, VisualizzaNotificaActivity.class);
//notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//Passo i parametri che l'activity dovrà gestire al suo interno
notificationIntent.putExtra(IConstants.NOTIFICA_DATA, amp);
//Apro l'activity indicata in precedenza
PendingIntent contentIntent = PendingIntent.getActivity(context, (int) System.currentTimeMillis(), notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_CANCEL_CURRENT);
//Preparo il costruttore della notifica
Notification.Builder builder = new Notification.Builder(context);
//Inserisco l'icona della notifica
builder.setSmallIcon(R.mipmap.warning);
//Indico quando è creata la notifica
builder.setWhen(System.currentTimeMillis());
//Indico se continua; nel nostro caso non lo è perché non riguarda un processo di background e l'utente può decidere di
//dismettere la notifica stessa
builder.setOngoing(false);
//Dismettiamo la notifica
builder.setAutoCancel(false);
builder.setTicker(context.getString(R.string.notifica_ticker));
builder.setContentIntent(contentIntent);
builder.setContent(remoteView);
builder.setDefaults(Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND);
//builder.setDefaults(Notification.DEFAULT_SOUND);
//Valorizzo i campi della notifica
remoteView.setTextViewText(R.id.data_notifica_text_id, DateUtil.formatMillisDate(amp.getDataAllarme()));
remoteView.setTextViewText(R.id.data_ricezione_notifica_text_id, DateUtil.formatMillisDate(amp.getDataRicezioneAllarme()));
TipoAllarmeMercePericolosa tmp = amp.getTipoAllarme();
if (tmp != null) {
String tipoNotifica = tmp.getCodiceAllarme() + " - " + tmp.getDescrizioneAllarme();
remoteView.setTextViewText(R.id.tipo_notifica_text_id, tipoNotifica);
}
remoteView.setTextViewText(R.id.descrizione_notifica_text_id, amp.getDescrizioneAllarme());
Notification notification = builder.build();
NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(IConstants.MQTT_NEW_NOTIFICATION_ARRIVED, notification);
}
}
In my callback implementation i send a broadcast in this way:
private void propagateBroadcastAction( AllarmeMerciPericolose amp )
{
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(IConstants.MQTT_MSG_RECEIVED_MSG);
broadcastIntent.putExtra(IConstants.NOTIFICA_DATA, amp);
currentService.sendBroadcast(broadcastIntent);
}
But my custom notification is not shown; I attach what is showed as notification to the user (in my emulator)
As you can see, the notification is created but the layout is empty.... Any idea on what I'm missing?
Thank you
Angelo