Руководство Android Intents

1- Введение

Статья основана на
  • Android Studio 1.4

2- Что такое Intent?

Intent (намерение) это асинхронные сообщения, позволяющие компонентам приложения запрашивать функциональность от других компонентов  Android. Intents позволяют вам взаимодействовать с другими компонента из тех же приложений, так же как и с компонентами созданные другими приложениями. Например, один Activity может вызвать внешний Activity, чтобы сделать фото.
intent это объект класса  android.content.Intent. Ваш код можно отправить на  Intent в систему  Android с определением компонентов, которые  вы хотите достичь.

Например, через  startActivity(), вы сможете дать определение  Intent который использвует для вызова другого  Activity. В целевом  Activity через метод  startActivity() вы сможете определить намерение отправителя вызвать данный (start) Activity.

Intent может содержать данные через  Bundle. Данные могут использоваться принимающим компонентом.

Intent можно использовать для:

  1. Стартовать Activity
  2. Стартовать дочерний Activity
  3. Стартовать сервис (Service).
После изучения про  Intent вы можете найти больше информации про  Android Service по ссылке:

3- Вилы Intent

Android поддерживает 2 вида  Intent это явные (explicit)   Intent và и неявные (implicit)  Intent.

Приложение может определить целевой компонент непосредственно  Intent (явное намерение) или запросить систему  Android оценить загистрированные компоненты основываясь на намерения данных (неявные  Intent).

4- Явный Intent 

Явные Intent (Explicit intents): это намерения (intent) назначить целевой компонент по его имени для обработки; при этом, в небязательном поле имени компонента устанавливается определенное значение через методы setComponent() или  setClass().
Созлать пример Intent:
// Create the Intent with the target of Greeting Activity.
// Intent(FirstActivity, SecondActivity.class)
Intent intent = new Intent(this,GreetingActivity.class);

// The data attached
intent.putExtra("firstName",firstName);
intent.putExtra("lastName", lastName);

// Start Activity (GreetingActivity)
// (No need feedback from the activity is called)
this.startActivity(intent);


// Start Activity and will have a feedback from the activity is called.
this.startActivityForResult(intent, MY_REQUEST_CODE);
Или:
// Way 1.
Intent mIntent = new Intent(this, GreetingActivity.class);
Bundle extras = mIntent.getExtras();
extras.putString("firstName", "<firstName>");
extras.putString("látName", "<lastName>");

// Way 2.
Intent mIntent2 = new Intent(this, GreetingActivity.class);
Bundle mBundle = new Bundle();
mBundle.putString("firstName", "<firstName>");
mBundle.putString("látName", "<lastName>");
mIntent2.putExtras(mBundle);

// Way 3:
// Using putExtra()
Intent mIntent3 = new Intent(this, GreetingActivity.class);
mIntent3.putExtra("firstName", "<firstName>");
mIntent3.putExtra("látName", "<lastName>");
В целевом  Activity:
Intent intent = this.getIntent();

String firstName= intent.getStringExtra("firstName");
String lastName = intent.getStringExtra("lastName");

// Or
Bundle extras = this.getIntent().getExtras();

String firstName1 = extras.getString("firstName");
String lastName2  = extras.getString("lastName");
OK, можете посмотреть иллюстрацию простых примеров ниже:

5- Пример с явным Intent

Это модель примера:
Создать новый  "Empty Activity" project с названием  ExplicitIntentExample:
  • main_activity.xml
Двойным нажатием на компоненты вашего интерфейса, вы можете установить для них  ID и  text:
EditText 1:
  • ID: text_firstName
  • Properties
    • layout_width: fill_parent
EditText 2:
  • ID: text_lastName
  • Properties
    • layout_width: fill_parent
TextView:
  • ID: text_feedback
  • Text: <Feedback>
  • Properties:
    • layout_width: fill_parent
    • gravity: center_horizontal
Button:
  • ID: button_greeting
  • Text: Show Greeting
  • Properties:
    • onClick: showGreeting
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/text_firstName"
        android:layout_alignParentTop="true"
        android:layout_marginTop="66dp"
        android:layout_centerHorizontal="true" />

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/text_lastName"
        android:layout_below="@+id/text_firstName"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="40dp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Show Greeting"
        android:id="@+id/button_greeting"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="132dp"
        android:onClick="showGreeting" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="&lt;Feedback>"
        android:id="@+id/text_feedback"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="59dp"
        android:gravity="center_horizontal" />

</RelativeLayout>

 
Когда пользователь нажимает на Button, программа вызовет другой Activity чтобы показать приветствие. Вам нужно создать другой   Activity с названием  GreetingActivity.
  • File/New/Activity/Empty Activity
  • activity_greeting.xml
Поменять атрибуты для компонентов на интерфейсе:
TextView
  • ID: text_greeting
  • Text: <Greeting>
  • Properties:
    • layout_width: fill_parent
    • gravity: center_horizontal

Button:
  • ID: button_back
  • Properties
    • onClick: backClicked
activity_greeting.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="org.o7planning.explicitintentexample.GreetingActivity">

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="&lt;Greeting>"
        android:id="@+id/text_greeting"
        android:layout_marginBottom="65dp"
        android:layout_above="@+id/button_back"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:gravity="center_horizontal" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Back"
        android:id="@+id/button_back"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:onClick="backClicked" />
</RelativeLayout>
 
MainActivity.java
package org.o7planning.explicitintentexample;

import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

   private EditText textFirstName;
   private EditText textLastName;
   private TextView textFeedback;

   public static final int MY_REQUEST_CODE = 100;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       this.textFirstName = (EditText)this.findViewById(R.id.text_firstName);
       this.textLastName = (EditText)this.findViewById(R.id.text_lastName);
       this.textFeedback = (TextView)this.findViewById(R.id.text_feedback);
   }

   // When 'Greeting Activity' completed, it sends back a feedback.
   // (If you have started it by startActivityForResult())
   @Override
   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       if (resultCode == Activity.RESULT_OK && requestCode == MY_REQUEST_CODE ) {
           String feedback = data.getStringExtra("feedback");
           this.textFeedback.setText(feedback);
       } else {
           this.textFeedback.setText("!?");
       }
   }

   // The method is called when the user clicks on "Show Greeting" button.
   public void showGreeting(View view)  {
        String firstName= this.textFirstName.getText().toString();
        String lastName= this.textLastName.getText().toString();

       Intent intent = new Intent(this,GreetingActivity.class);
       intent.putExtra("firstName", firstName);
       intent.putExtra("lastName", lastName);

       // Start Activity and no need feedback.
       // this.startActivity(intent);

       // Start Activity and get feedback.
       this.startActivityForResult(intent, MY_REQUEST_CODE);
   }

}
GreetingActivity.java
package org.o7planning.explicitintentexample;

import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class GreetingActivity extends AppCompatActivity {

   private String firstName;
   private String lastName;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_greeting);

       // Intent is passed into
       Intent intent = this.getIntent();

       this.firstName= intent.getStringExtra("firstName");
       this.lastName = intent.getStringExtra("lastName");

       String greeting = "Hello "+ firstName+" "+ lastName;

       TextView textGreeting =(TextView) this.findViewById(R.id.text_greeting);

       textGreeting.setText(greeting);
   }

   // When completed this Activity, send feedback to the caller.
   @Override
   public void finish() {
       // Prepare data intent
       Intent data = new Intent();
       data.putExtra("feedback", "I'm "+ this.firstName+", Hi!");
       // Activity finished ok, return the data
       this.setResult(Activity.RESULT_OK, data);
       super.finish();
   }


   // The method is called when the user clicks the Back button.
   public void backClicked(View view)  {
       // Calling onBackPressed().
       // Gọi phương thức onBackPressed().
       this.onBackPressed();
   }

 
}
Запус приложения:

6- Фильтр Intent (Intent Filter)

Когда вы создаете новый  Activity или  Service, вам нужно его объявить в  AndroidManifest.xml, обычно если вы создаете с помощью wizard в Android Studio автоматически создается регистрационный код в  AndroidManifest.xml. Например:
Можете заметить что в объявлении Activity на  AndroidManifest.xml может быть таг  <intent-filter>, этот таг определяет вид намерения Intent отправленный ему (Activity), который можно принять.
Когда вы создаете неявное намерение (Implicit Intent), система  Android назодит подходящие компоненты чтобы начать сравнивать содержания намерений (Intent) с фильтром намерений объявленные в файле  manifest других приложений на устройстве. Если Intent подходит к фильтру Intent, система вызывает этот компонент и передает в объект Intent.
Например:
 
** AndroidManifest.xml **
.....

<activity android:name=".HelloWorld"
   android:label="@string/app_name">
   <intent-filter>
       <action android:name="android.intent.action.VIEW"/>
       <category android:name="android.intent.category.DEFAULT"/>
       <category android:name="android.intent.category.BROWSABLE"/>
       <data android:scheme="http" android:host="o7planning.org"/>
   </intent-filter>
</activity>

...
Например при создании неявного Intent можно вызвать Activity выше (он подходит к фильтру Intent).
// An implicit intent, requested to view a URL

Intent intent = new Intent (Intent.ACTION_VIEW, Uri.parse("//o7planning.org"));
startActivity(intent);

7- Неявный Intent 

Неявные Intent (Implicit Intents): это намерения (intent), которые не дают определенные целевые компоненты, но включает достаточно информации для системы чтобы определить, какой настоящий компонент подходит для запуска этого намерения. Например приложение приложение дающее список ресторанов рядом с вами. Когда вы нажимаете и выбираете определенный ресторан, приложение спросит другое приложение, чтобы показать маршрут к выбранному ресторану. Чтобы добиться этого, оно может отправить явное намерение прямо к приложению Google Maps, или отправить неявное намерение, которое будет отправлено любому приложению, которое предоставляет функцию карты (map)  (например,  Yahoo Maps).

8- Простой пример с неявным Intent 

Простой пример, когда вы нажимаете на   Button запрашиваете посмотреть веб данный URL-ом, вы создаете неявное намерение (Intent), Intent отправляется системе Android решает какой компонент будет открыт, возможно в вашем устройстве есть много разных приложений ( Firefox, Chrome,..), устройство откроет браузер по умолчанию или ваш предпочитаемый браузер.
Помимо это в пример так же есть:
  • Отправление email
Создать новый Android project с названием  "ImplicitIntentExample".
Установить  ID, text и настройки для Button:
Button 1:
  • ID: button_google
  • Text: Go Google
  • Properties:
    • onClick: goGoogle
Button 2:
  • ID: button_email
  • Text: Send Email
  • Properties:
    • onClick: sendEmail
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Go Google"
        android:id="@+id/button_google"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="86dp"
        android:onClick="goGoogle" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send Email"
        android:id="@+id/button_email"
        android:layout_below="@+id/button_google"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="45dp"
        android:onClick="sendEmail" />

</RelativeLayout>

 
MainActivity.java
package org.o7planning.implicitintentexample;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

public class MainActivity extends AppCompatActivity {


   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
   }

   // The method is called when the user clicks on "Go Google" button.
   public void goGoogle(View view)  {
       String url="http://google.com";

       // An implicit intent, request a URL.
       Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
       this.startActivity(intent);
   }

   // The method is called when the user clicks on "Send Email" button.
   public void sendEmail(View view)  {

       // List of recipients
       String[] recipients=new String[]{"[email protected]"};

   
       String subject="Hi, how are you!";

     
       String content ="This is my test email";

       Intent intentEmail = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
       intentEmail.putExtra(Intent.EXTRA_EMAIL, recipients);
       intentEmail.putExtra(Intent.EXTRA_SUBJECT, subject);
       intentEmail.putExtra(Intent.EXTRA_TEXT, content);

       intentEmail.setType("text/plain");

       startActivity(Intent.createChooser(intentEmail, "Choose an email client from..."));
   }



}
Запуск приложения:
  • Send Email  (VIEW SLIDER).

9- Пример с неявным Intent, сфотографировать с Camera и записать в файл фото

Пример с неявным намерением  implicit​ Intent , когда вы нажимаете на Button, приложение отправляет системе  Android запрос сделать фото с помощью  Camera и сохранить фото в папке.