문자 메시지를 주고받는 것은 휴대 장비의 근본적인 기능입니다. 많은 개발자들은 안드로이드의  문자 경험을 성공적으로 향상시킨 앱들을 개발해왔습니다. 일부 사람들은 감추어진 API들을 사용하여 문자 앱을 개발하였습니다. 우리는 이런 사용을 비추하는데 숨겨진 API들은 삭제될 수도 있고 새로운 단말기에서 호환성이 검증되지 않기 때문입니다. 그래서 문자 앱을 만들때 전체적인 지원 API 집합을 제공하고 문자 경험을 보다 예측가능하게 만들기 위해, 안드로이드 4.4(킷캣, KitKat)은 기존 API들을 공개하고 기본 문자 애플리케이션 개념을 추가하였습니다. 사용자는 시스템 설정에서 기본 문자 애플리케이션을 선택할 수 있죠.

이것은 이전 플랫폼 버전에서 숨겨진 문자 API를 사용했다면 조금의 수정하면 올해 출시 될 안드로이드 4.4에서도 제대로 동작하는 것을 의미합니다.

여러분의 앱을 기본 문자 앱으로 하기


안드로이드 4.4에서 단지 하나의 애플리케이션만 새로 도입된 SMS_DELIVER_ACTION 인텐트를 받을 수 있습니다. 새 문자 메시지가 오면 시스템은 이 인텐트를 브로드캐스트합니다. 어떤 앱이 이 브로드캐스트를 받을지는 시스템 설정에서 사용자가 기본 SMS 앱을 골라 결정합니다. 마찬가지로 기본 문자 앱만이 MMS가 도착했을 때 새 인텐트 WAP_PUSH_DELIVER_ACTION를 받습니다.

새 메시지를 받길 원하는 다른 앱들은 SMS가 왔을 때 대신에 SMS_RECEIVED_ACTION를 받을 수 있습니다. 하지만 (사용자가 기본 SMS 앱으로 지정한) SMS_DELIVER_ACTION 브로드캐스트를 받는 앱만 android.provider.Telephony 클래스와 상속된 클래스로 정의된 문자 프로바이더를 작성할 수 있습니다. 이것은 기존의 앱이 안드로이드 4.4에서 기본 문자 앱이 사용가능해질 때 앱이 망가지지 않고 SMS 프로바이더가 조용하게 실패하고, 문자 앱을 즉시 업데이트하지 않아도 된다는 점에서 중요합니다.

  • 브로드캐스트 리시버에서 SMS_DELIVER_ACTION ("android.provider.Telephony.SMS_DELIVER")에 대한 인텐트 필터를 포함합니다. 브로드캐스트 리서버는 BROADCAST_SMS 권한을 반드시 가져야 합니다.

    이 권한이 앱이 수신된 문자 메시지를 직접 받게 합니다.
  • 브로드캐스트 리시버에서 WAP_PUSH_DELIVER_ACTION("android.provider.Telephony.WAP_PUSH_DELIVER") 인텐트 필터를 MIME 타입 "application/vnd.wap.mms-message"와 함께 포함합니다. 이 브로드캐스트 리시버는 BROADCAST_WAP_PUSH 권한을 반드시 요구해야 합니다.

    이 권한이 앱이 수신된 MMS 메시지를 직접 받게 합니다.
  • 새 메시지를 전달할 액티비티에서 ACTION_SENDTO("android.intent.action.SENDTO")를 위한 인텐트 필터를 sms:, smsto:, mms:, mmsto: 스키마와 같이 포함합니다.

    이 필터가 메시지를 전달하길 원하는 다른 앱으로 부터 인텐트를 받게 합니다.
  • 서비스에서 sms:, smsto:, mms:, mmsto: 스키마와 함께 ACTION_RESPONSE_VIA_MESSAGE("android.intent.action.RESPOND_VIA_MESSAGE") 인텐트 필터를 포함합니다. 서비스는 SEND_RESPOND_VIA_MESSAGE 권한을 필요합니다.

    이 필터는 사용자가 여러분의 앱을 사용하여 즉시 문자 메시지를 받으며 걸려온 전화를 응답하는 것을 가능하게 합니다.

필요한 콤포넌트와 인텐트 필터의 예입니다.
<manifest>
    ...
    <application>
        <!-- BroadcastReceiver that listens for incoming SMS messages -->
        <receiver android:name=".SmsReceiver"
                android:permission="android.permission.BROADCAST_SMS">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_DELIVER" />
            </intent-filter>
        </receiver>

        <!-- BroadcastReceiver that listens for incoming MMS messages -->
        <receiver android:name=".MmsReceiver"
            android:permission="android.permission.BROADCAST_WAP_PUSH">
            <intent-filter>
                <action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
                <data android:mimeType="application/vnd.wap.mms-message" />
            </intent-filter>
        </receiver>

        <!-- Activity that allows the user to send new SMS/MMS messages -->
        <activity android:name=".ComposeSmsActivity" >
            <intent-filter>
                <action android:name="android.intent.action.SEND" />                
                <action android:name="android.intent.action.SENDTO" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="sms" />
                <data android:scheme="smsto" />
                <data android:scheme="mms" />
                <data android:scheme="mmsto" />
            </intent-filter>
        </activity>

        <!-- Service that delivers messages from the phone "quick response" -->
        <service android:name=".HeadlessSmsSendService"
                 android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
                 android:exported="true" >
            <intent-filter>
                <action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="sms" />
                <data android:scheme="smsto" />
                <data android:scheme="mms" />
                <data android:scheme="mmsto" />
            </intent-filter>
        </service>
    </application>
</manifest>
SMS_RECEIVED_ACTION 브로드캐스트의 어떤 필터를 사용하는 기존 앱들은 안드로이드 4.4에서도 동작합니다. 하지만 새 메시지의 관찰자로서만 동작합니다. SMS_DELIVER_ACTION 브로드캐스트를 받지 않는 한 안드로이드 4.4의 문자 프로바이더를 쓸 수 없습니다.

안드로이드 4.4에서 시작되면 실시간에 플랫폼 버전을 확인하여  PackageManager.setComponentEnabledSetting()를 사용하여 SMS_RECEIVED_ACTION 브로드캐스트 수신을 멈추어야 합니다. 하지만 여러 분의 앱이 휴대전화 번호 인증과 같은 특별한 문자 메시지만 읽기를 원한다면 여전히 저 브로드캐스트를 받을 수 있습니다. SMS_RECEIVED_ACTION 인텐트를 안드로이드 4.4에서 다룬다면 다른 앱도 브로드캐스트를 필요할지 모르니 취소하지 말아야 합니다.

: 두 문자 브로드캐스트를 구별하기 위해 SMS_RECEIVED_ACTION를 단순히 "시스템이 문자를 받는다"로 생각하세요. SMS_DELIVER_ACTION는 기본 문자앱이기 때문에 "시스템이 여러분의 앱에 문자를 전달해준다"로 생각하고요.

기본 문자 앱이 아닌 경우에 비활성화되는 기능들


애플리케이션이 현재 기본 문자 앱으로 선택되지 않았다면 문자 프로바이더 작성 기능없이는 보내는 어떤 메시지도 사용자의 기본 문자 앱으로 나타나지 않기 때문에 새 메시지 전송하기 기능을 비활성화해야하는 것이 중요합니다.그래서 액티비티가 재게될 때 현재 기본 문자 앱의 패키지 네임을 반환하는 Telephony.Sms.getDefaultSmsPackage()를 질의하여 여러분의 앱이 기본 문자 앱인지 확인해야 합니다. 여러분의 패키지 이름과 일치하지 않는다면 메시지 전송 기능을 비활성화 합니다.
메시지 전송과 수신을 활성화하기 위해 시스템이 제공하는 다이얼로그를 띄울 수 있습니다. 이 다이얼로그에서 사용자는 여러분의 앱을 기본 앱으로 설정할 수 있습니다. 다이얼로그를 표시하기 위해 Sms.Intents.EXTRA_PACKAGE_NAME를 키로 삼고 여러분의 패키지 네임을 문자 값으로 삼는 extra를 포함한 Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT 인텐트와 함께 startActivity()를 호출합니다.

우아한 사용자 경험을 제공하기 위해 액티비티가 재개될 때 앱이 기본 문자 앱인지 확인하고, 사용자가 기본 문자 앱을 변경하게 하는 메시지를 담게 사용자 인터페이스를 수정하세요. 예를 들어 액티비티 코드는 이렇게 될 수 있습니다.
public class ComposeSmsActivity extends Activity {

    @Override
    protected void onResume() {
        super.onResume();

        final String myPackageName = getPackageName();
        if (!Telephony.Sms.getDefaultSmsPackage(this).equals(myPackageName)) {
            // App is not default.
            // Show the "not currently set as the default SMS app" interface
            View viewGroup = findViewById(R.id.not_default_app);
            viewGroup.setVisibility(View.VISIBLE);

            // Set up a button that allows the user to change the default SMS app
            Button button = (Button) findViewById(R.id.change_default_app);
            button.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    Intent intent =
                            new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
                    intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, 
                            myPackageName);
                    startActivity(intent);
                }
            });
        } else {
            // App is the default.
            // Hide the "not currently set as the default SMS app" interface
            View viewGroup = findViewById(R.id.not_default_app);
            viewGroup.setVisibility(View.GONE);
        }
    }
}

문자 백업 복구 앱에 대한 조언


문자 프로바이더를 쓸 수 있는 기능이 사용자가 기본 문자 앱으로 선택한 앱에 한정되기 때문에 순전히 문자를 백업하고 복구하게 설계된 기존 앱들이 안드로이드 4.4에서 문자를 복구하는 것이 현재 허용되지 않습니다. 문자 메시지를 백업하고 복구하는 앱은 기본 문자 앱으로 지정이 되어야 SMS 프로바이더에 메시지를 쓸 수 있습니다. 하지만 앱이 SMS 메시지를 받고 읽을 필요가 없다면 기본 문자 앱 설정을 유지해서는 안됩니다. 그래서 사용자가 여러분의 앱을 열어 일회용 복원 명령을 시작할 때 다음 설계된 기능적인 사용자 경험을 제공할 수 있습니다.
  1. 현재 기본 문자 앱의 패키지 네임을 질의 하고 저장합니다.
    String defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(context);
  2. 문자를 복원하기 위해 기본 문자앱을 사용자가 전환하게 요청합니다. (문자 프로바이더를 작성하기 위해서는 기본 문자 앱이 되어야 합니다.
    Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT);
    intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, context.getPackageName());
    startActivity(intent);
  3. 모든 문자 메시지가 복원되면 (첫번째 절차에서 저장된) 기존에 서택된 기본 문자 앱으로 돌아가도록 요청합니다.When you finish restoring all SMS messages, request the user to change the default SMS app back to the previously selected app (saved during step 1).
    Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT);
    intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, defaultSmsApp);
    startActivity(intent);

문자 앱 업데이트 준비하기


안드로이드에서 최고의 경험을 사용자에게 제공하기 위해 가능한 빨리 업데이트하길 격려합니다. 안드로이드 4.4의 변화를 컴파일하고 실험하기 위해 필요한 안드로이드 4.4를 위한 SDK  콤포넌트 곧 제공하겠습니다. 계속 개선하세요!






아래 사항을 참고하셔서 늦지 않게 참가 신청 부탁드립니다.

- 일시: 10월 24일 목요일 오전 9시 ~ 오후 6시
- 장소: 선릉역 디캠프 6층 http://dreamcamp.co/location

(아래에서 세션 제목을 클릭하시면 동영상을 시청하실 수 있습니다.)
09:00:00Registration
09:25:00GreetingSoonson Kwon
09:30:00Whats new in Mobile HTMLThis session will show you the leading edge of the mobile web, enabling you to take your mobile sites and apps to the next level. We will dive into features that you never thought you could enable in a mobile browser and give you practical advice for the year ahead.Alex Danilo, Eiji Kitamura
10:15:00Building modern apps with Polymer & Web ComponentsWeb components are a fundamentally different way of building web apps. Shadow DOM, templates, custom elements, and HTML Imports yield a huge boost in productive and allow us to finally create reusualbe, shareable components. In this session, you'll learn how to use Google's new framework Polymer to create web component-based applications. Eric Bidelman
11:00:00BREAK
11:45:00Using DevTools to improve your Mobile WorkflowChange file, hit F5, change file, hit F5. Let's evolve this. We'll cover the end-to-end workflow of constructing a quick feedback cycle development environment, using Chrome DevTools smartly to accelerate your development, support testing, and authoring mobile sites and webapps quickly. With the range of device form factors, platforms and browsers, it's important to find a workflow that helps you support these variations. This session will look at some of the approaches you could take.Paul Irish
12:30:00LUNCH
13:15:00Building great games with HTML5 and NaClBuilding great HTML5 games starts with picking the correct tech to build on. WebGl, Canvas, and NaCl will be covered. Games often push the browser to the limit, so you must become familiar with builtin performance analysis tools and best practices for keeping the GC under control. Finally, Polymer can allow your game to be built with custom elements, a demo of a 3D graphics engine built on top of Polymer will be shown. John McCutchan
14:00:00Chrome Apps: desktop today, mobile tomorrow.Just like web apps, Chrome Apps are written in HTML5, JavaScript, and CSS, but they look and behave like all other installed apps, and they have the same capabilities, with access to native hardware like USB and bluetooth. With Chrome Apps, you can easily build fully featured offline apps that work on any platform. Not only will you learn how you can build a Chrome App, but we'll take a look into the not so distant future to show you how to make that app work on mobile!Pete LePage
14:45:00Rendering without the lumpy bitsRight, we’ve got a new project, we have to calculate and draw 500,000 pixels, and the deadline is in 1.667 milliseconds. When we’re done, we’ll do it again, and again. Web performance has always been about delivering those pixels on time, but the target has shifted. Optimising pure JavaScript (loops, string concatination, arithmetic) is more irrelevant than ever, performance gains are to be found in the DOM, layout dependencies, and the interaction with the GPU.

We’ll look at a series of real-world rendering issues and how to combat them, understanding why particular hacks work, and how sometimes working against the browser can trick it into performing better. Covering basic html layout and animation, GPU interaction and high-dpi (retina) considerations across browsers and devices.
Jake Archibald
15:30:00BREAK
16:15:00Building fast mobile sites with PageSpeed InsightsDelivering a fast mobile experience is more important than ever and requires careful consideration and engineering: you need to optimize your network access, you need to prioritize critical assets to deliver the best visual rendering performance. You will learn detect potential performance of your sites on mobile browsers and how you can fix them to get your site as quickly as possible to your users.Paul Kinlan
17:00:00An introduction to DartStructure, Speed, Tools, and Polymer: Dart is an object oriented, class based language with static types that you will immediately feel comfortable programming in. The structured nature of Dart not only increases programmer productivity it also allows programs to run significantly faster. Dart has a powerful editor and a rich standard library that make writing large scale applications easy and fun. On top of all of this Dart has embraced Polymer as a first class citizen. Come and learn about Dart and the future of programming on the web.John McCutchan
17:45:00Closing remarkVivian Cromwell

- 10월 18일 오전 10시까지 등록 부탁 드립니다.
- 주요 참석 대상은 웹/모바일 관련 개발자/엔지니어/기술 담당자 분들입니다.
- 제목이나 내용, 시간은 추후 변경될 수 있습니다.
- 세션은 영어로 제공되며 동시통역이 제공될 예정입니다.
- 점심 식사는 주최측에서 제공하여 드립니다.
- 참석하신 분들께는 소정의 기념품을 제공하여 드립니다.
- 주차는 제공되지 않으니 대중교통을 이용해 주시기를 권장하여 드립니다.

좌석이 한정되어 있는 관계로 참가 신청은 선착순이 아니며 별도 선정후 연락 드립니다. 가장 관련이 높은 분들을 모시기 위한 조치이니 양해 부탁드리겠습니다.

10월 24일 Chrome Developer Day 참가 신청하기!


Chrome & Web Technology Barcamp

Barcamp는 가만히 앉아서 다른 사람의 이야기를 듣기만 하는 일반적인 세미나/컨퍼런스와는 다르게 특정 주제에 관해 관심있는 분들을 모시고 함께 편하게 이야기를 나누기 위한 자리입니다. 주제별로 대여섯명 정도씩 모여서 편하게 차한잔 하는 자리로 생각하시면 가장 좋습니다.

이번 Chrome & Web Technology Barcamp에서는 Chrome과 Mobile HTML, WebView, Polymer, Web Components, Dart, Web Game, Chrome Apps, Performance, DevTools, Blink 등 다양한 기술들을 모두 커버할 수 있는 약 15명의 구글 소프트웨어 엔지니어, 제품 관리자, 에반젤리스트 등이 함께합니다.

Chrome & Web Technology를 실제로 개발하고 있는 담당자들과 직접 이야기할 수 있는 흔치 않은 기회에 부디 많은 분들의 관심 부탁드립니다.

- 일시: 10월 25일 금요일 오후 2시 30분 ~ 5시
- 장소: 구글 코리아 사무실

- 참석해 주신 분들께는 소정의 기념품을 드립니다.
- 주차는 지원되지 않으며 상황에 따라 통역은 제공될 수도 있습니다.

신청은 10월 18일 금요일 오전 9시까지 받겠습니다.

선착순이 아니며 선정되신 분들께 별도로 연락을 드리겠습니다.

Chrome & Web Technology Barcamp 참가 신청하기!