Ho scoperto che quando si utilizzano i pulsanti di azione nelle notifiche espanse, è necessario scrivere altro codice e tu sei più vincolato.
Prima di utilizzare le notifiche espanse, l'azione predefinita nella notifica di download del file era l'avvio di un'attività VISTA sul file. L'intento VIEW era racchiuso da un intento Chooser. Non è stato possibile utilizzare un intento in sospeso per l'intento di Scelta risorse direttamente dalla notifica, in quanto Chooser si arrestava in modo anomalo se non c'era attività per visualizzare il tipo di file. Quindi avevo un BroadcastReceiver che avviava l'intento di Scelta Risorse.
Con le notifiche espanse, ho deciso di modificare la notifica di download del file in modo che l'azione predefinita sia quella di mostrare l'attività sui dettagli del file, con pulsanti di azione per Visualizza e Invia. Come notato dall'utente2536953, l'avvio di un ricevitore di trasmissione dalla notifica non chiude il cassetto delle notifiche. Sulla base delle sue informazioni sul fatto che un'attività avrebbe chiuso il cassetto, ho cambiato il mio ricevitore di trasmissione in NotificationActivity senza alcuna interfaccia utente.
Come indicato in questo post How to dismiss Android notification after action has been clicked, un altro problema è che è necessario annullare manualmente la notifica quando l'utente fa clic su un pulsante di azione. La notifica viene annullata automaticamente solo per l'azione predefinita. Ho anche aggiunto il codice in NotificationActivity per gestirlo.
Costruire la notifica ampliata con vista e inviare pulsanti:
NotificationCompat.Builder builder = new NotificationCompat.Builder(m_context).setAutoCancel(true);
final PendingIntent contentIntent = DownloadedFileIntentUtils.buildPendingItemDetailIntent(m_context, item);
builder.setContentIntent(contentIntent);
PendingIntent viewIntent = DownloadedFileIntentUtils.buildNotificationActionIntent(m_context, Intent.ACTION_VIEW,
m_context.getString(R.string.action_open), uri, MimeTypeUtil.getMimeType(item), id);
builder.addAction(R.drawable.actionbar_open_with, m_context.getString(R.string.action_open), viewIntent);
PendingIntent sendIntent = DownloadedFileIntentUtils.buildNotificationActionIntent(m_context, Intent.ACTION_SEND,
m_context.getString(R.string.action_send), uri, MimeTypeUtil.getMimeType(item), id);
builder.addAction(R.drawable.actionbar_share, m_context.getString(R.string.action_send), sendIntent);
builder.setTicker(title)
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.notification_download);
.setStyle(new NotificationCompat.BigTextStyle().bigText(text));
getNotificationManager().notify(id, builder.build());
Costruire l'intento di avviare un'attività dai pulsanti di azione di notifica:
public static PendingIntent buildNotificationActionIntent(Context context, String action, String actionTitle, Uri uri,
String mimeType, int notificationId) {
// Build the file action intent (e.g. VIEW or SEND) that we eventually want to start.
final Intent fileIntent = buildFileActionIntent(action, actionTitle, uri, mimeType);
// Build the intent to start the NotificationActivity.
final Intent notificationIntent = new Intent(context, NotificationActivity.class);
// This flag must be set on activities started from a notification.
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Pass the file action and notification id to the NotificationActivity.
notificationIntent.putExtra(Intent.EXTRA_INTENT, fileIntent);
notificationIntent.putExtra(IIntentCode.INTENT_EXTRA_NOTIFICATION_ID, notificationId);
// Return a pending intent to pass to the notification manager.
return PendingIntent.getActivity(context, s_intentCode.getAndIncrement(), notificationIntent, PendingIntent.FLAG_ONE_SHOT);
}
public static Intent buildFileActionIntent(String action, String actionTitle,
Uri uri, String mimeType) {
Intent intent = new Intent(action);
intent.addCategory(Intent.CATEGORY_DEFAULT);
if (action.equals(Intent.ACTION_SEND)) {
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setType(mimeType);
} else {
intent.setDataAndType(uri, mimeType);
}
intent.putExtra(Intent.EXTRA_TITLE, actionTitle);
// Grant read permission on the file to other apps without declared permission.
int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION;
intent.setFlags(flags);
return intent;
}
attività di notifica, senza alcuna Interfaccia utente:
public class NotificationActivity extends Activity {
private final static Logger s_logger = LogUtil.getLogger(NotificationActivity.class);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
// Cancel the notification that initiated this activity.
// This is required when using the action buttons in expanded notifications.
// While the default action automatically closes the notification, the
// actions initiated by buttons do not.
int notificationId = intent.getIntExtra(IIntentCode.INTENT_EXTRA_NOTIFICATION_ID, -1);
if (notificationId != -1) {
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(notificationId);
}
// If there is an activity to handle the action, start the file action.
if (DownloadedFileIntentUtils.verifyActivityIsAvailable(this, fileActionIntent, false)) {
fileActionIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
DownloadedFileIntentUtils.startFileActionActivity(this, fileActionIntent);
}
// Finish activity.
finish();
}
public static void startFileActionActivity(Context context, Intent fileActionIntent) {
// Start chooser intent.
Intent chooser = Intent.createChooser(fileActionIntent, fileActionIntent.getStringExtra(Intent.EXTRA_TITLE));
// Copy the flags from fileActionIntent to chooser intent.
// FileActionExecutor must set FLAG_ACTIVITY_NEW_TASK on the intent passed to startActivity
// because the flag is required when starting an activity from a context that is not an activity.
chooser.addFlags(fileActionIntent.getFlags());
context.startActivity(chooser);
}
Non dimenticare di aggiungere NotificationActivity a AndroidManifest.xml.
Hai mai trovato una soluzione per questo? –
No. Solo alcuni hack per usare la reflection ed espandere, comprimi la Status bar. Apparentemente, se il tuo Pending Intent contiene un Intento che si risolve in un'attività, il cassetto viene automaticamente collassato. Tuttavia, se il tuo Pending Intent racchiude un BroadcastReceiver o un servizio, la barra delle notifiche mantiene il suo stato (espanso). – Aster