Pergunta

Eu tenho um aplicativo Android que precisa ser acordado esporadicamente ao longo do dia.

Para fazer isso, estou usando o AlarmManager para configurar um elegante e ter esse gatilho um BroadCastreceiver. Este BroadCastreceiver inicia uma atividade para levar a interface do usuário ao primeiro plano.

Tudo isso parece funcionar, na medida em que a atividade se inicia corretamente; Mas gostaria que o BroadCastreceiver notifique a atividade de que ela foi iniciada pelo alarme (em vez de ser iniciado pelo usuário). Para fazer isso, estou tentando, do método onReceive () do Broadcastreceiver para definir uma variável no pacote extras da intenção, assim:

    Intent i = new Intent(context, MyActivity.class);
    i.putExtra(wakeupKey, true);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(i);

No método OnResume () da minha atividade, procuro a existência dessa variável booleana:

protected void onResume() {
    super.onResume();

    String wakeupKey = "blah";      
    if (getIntent()!=null && getIntent().getExtras()!=null)
        Log.d("app", "onResume at " + System.currentTimeMillis() + ":" + getIntent().getExtras().getBoolean(wakeupKey));
    else
        Log.d("app", "onResume at " + System.currentTimeMillis() + ": null");
}

O getIntent (). GetExstras () chamado inreSume () sempre retorna nulo - eu não parece capaz de passar por nenhum extrás de nenhum pacote.

Se eu usar o mesmo método para ligar extras ao PendingIntent, que aciona o BroadCastreceiver, os extras aparecem muito bem.

Alguém pode me dizer o que há de diferente em passar um pacote de um broadcastreceiver para uma atividade, em vez de passar o pacote de uma atividade para um broadcastreceiver? Eu temo estar fazendo algo muito óbvio errado aqui ...

Foi útil?

Solução

Só para deixar claro (porque eu usei muito tempo para descobrir como fazê -lo funcionar)

Na classe de serviço que se estende BroadcastReceiver. Coloque o seguinte código em onReceive()

Intent intent2open = new Intent(context, YourActivity.class);
intent2open.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent2open.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
String name = "KEY";
String value = "String you want to pass";
intent2open.putExtra(name, value);
context.startActivity(intent2open);

o FLAG_ACTIVITY_SINGLE_TOP Garanta que os aplicativos não sejam reabertos se já estão abertos. Isso significa que a intenção "antiga" que abriu sua atividade em primeiro lugar é reutilizada e não conterá os valores extras. Você tem que pegá -los em outro método chamado onNewIntent() dentro YourActivity.

public class YourActivity extends Activity {
    private String memberFieldString;

    @Override
    public void onCreate(Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

         // Code doing your thing...
    } // End of onCreate()

    @Override
    protected void onNewIntent(Intent intent) {
    Log.d("YourActivity", "onNewIntent is called!");

    memberFieldString = intent.getStringExtra("KEY");

    super.onNewIntent(intent);
} // End of onNewIntent(Intent intent)

    @Override
    protected void onResume() {
        if (memberFieldString != null) {
            if (opstartsIntent.getStringExtra(KEY) != null) {
               Log.d("YourActivity", "memberFieldString: "+ memberFieldString);
            } else {
               Log.d("YourActivity", "The intent that started YourActivity did not have an extra string value");
            }
        }
    } // End of onResume()

}  // End of YourActivity

Observe as duas declarações se - o onResume() não sabe se é chamado depois OnCreate()->OnStart() OR onRestart()->onStart()
Por favor, veja: http://www.anddev.org/images/android/activity_lifecycle.png

É usado apenas para testar se o aplicativo é lançado pelo usuário (intenção sem extras) ou pelo BroadcastReceiver (intenção com extras).

Outras dicas

Este BroadCastreceiver inicia uma atividade para levar a interface do usuário ao primeiro plano.

Este pode ser o cerne do seu problema aqui. Tente substituir onNewIntent() e vendo se o Intent Passado para ele tem o seu extra. Nesse caso, isso é por causa da maneira como você configura a atividade no manifesto (por exemplo, você está usando singleTop) e o fato de que, nesse caso específico, a atividade já existia.

Você também pode considerar se livrar de i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); E veja se isso muda importa.

O resultado é que o que você está fazendo - colocando o extra no Intent por startActivity() - deve funcionar bem. De fato, você pode ver exemplos disso aqui. Isso sugere que é algo descolado sobre a atividade (por exemplo, singleTop) ou a maneira como você está invocando a atividade (por exemplo, FLAG_ACTIVITY_NEW_TASK).

EDITAR:

Como minhas primeiras fotos não funcionaram, e dado o seu comentário "curioso" acima ...

Isso parece um pouco como um PendingIntent - Com isso, a menos que você tome medidas, você não poderá atualizar extras.

Por um capricho, tente adicionar um segundo <intent-filter> para sua atividade no manifesto, apenas em alguma string de ação exclusiva, e tente iniciar sua atividade do seu receptor usando isso. Ou apenas jogue alguma string de ação em seu Intent que o receptor está usando para startActivity(), sem mexer com o manifesto.

Ao invés de getIntent().getExtras().getBoolean(wakeupKey) É mais convencional escrever getIntent().getBooleanExtra(wakeupKey, defaultValue). Não posso ter certeza se isso está relacionado ao seu problema, mas há algumas coisas a ver com a criação de um pacote dentro do getExtras () sobre o qual não tenho certeza, por isso pode valer a pena ir de qualquer maneira.

Definir bandeira de singletop Works (não misture com outras bandeiras)

Intent intent = new Intent(ContextManager.getContext(),OrderList.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Bundle bundle = new Bundle();       

bundle.putString("username",username);
bundle.putString("password",password);

intent.putExtras(bundle);
startActivityForResult(intent,0); 

Basta substituir o OnNewIntent como este e o pacote VAR estará disponível no método OnResume:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top