태그 보관물: 인텐트

안드로이드 공유 인텐트(Share Intent) 목록 필터링 하기

안드로이드 앱에서 데이터를 공유(Share)하는데, 이 데이터를 받아주는 써드 파티 앱을 실행하는 데는 인텐트(Intent)를 사용한다. 그리고 텍스트 데이터를 공유하는 데 사용하는 코드는 아래와 같다. 아래의 2번째 줄이 공유하는 데이터의 MimeType이다.

Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("text/plain");

실제로 위 인텐트를 사용해서 텍스트 데이터를 공유하는 예제를 살펴보면 다음과 같다.

String subject = "메시지 제목";
String text = "메시지 내용은\n다음줄에서..";

Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_TEXT, text);
Intent chooser = Intent.createChooser(intent, "타이틀");
startActivity(chooser);

이 예제코드를 사용해서 텍스트를 공유하는데, 이 데이터를 받아주는 앱들을 안드로이드 운영체제에 요청하면 아래와 같은 결과를 보게 된다.

Screenshot_2015-12-23-23-46-06

이 화면을 보면, 개발자가 텍스트를 공유하기 원하는 안드로이드 앱(종종 SNS 서비스 만을 보여주길 원한다)을 선택하기에 너무나 많은 앱을 보게 된다. 그래서 데이터를 공유하는데, 보이기 원하는 앱만을 필터링해서 보여주는 방법을 살펴보자.

여기에서 사용하는 방법은 패키지 매니저를 사용해서 데이터를 공유하는 인텐트를 처리할 수 있는 액티비티 정보를 가져오고, 이 정보를 사용해서 앱 이름 또는 패키지 이름으로 필요한 앱만 화면에 보이게 한다.

아래는 화면에 보이기 원하는 앱 이름 또는 패키지 이름으로 보이도록, 원하는 인텐트를 필터링 하는 예제이다.

/**
 *
 * @param name 패키지나 앱 이름
 * @param subject 제목
 * @param text 내용
 *
 * @return
 */
private Intent getShareIntent(String name, String subject, String text) {
    boolean found = false;

    Intent intent = new Intent(android.content.Intent.ACTION_SEND);
    intent.setType("text/plain");

    // gets the list of intents that can be loaded. 
    List<ResolveInfo> resInfos = getPackageManager().queryIntentActivities(intent, 0);

    if(resInfos == null || resInfos.size == 0)
        return null;

    for (ResolveInfo info : resInfo) {
        if (info.activityInfo.packageName.toLowerCase().contains(name) ||
                info.activityInfo.name.toLowerCase().contains(name) ) {
            intent.putExtra(Intent.EXTRA_SUBJECT, subject);
            intent.putExtra(Intent.EXTRA_TEXT, text);
            intent.setPackage(info.activityInfo.packageName);
            found = true;
            break;
        }
    }

    if (found)
        return intent;

    return null;
}

이제 위에서 살펴본 메서드를 사용해서 원하는 앱을 보여주기 위한 코드를 살펴보자. 아래의 코드를 살펴보면, “facebook”, “twitter”, “com.google.android.apps.plus”, 그리고 “gmail”로 필터링해서 targetedShareIntents에 인텐트 목록을 저장해서, 이 목록에 있는 인텐트 앱을 화면에 보여준다.

String subject = "메시지 제목";
String text = "메시지 내용은\n다음줄에서..";

List targetedShareIntents = new ArrayList<>();

// 페이스북
Intent facebookIntent = getShareIntent("facebook", subject, text);
if(facebookIntent != null)
    targetedShareIntents.add(facebookIntent);

// 트위터
Intent twitterIntent = getShareIntent("twitter", subject, text);
if(twitterIntent != null)
    targetedShareIntents.add(twitterIntent);

// 구글 플러스
Intent googlePlusIntent = getShareIntent("com.google.android.apps.plus", subject, text);
if(googlePlusIntent != null)
    targetedShareIntents.add(googlePlusIntent);

// Gmail
Intent gmailIntent = getShareIntent("gmail", subject, text);
if(gmailIntent != null)
    targetedShareIntents.add(gmailIntent);

Intent chooser = Intent.createChooser(targetedShareIntents.remove(0), "타이틀");
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[]{}));
startActivity(chooser);

자 이제 화면을 살펴보자.

Screenshot_2015-12-23-23-47-01

이제 앱에서 데이터를 전송하기 원하는 앱을 몇 개만 보게된다. 그래서 Tell a Friend와 같은 메뉴가 있다면 SNS 카테고리에 해당하는 앱만을 보여줄 수 있고, MimeType이 이미지인 경우에도 클라우드 서비스(Gdrive, Dropbox, Onedrive, Box 등)만을 데이터 공유에 사용할 수 있다.

이 방식의 단점은 아무래도 필터링을 해야 하니, 반응이 약간 느리다. 이 단점은 미리 캐시해서 해결할 수도 있다.

* Reference

– http://stackoverflow.com/questions/13286358/sharing-to-facebook-twitter-via-share-intent-android