Usando startActivityForResult, como obter requestCode na atividade filho?

85

Eu tenho quatro atividades, digamos A, B, C e D. Minha situação é A iniciará a atividade B por startActivityForResult.

startActivityForResult(new Intent(this,B.class),ONE);

Em outra situação, irei B com outra situação. gostar

 startActivityForResult(new Intent(this,B.class),TWO);

Em B, preciso chamar C ou D dependendo de requestCode.
Ou seja, se UM precisa iniciar o C else D. Portanto, preciso saber como verificar o requestCode na atividade filho (B aqui).
Em outras palavras, desejo obter o código de solicitação com o qual a Atividade B foi iniciada.

Jithin
fonte

Respostas:

137

Você pode passar o código de solicitação por colocar extra.

intent.putExtra("requestCode", requestCode);   

Ou se você já usou startActivityForResultmuitas vezes, em seguida, melhor do que a edição de cada um, você pode overridea startActivityForResultsua Activity, adicioná-lo código lá como este

@Override
    public void startActivityForResult(Intent intent, int requestCode) {
        intent.putExtra("requestCode", requestCode);
        super.startActivityForResult(intent, requestCode);
    }

Portanto, não há necessidade de editar todos os seus startActivityForResult
Espero que tenha ajudado você

Labeeb Panampullan
fonte
49
Não há realmente nenhuma maneira de uma atividade filho obter seu código de solicitação?
i_am_jorf
1
Até agora, com meu melhor Conhecimento, não penso de outra maneira.
Labeeb Panampullan
17
Estava me perguntando a mesma coisa - essa é uma daquelas coisas nas APIs do Android que não faz nenhum sentido lógico.
Artem Russakovskii
7
startActivityForResult pode ser usado para iniciar atividades em outros aplicativos, requestCode é um assunto privado do seu aplicativo. Sob essa luz, faz sentido que Intent não tenha tal método e a abordagem certa é setAction informando exatamente o que você deseja que a Activity faça.
Maciej Beimcik
27

O código de solicitação não é passado para a atividade iniciada automaticamente porque ela não precisa (e não deveria) saber esse valor. Ele só precisa saber o que fazer e não de onde começou.

Iniciar uma atividade é apenas outra forma de chamar um método. Quando você chama um método, você recebe o resultado de forma síncrona (bem ali onde você fez a chamada). Nesse caso, você está apenas passando as informações de que o método precisa para fazer seu trabalho. Você não está dizendo de onde você fez a chamada.

Iniciar uma atividade é o análogo assíncrono de chamar um método, caso em que você recebe o resultado no método especial onActivityResult (). Neste método, você precisa saber o que fazer com o resultado que acabou de receber e você tem o código de solicitação para isso.

Para deixar um pouco mais claro por que não é uma boa ideia passar o código da solicitação como um parâmetro, considere a atividade de exemplo que mostra um produto que você pode comprar. Nesta atividade, existem dois botões rotulados "Comprar" e "Login" (já que você não está logado no momento). Pressionar "Login" iniciará uma atividade chamada "Login", que tentará fazer o login do usuário usando as informações fornecidas. Pressionar "Comprar" iniciará primeiro a mesma atividade de "Login" e, se o login for bem-sucedido, inicie a atividade de compra.

Agora, o botão "Login" usa o código de solicitação 1 para iniciar a atividade de login, mas o botão "Comprar" não pode usar o mesmo código de solicitação, pois terá que fazer algo diferente se o login for bem-sucedido. Portanto, o botão "Comprar" usa o código de solicitação 2.

Na atividade "Login", você pode receber dois códigos de solicitação diferentes, dependendo de onde foi chamada, mas você precisará fazer exatamente o mesmo procedimento.

Portanto, se você passar o código da solicitação como um parâmetro, acabará com o código que precisa fazer o mesmo para alguns códigos de solicitação diferentes, como:

if (requestCode == LOGIN || requestCode == BUY) {
    // ...
} else ...

Você também terminará armazenando as constantes do código de solicitação em um local central, por exemplo, uma classe chamada RequestCodes.

Em suma, o código de solicitação deve ser usado apenas para decidir o que fazer com o resultado recebido. Dessa forma, você terá um código mais modular, mais fácil de manter e de estender.

Szabolcs Berecz
fonte
1
E se for um tipo de "gerente" e você quiser que um código de solicitação entre para "salvar" um determinado valor (valor salvo em extras). Outro código de solicitação que "recuperaria" um valor (e retornaria em extras), mas dentro dessa atividade, eles também podem gerenciar de maneira geral os valores salvos, como renomear, editar, excluir, etc. O que você acha de algo assim? Eu acho que evitaria a duplicação de código / atividades para fazer as mesmas ações.
JRomero
@ J.Romero Não faça isso, só vai complicar as coisas. Basta colocar essa funcionalidade em uma classe (utilitário / singleton). Você também pode querer dar uma olhada em Handler and Service
Szabolcs Berecz
3
Szabolcs A atividade filho, mesmo que "não precise saber esse valor", pode precisar passar o valor para a próxima atividade em uma cadeia. Ironicamente, precisamos escrever mais código redundante para isso. Por algo que não precisamos saber tanto quanto recebemos mais palestras para ler sobre o que não devemos fazer.
user250343
Não vejo como isso ilustra por que uma atividade filho deve ter acesso negado ao código de solicitação. Eu nem tenho certeza de por que acessar o código de solicitação seria necessário em seu exemplo específico, considerando comprar agora e as chamadas de login são para duas atividades separadas de qualquer maneira.
Drazen Bjelovuk
1
@EvanR. talvez uma arquitetura melhor seria criar uma subclasse da atividade do item "mestre" em atividades de adicionar / editar separadas. Portanto, há uma reutilização mínima de código, mas cada atividade pode ser chamada independentemente.
Dane Powell
11

Acabei usando a ação Intent personalizada para passar esse tipo de informação para a atividade de inicialização.

protected static final String ACTION_DO_C = "do_c";
protected static final String ACTION_DO_D = "do_d";

Então você diria:

final Intent intent = new Intent(this,B.class)
intent.setAction(ACTION_DO_C);
startActivityForResult(intent,ONE);

E em Activity Bvocê consegue a ação facilmente:

getIntent().getAction();
Marcel Bro
fonte
0

Você pode usar getCallingActivity () para obter a atividade que iniciou a atividade atual e que receberá o valor do resultado com o código de resposta no final.

Moaz Rashad
fonte