Meu aplicativo Android está sendo chamado por um intent que está passando informações (pendenteintent na barra de status).
Quando eu clico no botão home e reabra meu aplicativo segurando o botão home, ele chama a intenção novamente e os mesmos extras ainda estão lá.
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
este é o código que não funciona como deveria
String imgUrl;
Bundle extras = this.getIntent().getExtras();
if(extras != null){
imgUrl = extras.getString("imgUrl");
if( !imgUrl.equals(textView01.getText().toString()) ){
imageView.setImageDrawable( getImageFromUrl( imgUrl ) );
layout1.setVisibility(0);
textView01.setText(imgUrl);//textview to hold the url
}
}
E minha intenção:
public void showNotification(String ticker, String title, String message,
String imgUrl){
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(ns);
int icon = R.drawable.icon; // icon from resources
long when = System.currentTimeMillis(); // notification time
CharSequence tickerText = ticker; // ticker-text
//make intent
Intent notificationIntent = new Intent(this, activity.class);
notificationIntent.putExtra("imgUrl", imgUrl);
notificationIntent.setFlags(
PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_ONE_SHOT);
PendingIntent contentIntent =
PendingIntent.getActivity(this, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_ONE_SHOT);
//make notification
Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(this, title, message, contentIntent);
//flags
notification.flags = Notification.FLAG_SHOW_LIGHTS |
Notification.FLAG_ONGOING_EVENT |
Notification.FLAG_ONLY_ALERT_ONCE |
Notification.FLAG_AUTO_CANCEL;
//sounds
notification.defaults |= Notification.DEFAULT_SOUND;
//notify
mNotificationManager.notify(1, notification);
}
Existe alguma maneira de limpar o intent ou verificar se ele já foi usado antes?
android
android-intent
Marte
fonte
fonte
Respostas:
ATUALIZAR:
Eu não sabia que essa resposta seria muito referida quando a escrevi pela primeira vez, há mais de 5 anos!
Vou esclarecer para apontar que, de acordo com a resposta @ tato-rodrigo, isso não ajudará você a detectar uma intenção já tratada em algumas situações.
Além disso, devo apontar que coloquei "claro" entre aspas por um motivo - você não está realmente limpando a intenção ao fazer isso, você está apenas usando a remoção do extra como um sinalizador de que essa intenção já foi vista pela atividade .
Eu tive exatamente o mesmo problema.
A resposta acima me colocou no caminho certo e encontrei uma solução ainda mais simples, use o:
chamada de método para "limpar" o Intent.
É um pouco tarde para responder, já que isso foi perguntado há um ano, mas espero que isso ajude outras pessoas no futuro.
fonte
setIntent(new Intent())
e está funcionando bem agora.EDITAR: Estou editando para postar a solução completa que estou usando.
Esta solução funcionará se o problema for "Não executar algum código quando a atividade começar no histórico (aplicativos recentes)" .
Em primeiro lugar, declare um
boolean
em seuActivity
para indicar se oIntent
já foi consumido:Em seguida, armazene e restaure esse valor com segurança usando os métodos
onSaveInstanceState
eonCreate
para lidar com alterações de configuração e casos em que o sistema pode interromper o seuActivity
quando for para segundo plano.Agora, verifique se você pode executar seu código no
onResume
método.Além disso, se
Activity
estiver configurado parasingleTop
, você deve redefinir seu sinalizador quando um novoIntent
for entregue.fonte
(intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)
então agora posso descobrir quando o início da atividade é da história e posso ignorar meus extras.boolean shouldThisIntentTriggerMyCode = [...];
da resposta (para que é usado?)consumedIntent
comoString
contendo notificação UID. Este Uid pode ser simplesmente adicionado à notificação no back-end como carimbo de data / hora atual. Além disso, você deve salvar este UidonSaveInstanceState
apenas se o Intent estiver vindo de formaonCreate
. Isso significa que você não deve salvar o Uid deonNewIntent
.A resposta do Maks funciona para limpar um extra:
Outro comando útil é:
Você também pode marcar uma intent chamando:
e depois é só verificar o valor.
fonte
Quando lançamos aplicativos Android do History (Recent Apps), o aplicativo pode ser iniciado com três sinalizadores de Intent diferentes.
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
É quando a atividade está sendo iniciada a partir do histórico de um aplicativo que foi minimizado (pressione longamente a tecla home).
Valor constante: 1048576 (0x00100000)
FLAG_ACTIVITY_NEW_TASK
É quando a atividade é iniciada por meio de "clicar no ícone do aplicativo" ou por meio de " Filtros de intenção ". Aqui, a atividade se tornará o início de uma nova tarefa nesta pilha de histórico.
Valor constante: 268435456 (0x10000000)
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY | FLAG_ACTIVITY_NEW_TASK
Isso é quando o aplicativo foi encerrado pressionando o botão Voltar e, em seguida, reiniciado do Histórico (aplicativos recentes).
Valor constante: 269484032 (0x10100000)
O valor constante pode ser recuperado via
getIntent().getFlags()
No terceiro caso, o Android recarrega os últimos valores de Intent de sua memória. Portanto, a intenção do seu aplicativo (
getIntent
) do terá valores do último intent que iniciou o aplicativo.Na verdade, o aplicativo deve se comportar como se fosse um novo lançamento, com valores de intents para um novo lançamento, em vez dos valores de intent do lançamento anterior. Esse comportamento pode ser visto se você iniciar o aplicativo clicando no ícone do aplicativo, ele nunca terá valores de intenção antigos. Isso ocorre porque o Android usa o seguinte filtro de intent para este cenário
Mas, no terceiro caso (aplicativo que foi encerrado, é iniciado a partir do histórico de aplicativos recentes), o sistema operacional Android usa a última intenção que iniciou o aplicativo antes de ser encerrado (pressionando o botão Voltar). Então, você acaba tendo valores de intent antigos e o fluxo do aplicativo não é adequado.
Remover a intenção é uma maneira de resolver, mas não resolveria o problema completamente! À medida que o Android OS recarrega o intent do último lançamento do aplicativo, e não da última instância do intent de lançamento.
Uma maneira limpa de evitar que isso aconteça é lidar com isso obtendo o tipo de Intent para determinar o tipo de inicialização.
Assim, no seu LaunchActivity (aquele que tem o filtro de intenção definida no manifesto), você pode usar o seguinte código nos
onCreate()
,onStart()
ouonResume()
métodos.Presumo
normalLaunch()
que não deva usar parâmetros do Intent; caso contrário, você precisaria separar e otimizar seu método de inicialização padrão para não usar parâmetros de intent.fonte
getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
, não importa se eu iniciar a atividade de outra atividade (método startActivity) ou reabri-la a partir da pilha de histórico (aplicativos recentes).Limpando um objeto de intent :
fonte
A resposta curta é jeito nenhum
Resposta longa. Não existe essa coisa de intenção "one-shot". A partir da experiência, é observado que o histórico de atividades recentes em Androids modernos nada mais é do que "histórico de intenções". A última intenção passada à atividade é simplesmente registrada no sistema e esse é o negócio. O pessoal acima sugere o uso
Mas não funciona porque a intenção já está registrada até o momento em que você a coloca dentro do método onNewIntent () ou onStart ().
Resolvi o problema evitando o uso de intents. Meu problema era semelhante ao postado pelo autor. Tentei implementar a Saída Global do aplicativo via controle na área de notificação. Ele deve interromper o serviço subjacente e fechar todas as atividades do aplicativo. Você pode encontrar o mesmo comportamento no aplicativo Waze.
O algoritmo:
Espero que ajude alguém porque não encontrei a resposta na internet.
fonte
Certifique-se de que você está usando PendingIntent.FLAG_UPDATE_CURRENT bandeira para PendingIntent .
Onde
mPutIntent
está o seuIntent
.Espero que isso ajude você.
fonte
Recentemente, tive esse problema e o resolvi adicionando um carimbo de data / hora como um parâmetro extra ao intent:
Depois disso, salve o carimbo de data / hora nas preferências compartilhadas:
fonte
Eu tenho exatamente o mesmo problema. Minha solução foi adicionar a
boolean
variável que foi definida quandoIntent
foi 'usado' e umaif
instrução baseada nissoboolean
para verificar se você deveria usarIntent
ou não.fonte
Quando terminar de processar o Intent, faça o seguinte:
Você não verá aquele Intent processado novamente e não mascarará o problema editando o conteúdo do Intent processado.
fonte
Não consegui encontrar uma maneira de remover o Intent Extra . Nenhuma das respostas sobre a remoção de extras da intenção funciona se você ativar "Não manter atividades " nas Opções do desenvolvedor (dessa forma, você pode destruir a atividade e voltar para testar se os extras ainda estão lá).
Como solução para o problema, armazenei o valor booleano em SharedPreferences após o processamento dos Intent Extras. Quando o mesmo Intent é reenviado para a Activity, eu verifico o valor SharedPreference e decido processar o Intent Extra. Caso você envie outro novo Intent Extra para a mesma Activity, você torna o valor SharedPreference falso e Activity irá processá-lo. Exemplo :
fonte
Mesmo depois de limpar manualmente os extras de Intent e Intent depois de terem sido analisados, parece que Activity.getIntent () sempre retornará o Intent original que iniciou a Activity.
Para contornar isso, recomendo algo assim:
Dessa forma, há um mecanismo para descartar o Intent original enquanto ainda retém a capacidade de reter explicitamente certas partes dos extras do Intent / Intent originais.
Observe que não testei todos os modos de inicialização de atividade.
fonte
A maneira direta é evitar chamar getIntent () de métodos diferentes de onCreate (). Mas isso causará problemas durante o próximo lançamento se o usuário deixar nossa atividade tocando no botão Início. Acho que esse problema não tem uma solução totalmente funcional.
fonte
Eu enfrento o mesmo problema e tento usar os métodos acima, mas não funciona.
Eu acho que pode ser a causa do modo de inicialização da atividade que usei o modo singleTop.
Quando eu uso o aplicativo em segundo plano e uso o RamEater para simular o problema, essa intenção sempre tem um valor extra, mesmo que seja definida como nula ou removida a chave.
O problema foi resolvido usando o armazenamento de preferência no Android para verificar se havia passado.
fonte
Não é uma boa prática adicionar outro extra apenas para saber se os extras foram consumidos ou não, porque não fazer isto ?:
fonte
Que tal agora? Define newIntent como a intenção.
fonte
Que tal quando você deseja limpar a intenção - substituí-la por uma vazia?
por exemplo.
fonte
Espero que isso ajude a todos. Então, primeiro temos a intenção
Coloque isso em algum lugar em Criar
Agora vamos definir isso para que toda vez que nosso aplicativo for destruído ou encerrado, removeremos os dados
Você entendeu, se isso não for suficiente, encontre mais chamadas de retorno ativas
fonte
Enquanto o
Intent.removeExtra("key")
irá remover uma chave específica dos extras, há também o método Intent.replaceExtras (Bundle) , que pode ser usado para excluir todos os extras do Intent, senull
for passado como um parâmetro.Dos documentos:
Como os métodos putXXX () inicializam os extras com um novo Bundle se for nulo, isso não é problema.
fonte
fonte