A partir do nível 26 da API do Android, as notificações persistentes são necessárias para serviços em primeiro plano. Esse requisito visa impedir que você se esconda serviços que possam exigir excessivamente os recursos do sistema, incluindo bateria em particular. Esse requisito cria um possível problema: se um app em vários serviços em primeiro plano não gerencia a notificação que sejam compartilhados entre todos os serviços, poderá haver várias notificações não dispensáveis, levando a uma desordem indesejada na lista ativa de notificações.
Esse problema se torna mais desafiador quando você usa SDKs como o Navigation
do SDK, que executam serviços em primeiro plano independentemente do app que tenham os
próprias notificações persistentes independentes, o que dificulta a consolidação delas.
Para resolver esses problemas, o SDK do Navigation v1.11 introduziu uma API simples para
ajudam a gerenciar notificações persistentes em todo o app, inclusive no SDK.
Componentes
O gerenciador de serviços em primeiro plano fornece um wrapper ao redor do primeiro plano do Android classe de serviço e de notificação persistente. O principal deste wrapper é aplicar a reutilização do ID de notificação para que a notificação seja compartilhada entre todos os serviços em primeiro plano que usam o gerenciador.
O SDK do Navigation contém métodos estáticos para inicializar e receber a
Singleton de ForegroundServiceManager
. Este Singleton só pode ser inicializado
uma vez durante a vida útil do SDK do Navigation. Consequentemente, se você usar um dos
chamadas de inicialização (initForegroundServiceManagerMessageAndIntent()
ou
initForegroundServiceManagerProvider()
), deverá cercar
com um bloco try-catch caso esse caminho seja inserido novamente. O SDK do Navigation
gera uma exceção de tempo de execução se você chamar um dos métodos mais de uma vez, a menos que você
primeiro, apague todas as referências ao ForegroundServiceManager
e chame
clearForegroundServiceManager()
antes de cada chamada seguinte.
Os quatro parâmetros de initForegroundServiceManagerMessageAndIntent()
são
application
, notificationId
, defaultMessage
e resumeIntent
. Se o
três parâmetros finais forem nulos, a notificação será o padrão
Notificação do SDK do Navigation. Ainda é possível ocultar outras imagens em primeiro plano
serviços no aplicativo por trás dessa notificação. O parâmetro notificationId
especifica o ID que deve ser usado para a notificação. Se for
nulo, um valor arbitrário será usado. É possível defini-lo explicitamente para contornar
entrar em conflito com outras notificações, como as de outro SDK. O
defaultMessage
é uma string que aparece quando o sistema não está
navegar. O resumeIntent
é uma intent acionada quando a notificação
é clicado. Se o resumeIntent
for nulo, vai clicar na notificação
são ignorados.
Os três parâmetros de initForegroundServiceManagerProvider()
são
application
, notificationId
e notificationProvider
. Se o resultado
dois parâmetros forem nulos, a notificação será o SDK do Navigation padrão
notificação. O parâmetro notificationId
especifica o ID da notificação que
deve ser usado para a notificação. Se for nulo, um valor arbitrário será
usados. Você pode defini-la explicitamente para solucionar conflitos com outros
notificações, como as de outro SDK. Se o notificationProvider
for
definido, o provedor é sempre responsável
gerando a notificação para que ela seja renderizada.
O método getForegroundServiceManager()
do SDK do Navigation retorna o
Singleton do gerenciador de serviços em primeiro plano. Se você ainda não tiver gerado uma,
ele é equivalente a chamar initForegroundServiceManagerMessageAndIntent()
com parâmetros nulos para notificationId
, defaultMessage
e
resumeIntent
.
O ForegroundServiceManager
tem três métodos simples. Os dois primeiros são para
movem um serviço para dentro e para fora do primeiro plano e costumam ser chamadas de
no serviço que foi criado. O uso desses métodos garante que os
e serviços do Google Cloud
sejam associados à notificação persistente compartilhada. O resultado
updateNotification()
, sinaliza ao gerenciador que a notificação
alterado e precisam ser renderizados novamente.
Se você precisar de controle total da notificação persistente compartilhada,
a API fornece uma interface NotificationContentProvider
para definir
provedor de notificação, que contém um único método para receber uma notificação
com o conteúdo atual. Ele também fornece uma classe base, que pode ser
podem usar para definir o provedor. Uma das funções principais
é que ele fornece uma maneira de chamar updateNotification()
sem o
precisa acessar ForegroundServiceManager
. Se você usar uma instância do
provedor de notificação para receber novas mensagens de notificação, você pode chamá-lo
método interno diretamente para renderizar a mensagem na notificação.
cenários de uso
Nesta seção, detalhamos os cenários de uso para utilização das permissões permanentes notificações.
- Ocultar notificações persistentes de outros serviços em primeiro plano do app
- O cenário mais fácil é preservar o comportamento atual e usar apenas o
notificação contínua para renderizar informações do SDK do Navigation. Outros serviços
pode ficar oculta por trás dessa notificação usando o gerenciador de serviços em primeiro plano
métodos
startForeground()
estopForeground()
. - Ocultar notificações persistentes de outros serviços em primeiro plano do app, mas definir texto padrão mostrado quando não está navegando
- O segundo cenário mais fácil é preservar o comportamento atual e usar apenas
a notificação persistente para renderizar informações do SDK de navegação, exceto
quando o sistema não está navegando. Quando o sistema não está navegando, o
string fornecida para
initForegroundServiceManagerMessageAndIntent()
é exibido em vez da string padrão do SDK de navegação que menciona "Google Maps". Você também pode usar essa chamada para definir a intent de currículo que é disparada quando a notificação é clicada. - Controle total da renderização da notificação persistente
- O cenário final exige a definição e a criação de um provedor de notificações
e passá-lo para o
ForegroundServiceManager
usandoinitForegroundServiceManagerProvider()
Essa opção oferece controle total sobre o que é renderizado na notificação, mas também desconecta as informações de notificação do SDK do Navigation do de modo automático, removendo assim as instruções passo a passo úteis mostradas na notificação. O Google não oferece uma maneira simples de recuperar esses dados e inserindo essas informações na notificação.
Exemplo de provedor de notificação
O exemplo de código a seguir demonstra como criar e retornar notificações usando um provedor de conteúdo de notificação simples.
public class NotificationContentProviderImpl
extends NotificationContentProviderBase
implements NotificationContentProvider {
private String channelId;
private Context context;
private String message;
/** Constructor */
public NotificationContentProviderImpl(Application application) {
super(application);
message = "-- uninitialized --";
channelId = null;
this.context = application;
}
/**
* Sets message to display in the notification. Calls updateNotification
* to display the message immediately.
*
* @param msg The message to display in the notification.
*/
public void setMessage(String msg) {
message = msg;
updateNotification();
}
/**
* Returns the notification as it should be rendered.
*/
@Override
public Notification getNotification() {
Notification notification;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
Spanned styledText = Html.fromHtml(message, FROM_HTML_MODE_LEGACY);
String channelId = getChannelId(context);
notification =
new Notification.Builder(context, channelId)
.setContentTitle("Notifications Demo")
.setStyle(new Notification.BigTextStyle()
.bigText(styledText))
.setSmallIcon(R.drawable.ic_navigation_white_24dp)
.setTicker("ticker text")
.build();
} else {
notification = new Notification.Builder(context)
.setContentTitle("Notification Demo")
.setContentText("testing non-O text")
.build();
}
return notification;
}
// Helper to set up a channel ID.
private String getChannelId(Context context) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
if (channelId == null) {
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(
"default", "navigation", NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("For navigation persistent notification.");
notificationManager.createNotificationChannel(channel);
channelId = channel.getId();
}
return channelId;
} else {
return "";
}
}
}
Depois de criar o NotificationContentProviderImpl
, conecte o
SDK do Navigation até ele usando o seguinte código:
ForegroundServiceManager f = NavigationApi.getForegroundServiceManager(getApplication());
mNotification = new NotificationContentProviderImpl(getApplication());
NavigationApi.clearForegroundServiceManager();
NavigationApi.initForegroundServiceManagerProvider(getApplication(), null, mNotification);
Advertências e planos futuros
- Ligue para
initForegroundServiceManagerMessageAndIntent()
ouinitForegroundServiceManagerProvider()
com antecedência para que o cenário de uso esperado esteja bem definido. É preciso chamar esse método antes de criar um novo navegador. - Certifique-se de capturar exceções de chamadas para
initForegroundServiceManagerMessageAndIntent()
ouinitForegroundServiceManagerProvider()
caso o caminho do código seja inserido mais de uma vez. No SDK do Navigation v2.0, chamar esse método várias vezes gera uma exceção verificada em vez de uma exceção de tempo de execução. - Talvez o Google ainda tenha trabalho a fazer para ter um estilo consistente vida útil da notificação que corresponde ao estilo do cabeçalho.
- Ao definir um provedor de notificações, é possível controlar o comportamento dos avisos com a prioridade.
- O Google não oferece um meio simples para recuperar a navegação guiada informações que um provedor de notificação pode inserir na notificação.