리눅스/일반
2014. 3. 28. 02:52
현재 작업 디렉토리를 알고 싶다 - pwd


pwd는 현재 내가 위치하고 있는 디렉토리의 절대경로를 표시한다.

ls, cd와 함께 세트로 많이 사용되는 명령어 중의 하나다.


pwd의 man page를 보면 'printf name of current/working directory.'라고 씌여 있는 걸 봐서는 '작업 디렉토리 출력'의 약자가 아닌가 싶다.


pwd의 사용법은 지극히 간단해서 아래와 같이 사용한다.


pwd [<옵션>]...


게다가 '옵션'도 달랑 '-L'과 '-P'뿐이다.


$ pwd -L


-L 은 logical location (심볼릭 링크의 안에 있다면 그냥 심볼릭 링크의 경로가 표시된다.)이고


$ pwd -P


-P은 physical location (심볼릭 링크 안에 있다면 심볼릭 링크가 가리키는 원래 디렉토리의 경로를 표시한다.)


리눅스 터미널에서는 현재 내가 위치한 디렉토리를 프롬프트 상에 표시해주기는 하지만 전체 경로가 어떻게 되는지 알려주지는 못한다. 그래서 현재 내가 위치한 디렉토리의 전체 경로를 알고자 할 때 'pwd'를 많이 사용하게 되므로 기억해 두자.


posted by 리치크루

리눅스/일반
2014. 3. 25. 23:37


리눅스 기본 명령어 - ls


리눅스 기본 명령어 중의 기본 명령어 ls에 대해서 알아보자.



ls를 사용하여 현재 디렉토리의 파일(디렉토리 포함) 목록 보기


ls는 List의 약어로 특정 디렉토리의 목록을 보여주는 명령어다.

MS-DOS나 MS Windows의 cmd.exe를 실행해서 사용하는 dir명령어와 비슷하다. 다만 ls는 터미널에서 사용된다.


OS의 종류에 상관없이 디렉토리는 파일의 한 형태라고 봐야 한다. 보통 "ls 명령어가 특정 디렉토리의 파일 목록을 보여준다."고 하는데 "디렉토리 목록까지 보여주니 이건 틀린 말이야."라고 생각하면 곤란하다는 거다. 사용자 입장에서는 파일과 디렉토리가 다르게 보일지 몰라도 OS입장에서는 그 놈이 그 놈이다.


ls의 사용법은 다음과 같다.


ls [<옵션>]... [<파일>]...


아주 간단하다. ls 쓰고 옵션쓰고 파일 또는 디렉토리를 써주면 끝!

하지만 ls의 옵션은 무려 58가지나 된다.(지금 세어봤다.)

터미널에 "ls --help"라고 한 번 쓰고 실행시켜보자. 그러면 ls 명령어의 도움말이 출력된다.

그런데 도움말을 읽다보면 이해 안되는 옵션들도 많고 정작 쓸만한 옵션은 고작 4~5개 정도?!

그래서 많이 씀직한 옵션들을 추려보았다.



ls에서 자주 사용하는 옵션


뭐 자주 사용하는 옵션이라고 한 건 지극히 개인적인 생각이다.

('어! 이것도 많이 쓰는 옵션인데?'라고 하시는 분... 당신은 이 글을 읽을 수준이 아닙니다.)


아래 옵션에 대한 설명을 하는 부분에서 옵션을 표현할 때 하이픈(-) 하나를 쓰는 경우와 두 개를 쓰는 경우가 있다. 하이픈이 하나일 경우에는 옵션명을 짧게 이니셜만을 사용하고 두 개 사용할 때는 옵션명을 길게 단어로 입력하게 된다. 물론 이 두 개의 옵션 표현은 해당 명령어에서 지원해줘야 한다.

이 두 종류의 옵션 표현은 ls명령에서만 해당되는 것이 아니니 기억해두자.


옵션 -a (또는 --all)

사용법

ls -a 또는 ls --all


설명

.(마침표)로 시작하는 항목을 무시하지 않는다. (do not ignore entries starting with .)
숨김 파일도 함께 보여 준다. 리눅스도 MS Windows와 마찬가지로 숨김 파일이 존재한다.


옵션 -l

사용법

ls -l


설명

파일 목록을 구구절절하게 표시한다. (use a long listing format)
파일 이름만 표시하는 것이 아니라 파일의 정보까지 자세히 보여준다.


옵션 -R (또는 --recursive)

사용법

ls -R 또는 ls --recursive

설명

하위 디렉토리의 목록까지 죄다 보여준다. (list subdirectories recursively)
현재 디렉토리의 파일 목록만이 아니라 하위 디렉토리가 있다면 하위 디렉토리의 파일 목록까지 보여주며 하위 디렉토리에 또 하위 디렉토리가 있다면, 또또 하위 디렉토리가 있다면... 하위 디렉토리가 없을 때까지 다 드러내 보여주는 옵션이다.



한번에 여러 개의 옵션을 동시에 사용할 때에는 따로 쓰지 않아도 된다. 함께 묶어 쓸 수도 있다.
예를 들어, ls에 -a, -l, -R의 3개 옵션을 모두 사용하여야 하는 경우
$ ls -a -l -R
이라고 쓸 필요가 없다. 그냥
$ ls -alR
이라고 쓰면 된다. 물론 옵션의 순서도 상관없다.


구구절절하게 설명하고 또 그 설명을 들어봐야 직접 한번 해 보는 것이 제일입니다. 한 번 해보세요. ls!



'리눅스 > 일반' 카테고리의 다른 글

rmdir - 디렉토리 삭제  (0) 2015.01.22
mkdir - 새로운 디렉토리 생성  (0) 2015.01.21
pwd - 현재 내 위치를 알려주는 명령어  (0) 2014.03.28
posted by 리치크루

IT 정보
2014. 3. 19. 17:39
VirtualBox란 무엇인가?


하나의 컴퓨터에서 하나 이상의 OS를 설치하여 사용해야 하는 경우가 있다.

우리나라에서는 서버가 아닌 개인용PC 또는 업무용PC의 경우 대부분 마이크로소프트의 Windows 운영체제를 사용한다. 하지만 간혹 내 PC에 설치된 운영체제와는 궁합이 맞지 않는 소프트웨어들이 꼭 있다. 예를 들어, 내 PC에 Windows 7 32bit 운영체제가 설치되어 있지만 XP 운영체제에서만 동작하는 소프트웨어가 있다거나 64bit 운영체제에서만 동작하는 소프트웨어들이 그렇다. 이런 경우, 여러 해결책이 있겠지만 보통은 다음과 같이 해결이 가능할 것이다.


  1. 동작하지 않는 소프트웨어의 사용을 포기한다.
  2. PC를 포맷하고 동작하지 않는 소프트웨어가 필요로하는 운영체제를 설치하여 사용한다.
  3. PC에 소프트웨어가 필요로하는 운영체제를 추가 설치하여 멀티부트 시스템을 구축한다.
  4. PC에 동작하지 않는 소프트웨어를 위한 가상머신을 만들어 필요한 운영체제를 설치하여 사용한다.


첫번째 방법은... 사실 해결방법은 아니죠. 그쵸?

두번째 방법은 벼룩 한마리 잡으려고 초가삼간 다 태우는 격이 될테고

세번째 방법의 멀티부트는 부팅할 때마다 운영체제를 선택해줘야하는 불편함과 잠시 다른 운영체제를 사용해야할 때 다시 리부팅하는 번거로움이 있다.

그리고 가장 추천하고픈 네번째 방법이 있다.


네번째 방법은 현재 PC에 설치된 운영체제 위해서 마치 하나의 소프트웨어가 동작하듯 가상의 PC를 운용할 수 있다. 리부팅을 하지 않아도 자유롭게 실제 PC와 가상 PC를 자유롭게 왔다갔다하며 사용할 수도 있다.(이 방법을 사용하기 위해서는 하드웨어 사양은 좀 받쳐줘야한다. 하지만 크게 고사양의 본체를 요구하는 것은 아니다. 리치크루의 PC는 20만원짜리 중고PC지만 호스트에는 윈도우, 게스트에는 우분투 Desktop을 설치해서 잘 쓰고 있다.)


앞서 설정했던 상황이 발생했을 때 네가지 방법 중 편의성을 고려해 한가지를 선택하라면 아마도 대부분의 사람들이 네번째 방법을 선택하지 않을까 싶다.

그러나 네번재 방법이 그냥되는 것은 아니다. 가상머신을 만들어주는 소프트웨어가 따로 필요하다. 그 중에서도 가장 많이 알려진 소프트웨어는 VMWare와 VirtualBox되시겠다. 컴퓨터 좀 만져봤다는 사람은 대부분 들어봤을 것이다.

이 글에서는 그 중 VirtualBox에 대해서 설명하고자 한다.



오픈 소스 소프트웨어 [VirtualBox]

VirtualBox의 웹사이트는 https://www.virtualbox.org/이다.


VirtualBox의 라이센스 정책


VMWare의 가격은 검색해보니 35만원가량한다. VMWare의 웹사이트에서는 좀 더 저렴하다. 크게 비싼 가격은 아니고 또 트라이얼 버전을 다운로드 받을 수 있지만 개인적으로 사용하려 한다면 큰 제약이 없는 VirtualBox를 추천한다.


VirtualBox의 웹사이트를 방문하면 메인페이지에 "이 소프트웨어는 GNU GPL 버전2의 조건하에 자유로이 사용이 가능한 오픈소스 소프트웨어다."라고 씌여져 있다. 항상 GPL이니 LGPL이니하는 라이센스가 명시되어 있으면 무료인지 아닌지 모호해지는 경향이 있다.

하지만 어떤 경우라도 GUN GPL을 따르는 경우라면 이 소프트웨어를 이용해 돈을 벌고자하지 않고 나홀로 내 컴퓨터에서 사용하는 것까지 제지하지는 않는다.



사랑하는 GPL. ^^;


VirtualBox는 어떻게 생겼나?




리눅스가 설치된 호스트 컴퓨터에서 가상머신으로 동작하는 윈도우XP


뭐 VirtualBox가 어떻게 생겼는지가 중요한건가? 위 그림처럼 하나의 PC에서 호스트 컴퓨터와 게스트 컴퓨터(가상머신)가 동시에 돌아간다는 것이 중요한거다.

물론 위 그림과는 반대의 상황도 가능하다. 앞서 말했지만 우리나라에서는 대개 윈도우즈 운영체제를 사용하다보니 호스트 컴퓨터에는 윈도우즈가 설치되고 게스트 컴퓨터에는 리눅스 또는 OS X를 설치하는 경우가 더 많으리라.


VirtualBox, 다운로드 해 보자.


어찌됐건 말로 열번 설명하는 것보다 한 번 보는 게 낫고 열 번 보는 것보다 한 번 경험해 보는 게 제일 좋다. 시간이 좀 걸리겠지만 VirtualBox의 웹사이트를 통해 다운로드 해보고 설치도 해보고 또 다른 운영체제도 설치해서 동작시켜보자.


VirtualBox의 다운로드 주소는 https://www.virtualbox.org/wiki/Downloads이다.

위 주소로 이동한 후에 아래 그림과 같이 다운로드하면 된다. 내 PC의 운영체제가 윈도우즈라면 아래 그림에 표시된 것처럼 윈도우즈 호스트용 바이너리를 다운로드 받도록 하자.





'IT 정보' 카테고리의 다른 글

웹페이지의 반란, HTML5  (0) 2014.03.11
posted by 리치크루

API GUIDE/2. App Components
2014. 3. 18. 20:56

저작권 표시 : 

 

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

 

현재 보시는 페이지는 안드로이드 오픈 소스 프로젝트에 의해 작성되고 공유된 작업물의 수정/번역본이며 크리에이티브 커먼즈 저작자 표시 2.5 라이센스에 기술된 조건의 사용 근거를 따른 것입니다.

 

본 문서의 원본은 http://developer.android.com/guide/components/activities.html이며 안드로이드 4.4 Kitkat 기준으로 설명되었습니다.





액티비티 라이프사이클 관리하기(Managing the Activity Lifecycle)



액티비티의 라이프사이클을 관리할 때 관련 콜백 메서드를 사용하면 강력하면서도 유연한 어플리케이션을 개발할 수 있다. 액티비티의 라이프사이클은 액티비티와 연계되어 있는 또 다른 액티비티, 태스크, 백스택에 의해 직접적인 영향을 받는다.


액티비티는 기본적으로 다음의 3개 상황에 처할 수 있다.


리줌 상태(Resumed)

이 상태에 있는 액티비티는 화면의 제일 전면에 있으며 사용자의 포커스를 갖고 있다. (이 상황은 종종 "실행 중"이라 일컫어지기도 한다.)


일시 정지 상태(Paused)

다른 액티비티가 화면의 제일 전면에서 포커스를 받고 있지만 해당 이 상태에 있는 액티비티는 여전히 그 일부가 사용자에게 보여지고 있다. 즉, 다른 액티비티의 일부분이 투명하거나 화면 전체를 완전히 메울 정도로 크지 않아서 이 상태에 있는 액티비티의 일부분이 보여지고 있는 상태다. 일시 중지된 액티비티는 완전한 상태로 살아있다.(Activity 객체는 모든 상태와 멤버의 정보 데이터를 보존하며 메모리에 남아 윈도우 매니저에 속하게 된다.) 하지만 메모리가 극도로 부족해지면 시스템에 의해서 강제 종료될 수도 있다.


완전 정지 상태(Stopped)

액티비티가 다른 액티비티로 완전히 가리워진 상태다.(액티비티는 현재 "백그라운드"에 있는 상태다.) 정지된 액티비티는 아직 살아있다. (Activity 객체는 마지막 상태와 멤버들의 정보를 모두 유지한 채 메모리에 남아있다. 하지만 윈도우 매니저에는 속하지 않는다.) 하지만 사용자에게는 더 이상 보여지지 않고 있으며 다른 곳에서 메모리가 필요하게 되면 시스템은 액티비티를 강제종료 시킬 수도 있다.


액티비티가 일시 정지되거나 완전 정지되면 시스템은 액티비티에 종료를 요구하거나 (finish() 메서드를 호출한다.) 그냥 프로세스를 강제 종료시키게 된다. 액티비티가 다시 열리면 (그냥 종료되거나 강제 종료 된 후에) 모든 것을 다시 생성해야 한다.


라이프사이클 콜백함수 구현하기(Implementing the lifecycle callbacks)

액티비티가 위에서 언급한 상태들 중의 하나로 상태가 변경될 때에는 다양한 콜백 메서드를 통해 알림을 받게 된다. 다시 말해, 액티비티의 상태 변화가 일어날 때 적절한 작업을 수행할 수 있는 콜백 메서드가 제공된다. 아래 코드는 액티비티의 기본적인 라이프사이클 메서드에 대한 예제다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class ExampleActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // The activity is being created.
    }
    @Override
    protected void onStart() {
        super.onStart();
        // The activity is about to become visible.
    }
    @Override
    protected void onResume() {
        super.onResume();
        // The activity has become visible (it is now "resumed").
    }
    @Override
    protected void onPause() {
        super.onPause();
        // Another activity is taking focus (this activity is about to be "paused").
    }
    @Override
    protected void onStop() {
        super.onStop();
        // The activity is no longer visible (it is now "stopped")
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // The activity is about to be destroyed.
    }
}
 


Note : 위 예제처럼 라이프사이클 메서드를 구현할 때는 어떤 작업을 수행하기 전에 부모클래스의 메서드를 먼저 호출해야 한다.


이 메서드들은 액티비티의 모든 라이프사이클에 관련되어 있다. 이 메서드들을 구현하게 되면 아래와 같은 액티비티 라이프사이클의 루프를 모니터링 해 볼 수 있다.


액티비티의 전체 라이프타임(entire lifetime)onCreate() 호출 시점 이후부터 onDestroy() 호출 시점 이전까지를 말한다. 액티비티는 onCreate() 메서드에서 (레이아웃 정의와 같은) 모든 준비를 완료해야 하며 onDestroy() 메서드에서는 남아 있는 모든 리소스를 해제시켜야 한다. 만일 액티비티에 네트워크로부터 데이터를 다운로드 받는 쓰레드가 동작하도록 되어 있다고 하면 onCreate()에서 쓰레드를 생성하고 onDestroy()에서 정지시켜야 한다.


액티비티의 비저블 라이프타임(visible lifetime)onStart() 호출 시점 이후부터 onStop() 호출 시점 이전까지를 말한다. 이 시간동안 사용자는 액티비티를 볼 수 있으며 소통할 수 있다. 예를 들어, 새로운 액티비티가 시작되면 onStop()이 호출되고 해당 액티비티는 더 이상 보여지지 않게 된다. onStart()가 호출될 때부터 onStop()이 호출될 때까지 사용자에게 액티비티를 보여주기 위해 필요한 리소스를 유지시킬 수 있다. 예를 들어, UI에 영향을 줄 만한 변화를 감지하기 위해 onStart()에서 BroadcastReceiver를 등록하고 사용자에게 UI를 더 이상 보여줄 필요가 없어지면 onStop()에서 등록을 해지할 수 있다. 사용자가 액티비티를 "보았다 안보았다"를 반복할 수 있기 때문에 액티비티의 전체 라이프타임 동안 onStart()와 onStop()은 여러 번 반복해서 호출될 수도 있다.


액티비티의 포어그라운드 라이프타임(foreground lifetime)onResume() 호출 시점 이후부터 onPause() 호출 시점 이전까지를 말한다. 이 라이프타임에서는 액티비티가 다른 어떤 액티비티보다도 화면의 맨 앞에 위치하게 되며 사용자의 입력을 받을 수 있게 된다. 액티비티는 자주 이 상태에 진입하기도 하고 빠져나가기도 한다. 기기가 슬립모드로 전환되거나 다이얼로그가 앞에 나오는 상황이 되면 액티비티는 이 라이프타임에서 빠져나가게 되며 반대로 슬립모드가 해제되거나 다이얼로그가 사라지면 다시 이 라이프타임으로 진입하게 된다. 이 라이프타임은 다른 라이프타임에 비해 매우 빈번하게 상태 변화가 일어나기 때문에 프로그램이 느려지지 않도록 하려면 onResume()onPause()를 매우 간단한 작업만 하도록 구현해야한다.


[그림 1]은 위의 3가지 루프와 액티비티의 상태변화가 어떤 순서로 일어나는지에 대해서 설명하고 있다.



그림 1. 액티비티의 라이프사이클



아래 [표 1]에서는 위 그림에 표시된 콜백 메서드들에 대한 좀 더 상세한 설명과 각 콜백 메서드가 액티비티의 라이프사이클 루프 중 어디에 속하는지 그리고 호출된 후에 액티비티가 강제 종료될 가능성이 있는지에 대해서 설명한다.


표 1. 액티비티 라이프사이클 콜백 메서드 요약

메서드명

 설명

호출 후

강제종료?

음 메서드

onCreate()

액티비티가 처음 생성되면 호출된다. 이메서드에서 뷰 생성이나 변수의 초기화 같은 셋업작업이 이루어져야 한다. 만일 이전에 실행되었을 때 마지막 상태가 저장되어 있었다면 (뒤에 나오는 액티비티 상태 저장하기(Saving Activity State) 참고) 이 메서드에 액티비티의 이전 상태에 대한 정보를 갖고 있는 Bundle 객체가 파라메터로 넘어온다.

이 메서드 다음에는 항상 onStart()가 실행된다.

아니오

onStart()

 

onRestart()

액티비티가 완전 정지 되었다가 다시 시작되기 바로 전에 호출된다.

이 메서드 다음에는 항상 onStart()가 실행된다.

아니오

onStart()

 

onStart()

액티비티가 사용자에게 보여지기 직전에 호출된다. 액티비티가 전면에 보여질거라면 다음에 onResume()이 호출되며 숨겨질거라면 다음에 onStop()이 호출된다.

아니오

onResum()
또는
onStop()

 

 

onResume()

액티비티가 사용자와 소통을 시작하기 바로 전에 호출된다. 이 시점에서 액티비티는 액티비티 스택의 최정점에 위치하게 되며 사용자의 입력을 받게 된다.

다음에 항상 onPause()가 호출된다.

아니오

onPause()

 

 

onPause()

시스템이 다른 액티비티를 막 재개하려고 할 때 호출된다. 이 메서드는 저장되지 않은 정보를 저장하거나 애니메이션처럼 CPU를 사용하는 작업을 중지할 때 사용된다. 이 메서드가 완료되어야만 다음 액티비티가 재개될 수 있기 때문에 이 메서드에서는 무슨 작업이 되었건 빠르게 수행하고 리턴해야한다.

액티비티가 다시 재개되느냐, 중지되느냐에 따라 다음 실행될 메서드는 onResume()이 될 수도 있고 onStop()이 될 수도 있다.

onResum()

또는
onStop()

 

onStop()

액티비티가 사용자에게 더 이상 보여지지 않게 되면 호출된다. 이 메서드는 액티비티가 파괴될 때나 다른 액티비티에 의해서 완전히 가리워질 때 발생한다.

사용자가 다시 이 액티비티를 불러내게 되면 다음 실행될 메서드는 onRestart()가 호출되며 그대로 액티비티가 종료된다면 onDestroy()가 호출된다.

onRestart()
또는
onDestroy()

onDestroy()

액티비티가 파괴되기 전에 호출된다.

액티비티가 수행할 수 있는 마지막 메서드다. 액티비티가 종료되거나(어디선가 finish()가 호출되거나), 메모리 부족으로 시스템이 액티비티를 강제 종료할 때 호출된다. 이 두가지의 호출상황은 isFinishing() 메서드로 구분이 가능하다.

없음.


"호출 후 강제종료?"라고 된 열은 말 그대로 시스템이 액티비티를 순간 강제 종료시킬 가능성이 있는지를 나타낸다. 3개 메서드가 "예"라고 표시되어 있다(onPause(), onStop(), onDestroy()). onPause()는 액티비티가 생성된 이후 3개의 메서드 중에서 첫번째 메서드이기 때문에 프로세스가 강제 종료될 때에도 수행이 보장되는 마지막 메서드다. 만일 시스템이 긴급하게 메모리를 확보해야 한다면 나머지 2개의 메서드(onStop(), onDestroy())는 반드시 수행된다고 보장하기는 어렵다. 따라서 사용자가 수정했다던가 하는 중요한 데이터는 onPause()에서 저장해 두어야 한다. 그러나 onPause()에서 보관해야하는 데이터에 대해서는 어느 정도 선별이 필요하다. onPause()가 수행을 종료해야만 다음 액티비티로의 상태 전환이 이루어지기 때문에 과도한 작업을 수행하면 사용자 경험이 느려지게 된다.


"강제 종료" 항목이 "아니오"라고 표시된 메서드들은 수행 중 프로세스가 강제 종료 되지 않도록 보호가 된다. 그래서 액티비티는 onPause()가 리턴되고 onResume()이 호출되기 전까지 강제 종료가 가능한 상태가 되며 onPause()가 다시 호출되고 리턴될 때까지 강제 종료의 대상에서 제외된다.


Note : [표 1]에서 강제 종료 여부가 "아니오"라고 표시되어 있다고 하더라도 시스템에 의해서 강제 종료될 수 있다. 더 이상 시스템 자원이 없는 극한의 상태가 된다면 강제 종료될 수도 있다. 액티비티가 강제 종료되는 상황에 대해 더 많은 정보가 필요하다면 Processes and Threading 문서를 참조하기 바란다.


액티비티 상태 저장하기(Saving activity state)

액티비티 라이프사이클 관리하기(Managing the Acitivity Lifecycle)의 소개 부분에서 액티비티가 일시 정지(pause)되거나 완전 정지(stop)될 때 액티비티의 상태가 유지되는 것에 대해 간략히 언급하였다. 액티비티가 일시 정지되거나 완전 정지되어도 Activity 오브젝트는 여전히 메모리에 로드되어 있는 상태이기 때문에 모든 멤버의 정보나 마지막 상태 정보도 모두 유지된다. 그래서 액티비티가 다시 화면의 맨 앞으로 나오게 되면(resume 될 때) 모든 정보가 그대로 남아있게 된다.


그러나 시스템이 메모리를 확보하기 위해 액티비티를 파괴하게 되면 시스템이 다시 액티비티를 복원(resume)시켜 간단히 원래 상태로 돌아올 수가 없다. 대신에 사용자가 다시 그 액티비티로 돌아가려고 하면 시스템은 액티비티 오브젝트를 다시 생성시킨다. 하지만 사용자는 시스템이 액티비티를 파괴하고 재생성한 일은 알지 못하기 때문에 마지막에 보았던 상태 그대로 유지되어 있을 것으로 생각한다. 이런 상황에서는 onSaveInstanceState()라는 또다른 콜백 메서드를 구현하여 액티비티의 중요한 정보를 유지시킬 수 있다.


시스템은 액비티티가 파괴되기 전에 onSaveInstanceState()를 호출한다. 시스템은 이 메서드를 호출할 때 액티비티의 상태 정보를 저장할 수 있도록 Bundle이라는 것을 넘겨준다. BundleputString()putInt()와 같은 메서드(리치크루 : 이 이름의 메서드들 외에 다른 메서드들도 있다.)를 사용하여 이름과 값이 짝을 이루는 형태(name-value pair)로 정보를 저장할 수 있다. 이후에 시스템이 어플리케이션 프로세스를 파괴하고 사용자가 다시 되돌아오는 상황이 발생하면 시스템은 액티비티를 재생성하고 onCreate()onRestoreInstanceState()에 Bundle을 넘겨준다. 이 두 개의 메서드를 사용하면 onSaveInstanceState()에서 저장한 상태 정보를 Bundle에서 추출하여 액티비티의 상태를 복구할 수 있다. 만일 복구해야할 정보가 없다면 Bundlenull값으로 넘어온다(액티비티가 처음 생성될 때 이런 상황이 된다.).


그림 2. 온전한 상태로 사용자 포커스를 다시 얻게되는 두 가지 상황.
(1) 액티비티가 파괴되고 재생성될 때 이전에 저장된 상태를 복구하거나
(2) 액티비티가 정지되었다가 복원(resume)되면 상태가 온전하게 유지된다.


Note : onSaveInstanceState() 메서드는 액티비티가 파괴되기 전에 반드시 호출되는 것은 아니다. 상태 정보를 저장할 필요가 없는 경우도 있기 때문이다. 예를 들어, 사용자가 "뒤로"버튼을 눌러서 액티비티를 종료하는 것은 사용자에게 명백하게 종료 의도가 있는 것이기 때문에 onSaveInstanceState()가 호출되지 않는다. 시스템이 onSaveInstanceState()를 호출하는 시점은 onStop()전이나 onPause()전일 수 있다.


그러나 onSaveInstanceState() 메서드에서 아무런 작업을 하지 않거나 심지어 이 메서드를 구현하지 않아도 Activity 클래스에서 기본적으로 구현해 놓은 onSaveInstanceState()가 일부 액티비티의 상태를 복구해 준다. 구체적으로 설명하자면 레이아웃에 있는 View들이 저장할 필요가 있는 정보를 저장할 수 있도록 각 View의 onSaveInstanceState() 메서드를 호출해 준다. 안드로이드 프레임워크에 있는 거의 대부분의 위젯은 시각적으로 보여지는 내용의 변화는 재생성될 때 다시 복구할 수 있도록 자체적으로 적절한 메서드를 구현하고 있다. 예를 들어, EditText는 사용자가 입력한 텍스트를 저장하며 CheckBox는 체크된 상태를 저장한다. 각 위젯이 이렇게 자동으로 상태를 저장할 수 있도록 하기 위해 해야할 일은 각 위젯에 유니크ID를 부여하는 것이다.(android:id 속성 사용) 위젯이 ID를 갖지 않는다면 시스템은 위젯의 상태를 저장할 수가 없다.


레이아웃에 있는 뷰가 상태를 저장하지 않도록 하려면 android:saveEnabeld 속성을 "false"로 설정하거나 setSaveEnabled() 메서드를 호출하면된다. 일반적으로 액티비티의 상태를 다른 방법으로 복구할 게 아니라면 이 항목을 해제시켜서는 안된다.

이렇게 액티비티의 상태를 자동으로 저장하도록 기본 onSaveInstanceState() 메서드가 구현되어 있긴 하지만 다른 추가적인 정보를 저장하기 위해서 이 메서드를 오버라이드 해야 할 수도 있다. UI외에도 UI와 연결되어 있는 멤버 변수들은 자동으로 저장되고 복구되지 않기 때문에 직접 onSaveInstanceState() 메서드를 구현해 줘야 한다.


기본적으로 구현되어 있는 onSaveInstanceState() 메서드는 UI의 상태를 저장해주고 있기 때문에 추가정보를 저장하기 위해서 메서드를 오버라이딩하려면 다른 작업을 하기 전에 항상 부모클래스의 onSaveInstanceState()를 먼저 호출해야 한다. 같은 맥락으로 onRestoreInstanceState()를 구현할 때도 부모클래스의 메서드를 먼저 호출해야만 UI의 상태가 복구된다.


Note : onSaveInstanceState() 는 반드시 호출된다고 보장할 수 없기 때문에 액티비티의 일시적 데이터(UI의 상태)를 저장할 때만 사용해야 하며 영구적으로 저장해야 할 때는 사용해선 안된다. 대신 사용자가 액티비티를 떠날 때에 (데이터베이스에 저장하는 것과 같이) 영구적으로 보관해야 하는 데이터는 onPause()에서 저장해야만 한다.


여러분이 만든 앱이 상태를 얼마나 잘 복구하는지 확인해 보려면 그냥 기기를 돌려서 화면이 회전되도록 해보면 된다. 화면의 방향이 바뀌면(가로방향에서 세로방향으로 또는 세로방향에서 가로방향으로) 시스템은 다른 방향의 레이아웃에 맞는 대체 자원을 적용시키기 위해서 액티비티를 파괴하고 새로 생성한다. 사용자들은 앱을 사용하면서 화면을 회전시키는 경우가 빈번하기 때문에 이런 상황 하나만으로도 액티비티가 파괴되고 재생성될 때 UI의 상태를 저장하고 복구하는게 얼마나 중요한지 알 수 있다.


설정 변화 핸들링하기(Handling configuration changes)

기기의 설정 일부는 실행 도중에 변경될 수도 있다(화면 방향, 키보드 설정, 언어 등과 같은 설정들). 이런 것들이 변경되면 안드로이드는 실행 중인 액티비티를 재생성하게 된다(시스템은 onDestroy()를 호출하고 바로 onCreate()를 호출한다.). 이렇게 하는 이유는 프로그램 작성자가 제공한 리소스들을 변경된 설정에 맞게 자동으로 다시 적용시키기 위해서다(예를 들어, 가로화면과 세로화면에 맞는 레이아웃을 따로 만들어 두었다면 사용자가 기기를 회전시켰을 때 그에 맞는 레이아웃을 다시 적용시키는 것이다.).


만일 위헤서 설명한 대로 화면의 방향이 바뀌고 그에 따라 액티비티의 상태가 복구될 수 있도록 프로그램을 작성했다면 그 앱은 액티비티의 라이프사이클 도중에 예상치 못한 상황에도 좀 더 유연해지게 된다.


이렇게 재시작되는 상황을 잘 대처하기 위해서는 앞서 설명한대로 onSaveInstanceState()에서 액티비티의 상태를 저장하고 onRestoreInstanceState()(또는 onCreate())에서 복구되도록 하는 것이 최선의 방법이다.


실행 중에 발생하는 설정 변경과 그에 대한 처리 방법에 대해 좀 더 알고 싶다면 Handling Runtime Changes를 참고하기 바란다.


액티비티간 콜백 메서드의 수행 순서(Coordinating activities)

어떤 액티비티가 다른 액티비티를 구동시키면 두 액티비티는 모두 라이프사이클의 상태 변화가 생긴다. 처음 액티비티는 일시정지(pause)된 후에 완전정지(stop)되며 (물론 액티비티가 뒤쪽에서 조금이라도 보이게 되면 안전정지(stop)되지는 않는다.) 반면에 다른 액티비티는 생성(create)이 된다. 이런 경우 이 두 개의 액티비티가 디스크나 다른 곳에 데이터를 저장하여 서로 정보를 공유하는 방식을 사용한다면, 두 번째 액티비티가 생성되기 전에 첫번째 액티비티는 완전하게 정지되지 않는다는 사실을 반드시 알고 있어야 한다. 좀 더 정확히 얘기하면 두번째 액티비티를 생성하는 프로세스와 첫번째 액티비티를 정지하는 프로세스가 겹쳐져서 수행된다는 말이다.


라이프사이클 콜백 메서드의 순서, 특히 같은 프로세스에서 하나의 액티비티가 다른 액티비티를 구동할 때의 순서는 명확하게 정해져 있다. 다음은 액티비티A가 액티비티B를 구동시킬 때의 동작 순서를 나열한 것이다.


  1. 액티비티A의 onPause() 메서드가 실행된다.
  2. 액티비티B의 onCreate(), onStart(), onResume()이 순서대로 실행된다.(액티비티B가 사용자 포커스를 받게 된다.)
  3. 이제 액티비티A가 화면에서 더 이상 보이지 않게 되면 onStop() 메서드가 실행된다.


이러한 라이프사이클 콜백 메서드의 순서를 참고하면 하나의 액티비티에서 다른 액티비티로 정보가 옮겨지는 것을 문제없이 수행할 수 있다. 예를 들어, 다음 액티비티에서 읽어내야 할 데이터를 첫번째 액티비티가 데이터베이스에 써 놓아야 한다면 onStop() 대신에 onPause()에서 데이터베이스 쓰기 작업을 수행해야만 한다.

posted by 리치크루

IT 정보
2014. 3. 11. 22:05




웹페이지의 반란, HTML5

최근 "HTML5"란 단어를 많이 듣게 되었다.


내가 이 쪽에 관심이 생긴건 지, 아니면 정말 사람들의 입에 많이 오르내리기 때문인지는 모르겠다.


이유야 어찌되었건 궁금하니까 뭔지 개념이라도 알아 보자.



HTML5가 대체 뭐길래?


찾아보니 이름 자체부터 그다지 대단한 느낌은 아닌 듯 하다.

(HTML5 무시했다고 악플달고 그러지는 않겠지... 설마... ㅡㅡ; )


그냥 지금까지 우리가 주욱~ 써오던 HTML(Hyper-text markup language; 하이퍼 텍스트 마크업 언어)의 버전 5.0이란다.


즉,  지금 까지의 HTML과 전~~~혀 다른, 혁신적인 것은 아니란 얘기다. 그냥 발전된 형태일 뿐이다.


그럼 "하이퍼 텍스트 마크업 언어"는 뭘까? 아주 간략하게 설명하자면 그냥 여러 문서를 링크로 엮어 놓는 방법을 적어놓은 것이다.


그런데 왜 이런 언어에 왜 규칙이 필요한 걸까? 게다가 버전번호까지 붙여가며 관리도 한다. 도대체 왜???




[대표적인 웹 브라우저(인터넷 익스플로러, 파이어폭스, 크롬, 사파리)]

근데 왜 사람들은 IE를 싫어하는 걸까? 운영체제에 끼워팔기해서? 그러면서도 전세계에서 가장 많이 사용된다.



HTML의 규칙이 필요해?
(이유는 인터넷 검색결과와 지극히 개인적인 생각을 섞어 놓았다. 뭐 서로에게 득이되는 태클은 일단 환영하옵니다.)


필요하니까 규칙을 정하는거다. 하지만 HTML은 강제성을 갖지 않는다. 다만 권고사항일 뿐이다.


예를 들어, 마이크로소프트의 인터넷 익스플로러에서는 잘 보이던 페이지가 구글의 크롬에서는 이상하게 보인다거나 그 반대의 상황이 가끔 있다. 이런 문제가 발생하는 건 마소건 구글이건 완벽하게 HTML의 규칙을 지키지 않았다는 거다.


웹페이지 작성자 입장에서는 공들여 만든 페이지를 어떤 사람들이 못보게 된다면 속상한 일이 아닐 수 없다. 반대로 웹브라우저의 제작자 입장에서는 일정한 규칙이 없다면 이런 상황, 저런 상황을 다 고려하여 프로그램을 작성하기가 매우 어렵게 된다.


그래서 규칙을 정하는 거다. 참 당연한 거지만 웹페이지 작성자도, 웹브라우저 제작자도 100% HTML의 규칙을 따르지 않는다. 심지어 나까지도.






HTML, 왜 버전이 필요한가?
(이 역시도 개인적인 생각이다.)


앞에서 말한 규칙을 정해놓는다는 건 정해진 틀에서 벗어나면 안된다는 거다. 규칙에서 똭~! 정해놓은 기능만 써야한다.


그런데 그렇게 정해놓자니 자꾸만 자꾸만 새로운 기능의 요구가 생겨나게 된다.


처음에는 글씨만으로 문서를 만들어도 만족하더니 시간이 지나니까 그림도 집어넣을 필요가 있게 됐다.


배경음악도 깔았으면 좋겠고


동영상도 넣었으면 좋겠다.


그러더니 이번에는 보여주는 것만이 아니라 보는 사람이 무슨 생각을 하는지 알고 싶어진거다.


이런 식의 요구를 계속 수용하면서 HTML은 업데이트 되었고 결국에는 버전 5.0의 발표를 코앞에 두게 되었다.



[이곳을 방문해봅시다.]



그럼 누가 HTML의 버전을 정하는건가?


W3C는 약 400 개에 달하는 회원 조직들과 70명 이상의 정규직 직원들로 이루어진 국제 컨소시엄이다.

일반 개인이나 회사가 운영하는 것이 아니라 여러 사람이나 조직이 모여 협의하는 비영리 단체다.

W3C에서 HTML의 규칙을 정하기 때문에 당연히 규칙에 대한 문서가 제공된다. 아주 자세히!

기본부터 공부해보겠다 그리고 영어 독해에 자신있다 하는 분들은 HTML을 공부하기 위해 강좌사이트나 서적을 찾아 헤메일 필요가 없다.

W3C의 홈페이지에서 제공하는 문서로 공부하면 된다.

HTML 4.01의 명세에 대해서 보고 싶다면 http://www.w3.org/TR/html401/를 방문하면 된다.

ㅋㅋㅋ 영어라서 머리 아프다. 그럼 한글로 된 사이트(http://trio.co.kr/webrefer/html/cover.html)를 방문해도 된다.
(한글로!? 이렇게 고마울 수가... 거기다가 공짜로... 이거 어쩌나 뽀뽀라도 해드려야되나?)

W3C에서는 HTML의 표준만 정하는 것이 아니다. 글을 쓰는 나도 확실히 모르는 CSS, DOM, HTTP등에 대한 표준도 함께 정하고 있다.

앞서 HTML의 명세를 W3C에서 정했다고 말했다. 그! 러! 나!  HTML5는 기존과 그 출발이 약간 다르다.

웹 브라우저 제작자들과 사용자들은 W3C가 최근 인터넷에서의 요구를 반영하는 새로운 명세를 채택해 주기만을 기다려왔다.

하지만 W3C가 엉뚱한 짓만 하고 있자. 일부 웹 브라우저의 제작사들이 뭉쳐 WTATWG(Web Hypertext Application Technology Working Group)라는 조직을 만들고 논의를 거쳐 자체적으로 HTML5의 명세를 만들기 시작했다.
(거~ 참. 이름도 길고 뭐라고 읽어야될지도 모르겠다. '더블유 티 에이 티 더블유 쥐'... ㅡㅡ; 이건 약자로 쓰나마나 아님?)

그리고 그걸 지켜보던 W3C. 결국엔 숟가락을 얹었다. 그리고 HTML5의 공식 발표를 앞두고 있다.






HTML5의 새로운 특징

기존의 HTML은 화려한 이펙트나 특정 기능을 수행하도록 하기 위해서 사실 조금 모자랐다.


정적인 언어였다. 하지만 그런 단점을 보완하기 위해서 JavaScript, ActiveX, Flash, Applet등의 기술을 사용해왔다.


이런 기술들은 늘상 써오는 사람들에게는 별 것 아닐지 몰라도 컴퓨터에 지식이 부족한 일반인들에게는 다른 나라 이야기처럼 들린다.


하지만 HTML5에서는 다른 기술들의 사용을 최소화하면서도 동등한 기능을 구현할 수 있도록 하고 있다.

(이건 뭐 더 두고봐야 알겠지만.)


HTML5의 새로운 기능은 다음과 같다.

  • 새로운 엘리먼트(<p>, <table> 같은 것들)
  • 새로운 속성(href, src, style등과 같이 엘리먼트의 안에 함께 표기되는 것들)
  • 완벽한 CSS3 지원
  • 비디오와 오디오 지원
  • 2D/3D 그래픽
  • 로컬 저장소
  • 로컬 SQL 데이터베이스
  • 웹 어플리케이션

(옮겨 쓰긴 했지만 일부는 어떻게 하겠다는 건지...)



HTML5, 결국은 이거다.

쉽게 얘기하면 이렇다.


이런 저런 외부기능은 최대한 안쓰고 HTML안에서 다 해결하자.


결국 기존의 웹문서는 작성자가 작성하고 방문자는 그냥 작성자가 작성한대로 보여주는 것이 전부였다.

(순수하게 HTML 코드로 작성된 문서일 때 그렇다는 것이다.)


하지만 HTML5는 사용자의 행동에 반응하고 그 결과를 저장할 수도 있다.


가장 쉽게 이해할 수 있는 것이 웹 오피스다.


예전에는 인터넷상에서 오피스를 쓰려면 액티브X를 쓰거나 자바 애플릿을 쓰거나 했다.


하지만 구글드라이브에서 지원하는 오피스를 보면 그런 것 없이도 문서를 작성하고 이미지도 드래그앤드랍이 가능하며 심지어 내 컴퓨터에 파일로 저장할 수도 있다.


더구나 어디서 들은 말로는 HTML5만 가지고도 게시판도 만들 수 있다더라.


현재 메이저 웹 브라우저들은 HTML5를 상당부분 지원한다. 아직 정식으로 발표되진 않았지만 여러분이 이미 경험한 서비스 중에도 HTML5가 존재하고 있다.


웹브라우저의 HTML5의 지원 정도가 궁금하다면 http://html5test.com를 참고하기 바란다.



[각 웹 브라우저(최신버전)별 HTML5 기능 지원 점수(만점은 555점)]

http://html5test.com/compare/browser/chrome-33/firefox-27/opera-19/safari-7.0/ie-11.html



하지만 위 이미지처럼 아직까지 완벽하게 HTML5를 지원하는 웹브라우저는 없다.


그 중에 가장 괜찮은 놈이 구글의 크롬이다. 그리고 인터넷 익스플로러는... 에휴~ 그나마 최신 버전이 이 정도가 되고 우리나라에서 가장 많이 사용되는 IE7, 8은 100점에도 미치지 못한다.

(IE7, 8은 차라리 'HTML5를 지원하지 않는다'고 말하는 게 속편하겠다.)


하긴 아직 HTML5의 명세가 확정된 것도 아니고 지금도 계속 수정이 이루어지고 있기 때문에 100% 지원하기를 바라는 것도 무리이긴 하다.


따라서, 아직까지 HTML5를 적극 애용하여 웹사이트를 꾸미는 일은 시기상조가 아닐까한다.

'IT 정보' 카테고리의 다른 글

내 컴퓨터 안의 또다른 컴퓨터 - VirtualBox  (0) 2014.03.19
posted by 리치크루

API GUIDE/2. App Components
2014. 3. 4. 22:13

저작권 표시 : 

 

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

 

현재 보시는 페이지는 안드로이드 오픈 소스 프로젝트에 의해 작성되고 공유된 작업물의 수정/번역본이며 크리에이티브 커먼즈 저작자 표시 2.5 라이센스에 기술된 조건의 사용 근거를 따른 것입니다.

 

본 문서의 원본은 http://developer.android.com/guide/components/activities.html이며 안드로이드 4.4 Kitkat 기준으로 설명되었습니다.






액티비티 개요(Activities)


Activity는 전화 걸기, 사진 찍기, 이메일 보내기, 맵 보기등과 같이 사용자가 뭔가 하려고 할 때 앱과 상호작용 할 수 있도록 화면을 제공하는 앱 컴포넌트다. 각 액티비티에는 UI를 그려넣을 수 있는 윈도우가 주어진다. 윈도우는 일반적으로 화면을 가득 메우지만 화면보다 작아서 다른 위도우의 위에 떠 있도록 할 수도 있다.


어플리케이션은 보통 서로 관계가 느슨한 여러 개의 액티비티로 구성되어 있다. 일반적으로 하나의 액티비티가 "main"액티비티로 지정이 되고 앱이 실행될 때 제일 처음 사용자에게 보여진다. 그리고나서 각 액티비티는 상황에 따라 다른 동작을 수행할 액티비티를 시작시킨다. 새로운 액티비티가 시작될 때마다 먼저번의 액티비티는 일시정지(pause)되고 시스템은 그 정지(stop)된 액티비티를 그대로 스택(백 스택; back stack)에 쌓아놓는다. 그리고 새로운 액티비티가 시작되면 백 스택에 푸시되고 포커스를 갖게 된다. 백스택은 스택의 기본 개념인 "Last In, First Out" 메커니즘을 따르기 때문에 사용자가 현재 액티비티에서 작업을 마치고 "뒤로"버튼을 누르면 스택의 마지막 액티비티는 스택에서 꺼내어지고 (그리고 파괴된다.) 이전의 액티비티가 복원이 된다. (한마디로 스택의 마지막 액티비티가 화면의 최전면에 표시되고 포커스를 갖게 되며 스택에서 꺼내지면 소멸된다. 백 스택은 Tasks and Back Stack에서 좀 더 자세히 논의된다.)


새로운 액티비티가 시작되어 현재 액티비티가 중지될 때, 이 변화된 상태는 액티비티의 라이프사이클 콜백 메서드를 통해 알려지게 된다. 상태변화(생성될 때, 정지될 때, 다시 복원될 때, 파괴될 때)를 알려주는 액티비티 콜백 메서드는 몇 종류가 있는데 이 메서드들은 상태 변화시에 앱이 특정 작업을 할 수 있는 기회를 제공하게 된다. 예를 들어, 액티비티가 정지되면 네트워크나 데이터베이스 연결 오브젝트 같은 덩치가 큰 오브젝트를 해제할 수도 있다. 액티비티가 정상 가동되면 해당 자원을 다시 획득할 수 있고 중단됐던 작업을 재개할 수 있다. 이런 상태의 변화는 액티비티 라이프사이클 전반에 걸쳐 발생된다.


이 문서에서는 (액티비티의 라이프사이클이 어떻게 동작하는 지를 포함해서) 액티비티를 만들고 사용하는 법에 대해 논의한다. 그래서 여러분이 다양한 액티비티의 상태 변화를 적절히 다룰 수 있도록 한다.



액티비티 생성하기(Creating an Activity)



액티비티를 생성하기 위해서는 Activity 클래스(또는 이미 존재하는 Activity의 서브클래스)의 서브클래스를 생성해야 한다. 서브클래스에서는 액티비티가 생성되고, 정지, 복귀, 파괴되는 등의 다양한 상태변화를 알려주는 콜백 메서드를 구현해야 한다. 가장 중요한 콜백 메서드는 다음의 2개다.


onCreate()

이 메서드는 반드시 구현해야 한다. 시스템은 액티비티가 생성될 때 이 메서드를 호출한다. 기본적인 컴포넌트의 초기화를 이 메서드에서 구현한다. 이메서드를 구현할 때 가장 중요한 것은 액티비티의 UI를 위한 레이아웃을 반드시 setContentView()를 통해 정해줘야 한다.


onPause()

시스템은 사용자가 액티비티를 떠날 때 가정 먼저 이 메서드를 호출한다.(이 메서드가 호출되었다고는 해도 액티비티가 항상 파괴되는 것을 의미하지는 않는다.) 이 메서드는 사용자가 현재 세션에서 떠날 때 (사용자가 다시 돌아오지 않고 프로세스가 종료될 수 있기 때문에) 영구보존해야 하는 정보를 저장해야 하는 곳이다.


라이프사이클 콜백 함수는 여러 종류가 있다. 액티비티 간의 UI를 적절하게 제공하고 액티비티가 정지되거나 심지어는 파괴되는 갑작스런 상황에도 대응하기 위해서는 이 콜백 메서드들을 활용해야만 한다. 모든 라이프사이클 콜백 메서드는 뒤쪽 섹션(액티비티 라이프사이클 관리하기; Managing the Activity Lifecycle)에서 더 자세히 다룬다.


UI 구현하기(Implementing a user interface)

액티비티의 UI는 View 클래스로부터 파생된 뷰콘트롤들로 만들어진다. 각 뷰콘트롤들은 액티비티의 윈도우 안에서 일정 부분의 직사각형 영역을 차지하고 동작하며 사용자와 상호작용을 하도록 되어 있다. 예를 들어, 버튼 뷰는 사용자가 터치하면 특정 동작을 시작하게 된다.


안드로이드는 레이아웃을 디자인하고 꾸밀 수 있도록 많은 뷰콘트롤들을 제공한다. "위젯"은 버튼, 텍스트 필드, 체크 박스 또는 이미지 같이 사용자에게 보여지고 입력을 처리하는 뷰콘트롤들이다. "레이아웃"은 ViewGroup을 상속받은 뷰이며 linear 레이아웃, grid 레이아웃, relative 레이아웃과 같이 각각 다른 레이아웃 모델을 제공한다. ViewViewGroup 클래스를 상속받거나 또는 상속받아 만들어진 기존의 클래스를 다시 상속받아 나만의 새로운 위젯과 레이아웃을 만들어서 액티비티 레이아웃에 사용할 수도 있다.


뷰를 사용하여 레이아웃을 만드는 가장 일반적인 방법은 앱리소스에 저장된 XML 레이아웃 파일을 이용하는 것이다. 이 방법을 사용하면 디자인과 소스코드를 분리하여 관리할 수 있다. 이렇게 만들어진 레이아웃은 레이아웃의 리소스ID를 setContentView()에 넘겨 액티비티의 UI로 사용할 수 있다. 그러나 액티비티의 코드안에서 새로운 View를 만들고 ViewGroup에 집어넣을 수도 있다. 그런 후에 최상위 ViewGroupsetContentView() 메서드에 넘겨 사용할 수 있다.


UI를 만드는 법은 User Interface 문서를 참고하기 바란다.


매니페스트에 액티비티 선언하기(Declaring the activity in the manifest)

만들어둔 액티비티가 시스템에서 액세스가 가능하도록 하려면 manifest 파일에 반드시 선언을 해 주어야 한다. 액티비티를 선언하려면 아래 예제처럼 <application> 엘리먼트의 내부에 <activity> 엘리먼트로 선언한다.


1
2
3
4
5
6
7
<manifest ... >
  <application ... >
      <activity android:name=".ExampleActivity" />
      ...
  </application ... >
  ...
</manifest >
 


이 엘리먼트에는 액티비티의 레이블, 아이콘, 테마 스타일 같은 속성을 정의하기 위한 몇몇 속성들이 있다. android:name 속성은 액티비티의 클래스명만 입력해 주면 된다. 일단 앱을 게시하고나면 앱의 숏컷과 같은 기능이 제대로 동작하지 않는 문제가 발생하기 때문에 이 이름은 바꿔줄 수가 없다. (이 문제에 대한 내용은 블로그의 Things That Cannot Change 포스트를 읽어보기 바란다.)


매니페스트에 액티비티를 선언하는 법에 대해 좀 더 자세히 알고 싶으면 <activity> 엘리먼트의 도움말을 참고하기 바란다.


인텐트 필터 사용하기(Using intent filters)

다른 앱에서 액티비티를 활성화시킬 수 있도록 하기 위해서 - <intent-filter> 엘리먼트를 사용하여 - 다양한 인텐트 필터를 <activity> 엘리먼트의 아래에 둘 수 있다.


안드로이드 SDK 툴을 사용하여 새로운 앱을 생성하면 텅빈 액티비티가 자동으로 생성된다. 이 액티비티는 "main" 액션과 "launcher" 카테고리를 나타내는 인텐트 필터가 자동으로 추가되어 있다. 인텐트 필터를 다음과 같이 생성된다.


1
2
3
4
5
6
<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
 


위 예제에서는 <action> 엘리먼트는 이 액티비티가 어플리케이션의 "주"진입점임을 선언하고 있으면 <category> 엘리먼트는 이 액티비티가 시스템의 앱 런처(사용자가 액티비티를 시작할 수 있도록 하는) 목록에 표시되도록 선언하고 있다.


만일 다른 앱에서 액티비티를 활성화시키는 것을 막고자 한다면 다른 인텐트 필터는 필요없다. 위 예제처럼 오직 하나의 액티비티만 "main" 액션과 "launcher" 카테고리를 선언하면 된다. 다른 앱에서 사용하지 못하도록 만든 다른 액티비티들은 인텐트 필터를 가져서는 안되며 명시적인 인텐트를 통해서 시작시킨다. (이 내용은 다음 섹션에서 설명된다.)


하지만 액티비티가 암시적 인텐트에 반응하도록 하려면 (어떤 어플리케이션에서 발생된 암시적 인텐트이건 관계없이) 액티비티에 적절한 인텐트 필터를 정의해 주어야 한다. 응답하고자 하는 각 종류별 인텐트에 대해서 <intent-filter>를 사용하여 인텐트 필터를 정의해 준다. <intent-filter>에는 필히 <action> 엘리먼트가 포함되어야 하며 액션에 따라 <category>, <data> 엘리먼트가 포함되어야 할 수도 있다. 이 엘리먼트들의 조합에 따라 액티비티가 응답하고자 하는 인텐트를 정의할 수 있다.


어떻게 하면 인텐트에 액티비티가 응답하도록 할 수 있는지에 대해 더 많은 정보를 얻고 싶다면 인텐트와 인텐트 필터(Intents and Intent Filters) 문서를 참고하기 바란다.



액티비티 구동하기(Starting an Activity)



다른 액티비티를 실행시키려면 실행시킬 액티비티에 대한 설명이 담긴 Intent를 파라메터로 하여 startActivity() 메서드를 호출한다. 인텐트는 실행시키려고 하는 정확한 액티비티를 지정하고 수행하고자 하는 액션에 대해 설명을 담고 있다. (시스템은 이 인텐트의 정보를 바탕으로 최적의 액티비티 - 다른 어플리케이션에 속한 액티비티라고 하더라도 - 찾아준다.) 인텐트는 실행된 액티비티가 액션을 수행하는 데 사용할 수 있는 데이터를 전달해 줄 수도 있다.


동일 어플리케이션의 액티비티라면 이미 존재하는 액티비티를 간단하게 실행시켜야 할 때도 있다. 이것은 실행시키고자 하는 액티비티의 클래스명을 가지고 명시적 인텐트를 생성함으로써 가능하다. 아래의 예제는 하나의 액티비티가 SignInActivity라는 이름을 가진 다른 액티비티를 실행시키는 방법에 대한 것이다.


1
2
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
 


그러나 여러분이 만든 액티비티의 데이터를 사용해서 이메일 또는 문자메시지를 보내거나 상태 업데이트 같은 액션을 수행해야 할 수도 있다. 이런 경우 여러분의 어플리케이션에 해당 액션을 수행할 수 있는 기능이 없으면 그 액션이 수행 가능한 다른 어플리케이션의 액티비티를 통해서 수행해야 한다. 이럴 때 인텐트가 아주 유용하다. 수행하고자 하는 액션에 대한 내용을 인텐트에 담아 생성하면 시스템은 다른 어플리케이션에서 적절한 액티비티를 찾아 실행시켜준다. 만일 해당 인텐트를 처리할 수 있는 액티비티가 여러 개 존재한다면 사용자는 그 중에서 하나를 골라 실행시킬 수 있다. 다음은 사용자가 이메일 메시지를 보내려고 할 때 인텐트를 생성하는 예제 코드다.


1
2
3
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
 


EXTRA_EMAIL 부가정보키와 함께 이메일을 받는 수신자들의 이메일 주소를 문자열 배열로 만들어 인텐트에 추가한다. 이메일 어플리케이션이 이 인텐트를 받게 되면 부가정보에 있는 문자열의 배열을 읽어 이메일 작성폼의 "수신자" 항목에 입력시킨다. 이 때, 이메일 어플리케이션의 액티비티가 실행되고 사용자가 일을 마치면 여러분의 액티비티로 다시 복귀하게 된다.


액티비티 구동시키고 결과 받기(Starting an activity for a result)

경우에 따라서는 여러분이 실행시킨 액티비티로부터 어떤 결과를 돌려받아야 할 때가 있다. 이럴 때는 startActivity() 메서드 대신에 startActivityForResult() 메서드를 호출한다. 실행시킨 액티비티로부터 결과를 돌려받기 위해서는 onActivityResult() 콜백 메서드를 구현해 주어야 한다. 실행시킨 액티비티의 일이 완료되면 결과를 Intent에 담아 onActivityResult() 메서드를 통해 넘겨준다.


아래 코드는 사용자로 하여금 연락처 중에 하나를 선택하도록 하고 선택된 연락처 정보를 사용해서 어떤 작업을 수행하도록 하는 예제다. 이 예제는 인텐트를 생성하고 그 결과를 처리하는 법을 보여준다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private void pickContact() {
    // Create an intent to "pick" a contact, as defined by the content provider URI
    Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
    startActivityForResult(intent, PICK_CONTACT_REQUEST);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // If the request went well (OK) and the request was PICK_CONTACT_REQUEST
    if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {
        // Perform a query to the contact's content provider for the contact's name
        Cursor cursor = getContentResolver().query(data.getData(),
        new String[] {Contacts.DISPLAY_NAME}, nullnullnull);
        if (cursor.moveToFirst()) { // True if the cursor is not empty
            int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
            String name = cursor.getString(columnIndex);
            // Do something with the selected contact's name...
        }
    }
}
 


이 예제는 액티비티로 되돌려지는 결과를 활용하기 위해 사용해야 하는 onActivityResult() 메서드에 대한 기본 로직을 보여주고 있다. 첫번째 if문은 조건 검사로써 요청에 대한 작업이 성공이었는지 - 성공이었다면 resultCodeRESULT_OK일 것이다. - 그리고 요청했던 작업에 대한 결과로 호출된 것이 맞는 지 - 예제에서는 requestCode의 값이 startActivityForResult()를 호출할 때 넘겨 준 요청코드와 맞는지를 확인하고 있다. 조건 검사가 끝나면 반환된 Intent(data 파라메터)의 데이터를 쿼리하여 액티비티의 결과를 처리한다.


데이터는 ContentResolver(예제에서는 getContentResolver() 메서드로 획득)로 컨텐트 프로바이더에 쿼리하여 Cursor를 획득하고 이 Cursor를 이용해 읽고자 하는 데이터를 다시 쿼리한다. 더 많은 정보는 Content Providers 문서를 참고하기 바란다.


이 섹션의 내용에 대해 더 자세히 알고 싶다면 인텐트와 인텐트 필터(Intents and Intent Filters) 문서를 참고하기 바란다.



액티비티 닫기(Shutting Down an Activity)



액티비티는 finish() 메서드를 호출하여 닫을 수 있다. 또한 finishActivity() 메서드를 사용하면 앞서 구동시킨 다른 액티비티도 닫을 수 있다.


Note : 대부분의 경우, 이런 메서드들을 직접 호출하여 액티비티를 종료하지 말아야 한다. 액티비티 라이프사이클에 대해 설명하고 있는 다음 섹션의 내용과 같이 안드로이드 시스템이 액티비티의 수명을 관리하고 있기 때문에 액티비티를 직접 종료시킬 필요가 없다. 이 메서드들은 사용자가 예상하지 못한 상황에 맞닥뜨리게 되는 부정적인 상황을 초래하기 때문에 이 액티비티에 사용자가 머물러서는 안된다는 확실한 이유가 있을 때만 직접 호출해야 한다.


posted by 리치크루

API GUIDE/2. App Components
2014. 3. 3. 08:33


 

 

안드로이드 앱 독학으로 개발하기 - 일반적인 인텐트(Common Intents) (2)


안드로이드 개발자 사이트에 있는 글 중에 현재까지 1/10도 번역하지 못했지만 지금까지의 글만 보면 안드로이드는 인텐트 없이 아무것도 할 수 것이 아닌가 할 정도록 인텐트를 반복적으로 설명하고 있습니다. 물론, 액티비티, 서비스 등등 다른 중요 키워드들도 많았지만 인텐트만큼은 아니었지요.


이렇게 강조하고 있다는 것은 당연히 매우 중요하다는 뜻이겠죠. 그런 인텐트를 전부 다 외운다는 건 어렵겠지만 이 글에 나오는 것들만 알고 있으면 앱 개발에 있어 큰 문제는 없을 것 같습니다.


이제 일반적인 인텐트의 종류가 얼마남지 않았습니다. 자 그럼 끝까지 다 읽어서 인텐트를 확실하게 알고 개발해 보도록 합시다.


무슨 일이든 기초가 중요합니다. 그러니 지금 이 순간 열심히 공부해서 멋진 안드로이드 앱을 개발해 보자구요. 언제나 그렇듯 오역, 오타, 깨진 링크가 있으면 제보 부탁드립니다.


 

저작권 표시 : 

 

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

 

현재 보시는 페이지는 안드로이드 오픈 소스 프로젝트에 의해 작성되고 공유된 작업물의 수정/번역본이며 크리에이티브 커먼즈 저작자 표시 2.5 라이센스에 기술된 조건의 사용 근거를 따른 것입니다.

 

본 문서의 원본은 http://developer.android.com/guide/components/intents-common.html이며 안드로이드 4.4 Kitkat 기준으로 설명되었습니다.


일반적인 인텐트(Common Intents)



파일 저장소(File Storage)



지정한 타입의 파일 획득하기(Retrieve a specific type of file)

사용자가 문서나 사진같은 파일을 선택하고 그 파일을 앱에서 참조할 수 있도록 요청하려면 ACTION_GET_CONTENT 액션을 사용하고 원하는 MIME 타입을 지정한다. 앱으로 반환된 파일의 참조는 현재의 액티비티가 소멸 될 때 까지만 일시적으로 사용가능한 것이기 때문에 나중에 다시 읽을 수 있도록 하려면 파일의 복사본을 만들어 두어야 한다. 이 인텐트는 사용자가 새로운 파일을 만드는 것도 가능하도록 해준다. 예를 들어, 저장된 사진을 선택하도록 하는 대신에 카메라로 새로운 사진을 촬영하도록 할 수도 있다.


결과 Intent는 파일을 가리키는 URI를 포함한 채 onActivityResult() 콜백 메서드로 전달된다. URI는 http: URI, file: URI, content: URI 중 어떤 것이라도 될 수 있다. 하지만 컨텐트 프로바이더로 접근 가능하고 (content: URI) openFileDescriptor() 메서드로 파일 스트림을 만들 수 있는 파일만 선택가능ㅎ도록 제한하고 싶다면 인텐트에 CATEGORY_OPENABLE 카테고리를 추가해 준다.


안드로이드 4.3(API 레벨 18)이상에서는 인텐트에 EXTRA_ALLOW_MULTIPLE을 추가하고 true로 설정하면 여러 개의 파일을 선택하도록 할 수도 있다. 그런 후에 getClipData() 메서드로 ClipData 오브젝트를 구하면 선택된 파일들을 각각 액세스 할 수 있다.


액션(Action)

ACTION_GET_CONTENT


데이터 URI 스키마(Data URI Scheme)

필요없음


MIME Type

사용자가 선택할 파일의 타입에 상응하는 MIME 타입



부가정보(Extras; 선택사항)

EXTRA_ALLOW_MULTIPLE

사용자가 동시에 여러 개의 파일을 선택할 수 있는지 여부를 나타내는 boolean(true or false) 값

EXTRA_LOCAL_ONLY

외부 서비스로부터 다운로드 받는 파일이 아니라 기기내에 존재하는 파일만 선택하도록 할 지 여부를 나타내는 boolean(true or false) 값


카테고리(Category; 선택사항)

CATEGORY_OPENABLE

openFileDescriptor()로 열어서 파일 스트림을 구할 수 있는 "열 수 있는" 파일만 선택하도록 하기 위한 값.


사진 파일을 얻는 인텐트 예제 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static final int REQUEST_IMAGE_GET = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_GET);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) {
        Bitmap thumbnail = data.getParcelable("data");
        Uri fullPhotoUri = data.getData();
        // Do work with photo saved at fullPhotoUri
        ...
    }
}


사진 파일을 반환하는 인텐트 필터 예제 :

1
2
3
4
5
6
7
8
9
10
11
<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.GET_CONTENT" />
        <data android:type="image/*" />
        <category android:name="android.intent.category.DEFAULT" />
        <!-- The OPENABLE category declares that the returned file is accessible
             from a content provider that supports OpenableColumns
             and ContentResolver.openFileDescriptor() -->

        <category android:name="android.intent.category.OPENABLE" />
    </intent-filter>
</activity>

특정 타입의 파일 열기(Open a specific type of file)

안드로이드 4.4 이상에서는 앱에서 사용할 파일의 복사본을 만드는 대신에 (ACTION_GET_CONTENT 액션을 사용할 때) ACTION_OPEN_DOCUMENT 액션과 MIME 타입을 지정하여 다른 앱에서 관리중인 파일을 열도록 요청할 수 있다. 또한 ACTION_CREATE_DOCUMENT를 사용하면 여러분의 앱으로 쓰기가 가능한 새로운 문서를 만들도록 할 수도 있다. 예를 들어, 이미 저장되어 있는 PDF문서를 선택하도록 하는 대신에 ACTION_CREATE_DOCUMENT를 사용해서 새로운 문서가 만들어질 위치를 사용자가 선택하도록 할 수 있다.(그 위치는 다른 앱에서 관리하는 문서 저장공간이다.) 그러면 여러분의 앱은 새로운 문서를 작성할 수 있는 위치의 URI를 획득할 수 있다.


ACTION_GET_CONTENT 액션을 사용하면 onActivityResult()를 통해 해당 파일의 URI를 돌려준다. 반면에 ACTION_OPEN_DOCUMENT, ACTION_CREATE_DOCUMENT를 사용하면 항상 DocumentsProvider를 통해 선택된 파일에 대한 content: URI를 되돌려준다. 그러면 openFileDescriptor()를 사용해서 파일을 열 수 있고 DocumentsContract.Document의 컬럼을 사용해 상세한 내용을 쿼리해 볼 수 있다.


반환된(획득된) URI는 앱이 동작하는 동안에는 파일을 읽고 쓸 수가 있다. 그래서 ACTION_OPEN_DOCUMENT를 사용하면 파일의 복사본을 만들어 두어야 하는 ACTION_GET_CONTENT와는 달리 아무때나 파일을 열고 수정할 수 있기 때문에 상당히 유용하다.


인텐트에 EXTRA_ALLOW_MULTIPLE을 추가하고 true로 설정하면 사용자가 여러 개의 파일을 선택하도록 할 수 있다. 사용자가 하나의 아이템만 선택하면 getData() 메서드로 그 아이템을 획득할 수 있다. 사용자가 여러 개의 아이템을 선택하면 getData()는 null을 리턴하고 대신에 getClipData()로 부터 반환되는 ClipData 오브젝트를 통해 각 아이템을 획득할 수 있다.


Note : ACTION_OPEN_DOCUMENTACTION_CREATE_DOCUMENT를 사용하려면 MIME 타입을 반드시 설정해야 하며 CATEGORY_OPENABLE 카테고리를 반드시 선언해야 한다. 필요하다면 부가정보키 EXTRA_MIME_TYPES를 사용하여 MIME 타입의 배열을 추가하면 하나 이상의 MIME 타입을 설정할 수도 있다. 단, 이 방법을 사용할 때는 setType() 메서드를 사용하여 메인 MIME 타입에 "*/*"를 세팅해 준다.


액션(Action)

ACTION_OPEN_DOCUMENT 또는

ACTION_CREATE_DOCUMENT


데이터 URI 스키마(Data URI Scheme)

필요없음


MIME Type

사용자가 선택해야 하는 파일타입에 상응하는 MIME 타입


부가정보(Extras; 선택사항)

EXTRA_MIME_TYPES

앱이 요구하는 파일 타입들에 대한 MIME 타입의 배열. 부가정보에 이 키 값을 사용하면 메인 MIME 타입은 setType() 메서드를 통하여 반드시 "*/*"로 세팅해 주어야 한다.

EXTRA_ALLOW_MULTIPLE

사용자가 동시에 여러 개의 파일을 선택할 수 있는지 여부를 나타내는 boolean(true or false) 값

EXTRA_TITLE

ACTION_CREATE_DOCUMENT 액션을 사용할 때 파일 이름을 지정한다.

EXTRA_LOCAL_ONLY

외부 서비스로부터 다운로드 받는 파일이 아니라 기기내에 존재하는 파일만 선택하도록 할 지 여부를 나타내는 boolean(true or false) 값


카테고리(Category)

CATEGORY_OPENABLE

openFileDescriptor()로 열어서 파일 스트림을 구할 수 있는 "열 수 있는" 파일만 선택하도록 하기 위한 값.


사진 파일을 얻는 인텐트 예제 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
static final int REQUEST_IMAGE_OPEN = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.setType("image/*");
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
    startActivityForResult(intent, REQUEST_IMAGE_OPEN);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_OPEN && resultCode == RESULT_OK) {
        Uri fullPhotoUri = data.getData();
        // Do work with full size photo saved at fullPhotoUri
        ...
    }
}


사실 서드파티 앱은 ACTION_OPEN_DOCUMENT 액션이 담긴 인텐트를 처리할 수가 없다. 대신 시스템이 받아서 통합 UI를 통해 다양한 앱으로부터 사용가능한 모든 파일을 디스플레이 해 준다.


여러분의 앱에 있는 파일들을 이 UI에 표시되고 다른 앱에서 열어볼 수 있도록 하려면 DocumentsProvider를 구현해야 하며 인텐트 필터에 PROVIDER_INTERFACE("android.content.action.DOCUMENTS_PROVIDER")가 포함되어 있어야 한다. 다음은 그 예제다.


1
2
3
4
5
6
7
8
<provider ...
    android:grantUriPermissions="true"
    android:exported="true"
    android:permission="android.permission.MANAGE_DOCUMENTS">

    <intent-filter>
        <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
    </intent-filter>
</provider>


다른 앱에 있는 파일을 만들고 사용하는 법에 대해 더 알고 싶다면 Stroage Access Framework 가이드를 참고하기 바란다.



지도(Maps)



지도 상에 위치 표시하기(Show a location on a map)

지도를 열어보려면 ACTION_VIEW 액션을 사용하고 아래에 정의된 스키마 중의 하나로 인텐트에 위치정보를 지정해 준다.


액션(Action)

ACTION_VIEW


데이터 URI 스키마(Data URI Scheme)

geo:latitude,longitude

주어진 위도와 경도로 맵에 위치를 표시한다.

예 : "geo:47.6,-122.3"


geo:latitude,longitude?z=zoom

주어진 위도와 경도를 정해진 줌 레벨로 지도에 표시한다. 줌 레벨1은 지구 전체를 보여주며 주어진 위도와 경도가 화면 중앙에 위치된다. 가장 높은(확대된) 줌 레벨은 23이다.

예 : "geo:47.6,-122.3?z=11"


geo:0,0?q=lat,lng(label)

주어진 위도와 경도를 라벨과 함께 표시한다.

예 : "geo:0,0?q=34.99,-106.61(Treasure)"


geo:0,0?q=my+street+address

"my street address"의 위치를 표시한다.(특정 주소나 위치 찾기 가능한 주소)

예 : "geo:0,0?q=1600+amphitheatre+parkway+ca"


MIME Type

필요없음


인텐트 예제 :

1
2
3
4
5
6
7
public void showMap(Uri geoLocation) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(geoLocation);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}


인텐트 필터 예제 :

1
2
3
4
5
6
7
<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="geo" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>



음악 / 동영상(Music or Video)



음악 파일 재생하기

음악 파일을 재생하려면 ACTION_VIEW 액션을 사용하고 인텐트 데이터에 파일을 가리키는 URI 위치를 지정한다.


액션(Action)

ACTION_VIEW


데이터 URI 스키마(Data URI Scheme)

file:<URI>

content:<URI>

http:<URL>


MIME Type

"audio/*"

"application/ogg"

"application/x-ogg"

"application/itunes"

또는 앱이 필요로 하는 다른 타입


인텐트 예제 :

1
2
3
4
5
6
7
public void playMedia(Uri file) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(file);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}


인텐트 필터 예제 :

1
2
3
4
5
6
7
8
<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:type="audio/*" />
        <data android:type="application/ogg" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>



전화(Phone)



전화 걸기(Initiate a phone call)

전화 앱을 열고 전화번호가 입력되도록 하려면 ACTION_DIAL 액션을 사용하고 아래 정의된 URI 스키마를 사용하여 전화번호를 지정한다. 전화 앱이 실행되면 전화번호가 입력된 상태가 되지만 반드시 사용자가 "통화"버튼을 눌러야만 전화가 걸린다.


액션(Action)

ACTION_DIAL


데이터 URI 스키마(Data URI Scheme)

tel:<phone-number>


MIME Type

필요없음


유효한 전화번호는 the IETF RFC 3966에 정의되어 있다. 유효한 전화번호의 예는 다음과 같다.

  • tel:2125551212
  • tel:(212) 555 1212


전화 다이얼러는 전화번호 같은 일반적인 스키마에서 유연하게 잘 동작한다. 그래서 스킴의 내용이 규칙에 정확히 맞지 않아도 Uri.parse() 메서드를 사용하는데는 큰 문제가 없다. 하지만 사용해 본 적이 없고 잘 동작할 지 확실하지 않다면 Uri.fromParts() 메서드를 대신 사용하도록 한다.


인텐트 예제 :

1
2
3
4
5
6
7
public void dialPhoneNumber(String phoneNumber) {
    Intent intent = new Intent(Intent.ACTION_DIAL);
    intent.setData(Uri.parse("tel:" + phoneNumber));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}



환경 설정(Settings)



환경 설정의 특정 부분 열기(Open a specific section of Settings)

사용자가 시스템 설정의 일부분을 바꿀 수 있도록 특정 환경 설정 창을 열고 싶을 때는 다음의 액션 중 하나를 액션으로 사용한다.


액션(Action)

ACTION_SETTINGS

ACTION_WIRELESS_SETTINGS

ACTION_AIRPLANE_MODE_SETTINGS

ACTION_WIFI_SETTINGS

ACTION_APN_SETTINGS

ACTION_BLUETOOTH_SETTINGS

ACTION_DATE_SETTINGS

ACTION_LOCALE_SETTINGS

ACTION_INPUT_METHOD_SETTINGS

ACTION_DISPLAY_SETTINGS

ACTION_SECURITY_SETTINGS

ACTION_LOCATION_SOURCE_SETTINGS

ACTION_INTERNAL_STORAGE_SETTINGS

ACTION_MEMORY_CARD_SETTINGS


이 외에 또다른 설정 화면에 대한 정보는 Settings 화면을 참조하기 바란다.


데이터 URI 스키마(Data URI Scheme)

필요없음


MIME Type

필요없음


인텐트 예제 :

1
2
3
4
5
6
public void openWifiSettings() {
    Intent intent = new Intent(Intent.ACTION_WIFI_SETTINGS);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}



문자 메세지(Text Messaging)



첨부와 함께 SMS/MMS 메시지 보내기(Compose an SMS/MMS message with attachment)

SMS 또는 MMS 문자 메시지를 보내려면 다음의 인텐트 액션을 사용하고 전화번호, 제목, 내용 등과 같은 메시지의 세부 내용은 다음 목록에 있는 부가정보키를 사용하여 지정한다.


액션(Action)

ACTION_SENDTO 또는

ACTION_SEND 또는

ACTION_SEND_MULTIPLE


데이터 URI 스키마(Data URI Scheme)

sms:<phone_number>

smsto:<phone_number>

mms:<phone_number>

mmsto:<phone_number>


이 스키마들은 모두 동일하게 취급된다.


MIME Type

PLAIN_TEXT_TYPE ("text/plain")

"image/*"

"video/*"


부가정보(Extras; 선택사항)

"subject"

메시지의 제목을 위한 문자열(보통 MMS에만 필요하다.)

"sms_body"

메시지 본문을 위한 문자열

EXTRA_STREAM

첨부하고자 하는 사진이나 동영상을 가리키는 Uri. 만일 ACTION_SEND_MULTIPLE 액션을 사용한다면 첨부하려는 사진들이나 동영상들의 Uri로 이루어진 ArrayList 값이 되어야 한다.


인텐트 예제 :

1
2
3
4
5
6
7
8
9
public void composeMmsMessage(String message, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType(HTTP.PLAIN_TEXT_TYPE);
    intent.putExtra("sms_body", message);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}


이 인텐트가 이메일 앱이나 소셜 앱이 아닌 문자메시지 앱으로 처리되도록 하고 싶다면 ACTION_SENDTO 액션을 사용하고 데이터 스키마에 "smsto:"를 포함시키도록 한다. 다음은 그 예제다.


1
2
3
4
5
6
7
8
9
public void composeMmsMessage(String message, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setData(Uri.parse("smsto:"));  // This ensures only SMS apps respond
    intent.putExtra("sms_body", message);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}


인텐트 필터 예제 :

1
2
3
4
5
6
7
8
<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <data android:type="text/plain" />
        <data android:type="image/*" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>


Note : 안드로이드 4.4버전 이상에서 기본 SMS 앱으로 사용가능한 SMS/MMS 메세지 앱을 개발 중이라면 몇몇 추가적인 액션을 인텐트 필터에 추가로 구현해야 한다. 더 자세한 정보는 Telephony 문서를 참조하기 바란다.



웹 브라우저(Web Browser)



웹 URL 열기(Load a web URL)

웹 피이지를 열려면 ACTION_VIEW 액션을 사용하고 인텐트 데이터에 웹 URL을 지정한다.


액션(Action)

ACTION_VIEW


데이터 URI 스키마(Data URI Scheme)

http:<URL>

https:<URL>

이 스키마들은 모두 동일하게 취급된다.


MIME Type

PLAIN_TEXT_TYPE ("text/plain")

"text/html"

"application/xhtml+xml"

"application/vnd.wap.xhtml+xml"


인텐트 예제 :

1
2
3
4
5
6
7
public void openWebPage(String url) {
    Uri webpage = Uri.parse(url);
    Intent intent = new Intent(Intent.ACTION_VIEW, webpage);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}


인텐트 필터 예제 :

1
2
3
4
5
6
7
8
9
10
11
<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <!-- Include the host attribute if you want your app to respond
             only to URLs with your app's domain. -->

        <data android:scheme="http" android:host="www.example.com" />
        <category android:name="android.intent.category.DEFAULT" />
        <!-- The BROWSABLE category is required to get links from web pages. -->
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
</activity>


Tip : 여러분의 앱이 웹 사이트와 비슷한 기능을 제공한다면 그 웹사이트를 가리키는 URL을 포함한 인텐트 필터를 선언해야 한다. 그러면 여러분의 앱을 설치한 사용자가 여러분의 웹 사이트를 가리키는 이메일이나 다른 웹 사이트의 링크를 누르게 되면 웹 페이지 대신에 여러분의 앱이 실행된다.


웹 검색하기(Perform a web search)

웹 검색을 하려면 ACTION_WEB_SEARCH 액션을 사용하고 SearchManager.QUERY 부가정보키에 검색할 문자열을 지정해 준다.


액션(Action)

ACTION_WEB_SEARCH


데이터 URI 스키마(Data URI Scheme)

필요없음


MIME Type

필요없음


부가정보(Extras)

SearchManager.QUERY

검색할 문자열


인텐트 예제 :

1
2
3
4
5
6
7
public void searchWeb(String query) {
    Intent intent = new Intent(Intent.ACTION_SEARCH);
    intent.putExtra(SearchManager.QUERY, query);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}


이번 글은 여기까지 입니다.


그럼 다음 글에서 뵙겠습니다.


다음 글 >> 

이전 글 >> 일반적인 인텐트(Common Intents) (1)


posted by 리치크루