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


    Введение


    Объекты типа 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));
        }   
    }
    

    Заключение


    Механизм интентов предоставляет большие возможности разработчику. В этой статье я хотел показать примеры действий, которые можно реализовать проще с помощью интентов. Надеюсь она сэкономит кому-нибудь время на разработку.
    Возможно существуют и другие интересные варианты использования интентов. Предлагаю делиться ими в комментариях.
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 18

      +2
      Чтобы просто открыть url в маркете никаких разрешений не нужно.
        +2
        Как, впрочем, и любой другой сайт в браузере
          0
          Да, спасибо, исправил.
            0
            Маркет можно открывать просто по market.android.com/… – тогда пользователи без Маркета получат результат в доступном браузере, но и минус в том, что адрес будет предложено открыть не только Маркетом, но и каждым браузером.
              +2
              Вы правы, но все таки приложения удобнее устанавливать через маркет, не через веб интерфейс. В крайнем случае можно добавить обработчик ActivityNotFoundException и перенаправить на браузер.
        +1
        Вот здесь еще автор наглядно и в картинках развивает тему мощности интентов для коммуникации между собой различных приложений.
          –1
          Предлагаю убрать «ов» в конце заголовка, так как не знаю как другие, а я прочитал сначала
          «Некоторые возможности использования интернетов»

          ПС: голосуем плюсами или минусами за комментарий.
            +3
            Тогда уж разделить для читаемости: использование Intent'ов.
            0
            Intent dialIntent = new Intent(Intent.ACTION_CALL, Uri.parse(«tel:» + «123456789»));
            startActivity(intent);

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


            Вы уверены? Я по практике знаю что не нужно, поскольку это ссылка, которая просто автоматически заполняет поле номера, но не производит вызов :) Тоесть пермишенов на телефонный вызов для этого не нужно.
              0
              Туплю, я про ACTION_DIAL писал.
              0
              Статью в избранное, спасибо!
                0
                В примерах все как всегда просто и понятно, но как оно в реальной жизни?..

                Например, камера: htc и стоковое приложение ведут себя по-разному, поэтому сохранять/забирать фото нужно немного более извращенно заботливо:

                Делаем фото:
                public void takePhoto() {
                // name consists of Photo + time taken
                Time now = new Time();
                now.setToNow();
                String fileName = "Photo_" + now.toString().substring(0, 13) + ".jpg";
                // create parameters for Intent with filename
                ContentValues values = new ContentValues();
                values.put(MediaStore.Images.Media.TITLE, fileName);
                values.put(MediaStore.Images.Media.DESCRIPTION, "Image captured by camera");
                // imageUri is the current activity attribute, define and save it
                // for later usage (also in onSaveInstanceState)
                mPhotoUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                values);
                // create new Intent
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoUri);
                intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
                startActivityForResult(intent, PHOTO_REQUEST_CODE);
                }


                Забираем:
                @Override
                protected void onActivityResult(int requestCode, int resultCode, Intent data) {

                super.onActivityResult(requestCode, resultCode, data);
                switch (requestCode) {
                case PHOTO_REQUEST_CODE:
                if (resultCode == Activity.RESULT_OK) {
                Bitmap bitmap = null;
                if (data != null)
                bitmap = (Bitmap) data.getExtras().get("data");
                else
                try {
                bitmap = android.provider.MediaStore.Images.Media.getBitmap(
                getContentResolver(), mPhotoUri);
                } catch (FileNotFoundException e) {
                e.printStackTrace();
                } catch (IOException e) {
                e.printStackTrace();
                }

                }
                break;

                default:
                break;
                }
                }
                  0
                  Вы хотите сказать не всегда в onActivityResult битмап можно получить из экстра?
                    +1
                    Увы и ах. Попробуйте сами на htc hero, например, и стоковом android (хоть на эмуляторе).
                      0
                      пробовал на desire, все было нормально. на эмуляторе вообще с камерой проблемы. Но спасибо за уточнение, буду добавлять проверки в следующий раз
                  +1
                  Почему-то не нашел аналогов на английском или русском, поэтому вот ссылка на то, что есть. Довольно большая подборка интентов для организации взаимодействия с популярными приложениями.
                    0
                    Добавил в закладки — пригодится. Спасибо, что собрали в одном месте это все — удобно.
                      0
                      хорошая статья, спасибо! добавляю в закладки

                      Only users with full accounts can post comments. Log in, please.