Esta lição ensina a
Leia também
As duas lições anteriores enfatizaram um lado da história: iniciar a atividade de outro aplicativo pelo
seu aplicativo. Mas, se seu aplicativo puder executar uma ação que talvez seja útil para outro aplicativo,
ele precisará estar preparado para responder às solicitações de ação de outros aplicativos. Por exemplo, se
construir um aplicativo social que compartilhe mensagens ou fotos com os amigos do usuário, é interessante
que ele possa responder ao intent ACTION_SEND para que os usuários consigam iniciar uma
ação de “compartilhar” por outro aplicativo e iniciar seu aplicativo para executar a ação.
Para permitir que outros aplicativos iniciem a sua atividade, é necessário adicionar um elemento <intent-filter>
no seu arquivo de manifesto para o elemento <activity> correspondente.
Quando o aplicativo é instalado em um dispositivo, o sistema identifica seu filtro de
intents e adiciona as informações a um catálogo interno de intents suportado por todos os aplicativos instalados.
Quando um aplicativo chama startActivity() ou startActivityForResult(),
com um intent implícito, o sistema encontra quais atividades podem responder ao
intent.
Adicionar um filtro de intents
Para definir adequadamente que intents sua atividade poderá processar, cada filtro de intents adicionado deverá ser o mais específico possível em termos de tipo de ação e dados aceitos pela atividade.
O sistema pode enviar uma determinada Intent para uma atividade se ela tiver
um filtro de intents que atenda aos seguintes critérios do objeto Intent:
- Ação
- Uma cadeia de caracteres que dá nome à ação a ser executada. Geralmente, um dos valores definidos pela plataforma,
como
ACTION_SENDouACTION_VIEW.Especifique-a em seu filtro de intents com o elemento
<action>. O valor especificado nesse elemento deve ser o nome completo da cadeia de caracteres para a ação, e não a constante da API (veja exemplos abaixo). - Dados
- A descrição dos dados associados ao intent.
Especifique-a em seu filtro de intents com o elemento
<data>. Usando um ou mais atributos nesse elemento, você pode especificar apenas o tipo MIME, apenas um prefixo de URI, apenas um esquema de URI ou uma combinação desses e de outros elementos que indicam o tipo de dados aceito.Observação: Se não for necessário especificar os dados
Uri(como quando a atividade processa outros tipos de dados “extras”, em vez de um URI), especifique apenas o atributoandroid:mimeTypepara declarar o tipo de dado que a atividade processa, comotext/plainouimage/jpeg. - Categoria
- Oferece uma forma adicional de caracterizar a atividade que processa o intent, geralmente relacionada
ao gesto do usuário ou ao local onde foi iniciada. Há diversas categorias
suportadas pelo sistema, mas a maioria raramente é usada. No entanto, todas os intents implícitos são definidas com
CATEGORY_DEFAULTpor padrão.Especifique-a em seu filtro de intents com o elemento
<category>.
No filtro de intents, declare quais critérios serão aceitos pela atividade
declarando cada um deles com elementos XML correspondentes aninhados no elemento <intent-filter>
.
Este é um exemplo de atividade com filtro de intents que processa o intent ACTION_SEND quando o tipo de dado é texto ou imagem:
<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
<data android:mimeType="image/*"/>
</intent-filter>
</activity>
Cada intent recebida especifica apenas uma ação e um tipo de dado, mas pode-se declarar
várias instâncias dos elementos <action>, <category> e <data> em cada
<intent-filter>.
Se dois pares de ação e dados forem mutuamente exclusivos no comportamento, crie filtros de intents separados para especificar quais ações são aceitáveis quando pareadas com qual tipo de dado.
Suponha que a atividade processe texto e imagens para os intents ACTION_SEND e ACTION_SENDTO. Nesse caso, é preciso definir dois
filtros de intents para as duas ações porque um intent ACTION_SENDTO deve usar os dados de Uri para especificar
o endereço do destinatário usando o esquema de URI send ou sendto. Por exemplo:
<activity android:name="ShareActivity">
<!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
<intent-filter>
<action android:name="android.intent.action.SENDTO"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="sms" />
<data android:scheme="smsto" />
</intent-filter>
<!-- filter for sending text or images; accepts SEND action and text or image data -->
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="image/*"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
Observação: Para receber intents implícitos, inclua a categoria
CATEGORY_DEFAULT no filtro de intents. Os métodos startActivity() e startActivityForResult() tratam de todos os intents como se eles
declarassem a categoria CATEGORY_DEFAULT. Se você não a declarar
em seu filtro de intents, nenhum intent implícito será resolvida para a sua atividade.
Para obter mais informações sobre o envio e o recebimento de intents ACTION_SEND
que realizam comportamentos de compartilhamento social, consulte a lição Recebimento de dados simples de outros aplicativos.
Processar o intent em sua atividade
Para decidir qual ação tomar em sua atividade, leia a Intent usada para iniciá-la.
Quando a atividade iniciar, chame getIntent() para recuperar a
Intent que iniciou a atividade. Pode-se fazer isso a qualquer momento durante
o ciclo de vida da atividade, mas recomenda-se fazê-lo em retornos de chamada iniciais, como
onCreate() ou onStart().
Por exemplo:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Get the intent that started this activity
Intent intent = getIntent();
Uri data = intent.getData();
// Figure out what to do based on the intent type
if (intent.getType().indexOf("image/") != -1) {
// Handle intents with image data ...
} else if (intent.getType().equals("text/plain")) {
// Handle intents with text ...
}
}
Retornar um resultado
Se você deseja retornar um resultado para a atividade que invocou a sua, basta chamar setResult() para especificar o código do resultado e a Intent de resultado. Quando a operação estiver concluída e o usuário precisar retornar à atividade
original, chame finish() para fechar (e destruir) a atividade. Por
exemplo:
// Create intent to deliver some kind of result data
Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"));
setResult(Activity.RESULT_OK, result);
finish();
Sempre especifique um código de resultado com o resultado. Geralmente, é RESULT_OK ou RESULT_CANCELED. Pode-se fornecer
dados adicionais com uma Intent, caso seja necessário.
Observação: O resultado é definido como RESULT_CANCELED por padrão. Portanto, se o usuário pressionar o botão Voltar
antes de concluir a ação e de você definir o resultado, a atividade original receberá
o resultado “cancelado”.
Se precisa simplesmente retornar um número inteiro que indica uma das várias opções de resultado, você pode definir
o código de resultado como qualquer valor maior que 0. Se usar o código de resultado para entregar um número inteiro
e não tiver necessidade de incluir o Intent, você pode chamar setResult() e passar apenas um código de resultado. Por exemplo:
setResult(RESULT_COLOR_RED); finish();
Nesse caso, talvez existam apenas alguns poucos resultados possíveis. Portanto, o código do resultado é um número inteiro definido localmente (maior que 0). Isso funciona bem ao retornar um resultado para uma atividade em seu aplicativo porque a atividade que recebe o resultado pode fazer uma referência à constante pública para determinar o valor do código de resultado.
Observação: Não há necessidade de verificar se a atividade foi iniciada
com startActivity() ou startActivityForResult(). Simplesmente chame setResult() se o intent que iniciou sua atividade
estiver esperando um resultado. Se a atividade inicial tivesse chamado startActivityForResult(), o sistema lhe forneceria
o resultado para setResult(); caso contrário,
o resultado é ignorado.