Pull to refresh

Некоторые возможности использования Intent'ов

Reading time6 min
Views67K

Введение


Объекты типа Intent могут быть использованы для общения между отдельными частями Android приложения, либо между различными приложениями системы. Мощь механизма интентов заключается в том, что с его помощью можно обращаться к любому установленному в системе приложению. Это позволяет повторно использовать некоторые компоненты и значительно сократить время на разработку.

В этой статье я покажу некоторые возможности использования класса Intent для обращения к системным приложениям.

Итак, что можно сделать с помощью Intenta:

1. Позвонить


Intent dialIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + "123456789"));
startActivity(dialIntent);

Необходимо также добавить разрешение совершать звонки:
<uses-permission android:name="android.permission.CALL_PHONE" />

Либо разрешение для экстренных вызовов:
<uses-permission android:name="android.permission.CALL_PRIVILEGED" />

Звонки можно также совершать, указав интенту первый параметр как ACTION_DIAL. При этом будет открываться телефонная книга с указанным номером, но сам звонок автоматически совершаться не будет. Этому параметру не нужны разрешения в манифесте.

2. Отправить смс


Intent smsIntent = new Intent(Intent.ACTION_VIEW);
smsIntent.setType("vnd.android-dir/mms-sms");
smsIntent.putExtra("sms_body", "Some SMS text"); 
startActivity(smsIntent);   

Т.к. этот код не отправляет смс напрямую, а запускает стандартное активити для отправки смс, то никаких разрешений указывать не нужно.

3. Получить контакт из телефонной книги


Intent pickIntent = new Intent(Intent.ACTION_PICK, 
    android.provider.ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(pickIntent, PICK_RESULT);

Этот код откроет стандартное приложение контактов. Метод startActivityForResult позволяет получить uri выбранного контакт из параметра Intent data переопределенного метода onActivityResult.

Приведенный выше код показывает в приложении контактов сразу все контакты пользователя, включая почтовые. Если необходимо выбрать только контакт из телефонной книги, можно воспользоваться следующим кодом:

Intent pickIntent = new Intent(Intent.ACTION_GET_CONTENT);
pickIntent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
startActivityForResult(pickIntent, PICK_RESULT);

Для чтения списка контактов необходимо также добавить в манифест разрешение:

<uses-permission android:name="android.permission.READ_CONTACTS" />

4. Открыть ссылку в браузере


Intent browseIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
startActivity(browseIntent);

Данный код откроет переданную в параметре ссылку в одном из установленных браузеров. При этом пользователь сможет сам выбрать браузер для просмотра. Eсли ссылка ведет на YouTube, то можно сразу открыть видео стандартным YouTube приложением.
С помощью этого интента можно также открыть стандартный клиент Android Market с ссылкой на какое-либо приложение. Для этого необходимо в параметр uri передать ссылку вида market://search?q=search query, где search query необходимо заменить соответствующим поисковым запросом.
Разрешения на интернет указывать не нужно, т.к. сеть используется не напрямую, а через приложение браузер.

5. Расшарить контент/написать письмо


Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Content subject");
shareIntent.putExtra(Intent.EXTRA_TEXT, "Content text");
startActivity(Intent.createChooser(shareIntent, "Sharing something."));

Интенту можно задать тему и текст контента, который необходимо разшарить. Метод Intent.createChooser() создает диалог выбора соответствующего приложения.
Если необходимо разшарить медиа контент (изображение/видео), то нужно указать соответствующий тип контента в методе setType, например mailIntent.setType(«image/png»);, а также добавить сам контент в extra интента:

shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri);

С помощью этого интента можно также отправить электронную почту по конкретному адресу:

shareIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { mail });

6. Открыть карту по определенным координатам либо запросу


String uri = "geo:"+ latitude + "," + longitude;
Intent mapIntent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(mapIntent);

Uri при этом можно модифицировать, указывая другие параметры:
  • geo:latitude,longitude
  • geo:latitude,longitude?z=zoom Параметр z — уровень зума при отображении карты (от 0 до 23)
  • geo:0,0?q=my+street+address
  • geo:0,0?q=business+near+city

7. Сделать снимок с камеры


Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_RESULT);

Этот код запускает стандартное приложение камеры. Полученное с камеры изображение можно обработать в методе onActivityResult:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == CAMERA_RESULT) {
        Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
        ImageView ivCamera = (ImageView) findViewById(R.id.iv_camera);
        ivCamera.setImageBitmap(thumbnail);
    }
}

Изображение, полученное с камеры при этом можно сохранить в конкретной директории, добавив параметр в интент:

File photo = new File(Environment.getExternalStorageDirectory(),  "Pic.jpg");
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(filePath)));

Для использования этого интента не нужно разрешения android.permission.CAMERA, т.к. камера используется не напрямую, а всего лишь вызывается встроенное приложение камеры. Однако рекомендуется добавить в AndroidManifest следующую строку:

<uses-feature android:name="android.hardware.camera"></uses-feature>

Таким образом, люди с девайсами без встроенной камеры (судя по всему, такое тоже бывает) не будут видеть ваше приложение на маркете.

8. Позвонить какому-либо контакту через Skype

Для совершения звонка через скайп интенту необходимо указать конкретное имя активити и пакета, к которым он будет обращаться. Это немного усложняет код, т.к. в двух разных версиях скайпа имена пакетов отличаются. Необходимо выполнять проверку того, какая версия скайп клиента установлена в системе, и установлена ли она вообще. Для проверки можно использовать следующий метод:

public static boolean isIntentAvailable(Context context, Intent intent) {
    final PackageManager packageManager = context.getPackageManager();
    List<ResolveInfo> list = packageManager.queryIntentActivities(
        intent, PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() > 0;
}

Этот метод проверяет в системе наличие приложения, способного ответить на конкретный интент. С использованием этого метода код звонка через скайп будет выглядеть следующим образом:

private static final String SKYPE_PATH_GENERAL = "com.skype.raider";
private static final String SKYPE_PATH_OLD = "com.skype.raider.contactsync.ContactSkypeOutCallStartActivity";
private static final String SKYPE_PATH_NEW = "com.skype.raider.Main";

Intent skypeIntent = new Intent().setAction("android.intent.action.CALL_PRIVILEGED");
skypeIntent.setData(Uri.parse("tel:" + skype));

if (isIntentAvailable(context, skypeIntent.setClassName(SKYPE_PATH_GENERAL, SKYPE_PATH_NEW))) {
    context.startActivity(skypeIntent);
} else if (isIntentAvailable(context, skypeIntent.setClassName(SKYPE_PATH_GENERAL, SKYPE_PATH_OLD))) {
    context.startActivity(skypeIntent);
} else {
    Toast.makeText(context, "Приложение Skype не установлено.", Toast.LENGTH_LONG).show();
}

Более простым методом проверки наличия приложения в системе является перехват ActivityNotFoundException, которое будет вылетать в методе startActivity. Однако это позволит всего лишь среагировать на проблему, но не предотвратить ее. Например, используя вышеприведенный метод isIntentAvailable можно вовремя сделать соответствующий контрол неактивным, либо перенаправить пользователя на Android Market для установки соответствующего приложения.

9. Использовать Speech to Text для распознавания голоса


Intent speechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
speechIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, 
    RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
speechIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speak please");
startActivityForResult(speechIntent, RESULT_SPEECH_TO_TEXT);

Этот код запускает приложение распознавания речи. Если произнести что-либо, система обработает голос и вернет результат в метод onActivityResult:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == RESULT_SPEECH_TO_TEXT && resultCode == RESULT_OK) {
        ArrayList<String> matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
        TextView tvSpeech = (TextView) findViewById(R.id.tv_speech);
        tvSpeech.setText(matches.get(0));
    }   
}

Заключение


Механизм интентов предоставляет большие возможности разработчику. В этой статье я хотел показать примеры действий, которые можно реализовать проще с помощью интентов. Надеюсь она сэкономит кому-нибудь время на разработку.
Возможно существуют и другие интересные варианты использования интентов. Предлагаю делиться ими в комментариях.
Tags:
Hubs:
+70
Comments18

Articles

Change theme settings