안녕하세요. 제임스 입니다. 


이번에는 안드로이드에서 LinearLayout 과 함께 가장 많이 사용되고 있는 RelativeLayout 에 대해 정리해 보겠습니다. 


■ Relativelayout 란?


뷰들을 상대적인 위치 정보를 설정하여 배치 시키는 형태 입니다. 

java.lang.Object

↳ android.view.View

↳ android.view.ViewGroup

android.widget.RelativeLayout


■ RelativeLayout 속성

RelativeLayout 에는 많은 속성 값들이 존재 합니다. 


◎ 부모 컨테이너를 기준으로 설정하는 속성 목록


layout_alignParentBottom : 부모 컨테이너의 아래쪽과 뷰의 아래쪽을 맞춤

layout_alignParentEnd : 부모 컨테이너의 끝과 뷰의 끝을 맞춤 (오른쪽 끝)

layout_alignParentLeft : 부모 컨테이너의 왼쪽 끝과 뷰의 왼쪽 끝을 맞춤

layout_alignParentRight : 부모 컨테이너의 오른쪽 끝과 뷰의 오른쪽 끝을 맞춤

layout_alignParentStart : 부모 컨테이너의 시작점을 뷰의 시작점에 맞춤 (왼쪽 끝)

layout_alignParentTop : 부모 컨테이너의 상단 끝과 뷰의 상단 끝을 맞춤

layout_centerHorizontal : 부모 컨테이너의 수평방향 중간에 맞춤

layout_centerVertical : 부모 컨테이너의 수직방향 중간에 맞춤

layout_centerInParent : 부모 컨테이너의 수직 & 수평 중간에 맞춤 (정중앙에 위치)



◎ id 값으로 지정한 뷰 기준으로 설정하는 속성 목록


layout_above : 지정한 뷰의 위쪽에 위치 시킴

layout_alignBaseline : 지정한 뷰와 내용물의 아래쪽 기준선에 맞춤

layout_alignBottom : 지정한 뷰의 아래쪽과 맞춤

layout_alignEnd : 지정한 뷰의 끝에 맞춤

layout_alignLeft : 지정한 뷰의 왼쪽에 맞춤

layout_alignRight : 지정한 뷰의 오른쪽에 맞춤

layout_alignStart : 지정한 뷰의 시작점에 맞춤

layout_alignTop : 지정한 뷰의 상단에 맞춤

layout_below : 지정한 뷰의 아래쪽에 위치 시킴

layout_toLeftOf : 지정한 뷰의 왼쪽에 위치 시킴

layout_toRightOf : 지정한 뷰의 오른쪽에 위치 시킴


위 목록들이 자주 사용하는 속성값들입니다. 

위 값들만 적절히 잘 사용해 주시면 거의 모든 레이아웃 구성도 가능합니다. 



■ 부모 컨테이너를 기준으로 설정하는 속성 예제 


가장 위에 있는 민트색 바탕의 사각형에 속성01 부터 속성07 까지 사각형이 배치되어 있습니다. 



속성01 

- 어떠한 속성 값도 지정하지 않은 기본 상태로 RelativeLayout 내에서 좌측상단에 위치하게 됩니다. 

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#933c3c"
android:text="속성01"/>


속성02 

- layout_alignParentRight 속성을 true 로 지정하여 부모 컨테이너의 오른쪽 끝에 위치하게 했습니다. 

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#ce5d24"
android:text="속성02"
android:layout_alignParentRight="true"
/>


속성03

- layout_alignParentBottom 속성을 true 로 지정하여 부모 컨테이너의 가장 아래쪽에 위치하게 했습니다. 

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#980cd9"
android:text="속성03"
android:layout_alignParentBottom="true"
/>


속성04

- layout_alignParentRight 속성 및 layout_alignParentBottom 속성을 true 로 지정하여 부모 컨테이너의 우측하단에 위치하게 했습니다.

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#f9f902"
android:text="속성04"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
/>


속성05

- layout_centerHorizontal 속성을 true 로 지정하여 부모 컨테이너의 수평방향으로 중앙에 위치하게 했습니다. 

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#d52d9a"
android:text="속성05"
android:layout_centerHorizontal="true"
/>


속성06

- layout_centerVertical 속성을 true 로 지정하여 부모 컨테이너의 수직방향으로 중앙에 위치하게 했습니다. 

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#abf902"
android:text="속성06"
android:layout_centerVertical="true"
/>


속성07

- layout_centerInParent 속성을 true 로 지정하여 부모 컨테이너의 수직방향 및 수평방향 모두 중앙에 위치하게 했습니다. (정중앙 위치)

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#e7110a"
android:text="속성07"
android:layout_centerInParent="true"
/>



■ id 값으로 지정한 뷰를 기준으로 설정하는 속성 예제 




아래쪽 하늘색 큰 사각형은 상단의 민트색 사각형을 기준으로 layout_below 지정하여 마진 5dp 를 준 상태입니다. 

이번 화면에서는 속성07 의 붉은색 사각형을 기준으로 속성값을 지정 했습니다. 


속성07

- layout_centerInParent 값을 true 로 지정하여 부모 컨테이너의 정중앙에 배치 시켰습니다. 

- id 값을 tv_07 로 지정하여 다른 뷰들이 속성07을 기준으로 자리 배치를 하도록 합니다. 

<TextView
android:id="@+id/tv_07"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#e7110a"
android:text="속성07"
android:layout_centerInParent="true"
/>


속성08-1

- layout_toLeftOf 속성을 속성07의 id 값 기준으로 지정하여 속성07의 바로 왼쪽에 위치하고 있습니다. 

- 수직방향으로의 속성값을 지정하지 않았으므로 default 값으로 상단에 붙어 있습니다. 

<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:padding="10dp"
android:background="#0ae733"
android:text="속성08-1"
android:layout_toLeftOf="@id/tv_07"
/>


속성08-2

- layout_toLeftOf 속성을 속성07 기준으로 지정하여 속성07의 바로 왼쪽에 위치하고 있습니다. 

- layout_alignTop 속성을 속성07 기준으로 지정하여 속성07의 상단과 속성08-2의 상단을 같은 위치에 배치 했습니다. 

- 속성08-2 의 높이가 길어 속성07 보다 아래쪽으로 밀려 난것을 확인하실 수 있습니다. 

<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:padding="10dp"
android:background="#0ae733"
android:text="속성08-2"
android:layout_toLeftOf="@id/tv_07"
android:layout_alignTop="@id/tv_07"
/>


속성09-1

- layout_toRightOf 속성을 주고 속성07의 바로 오른쪽에 위치하고 있습니다. 

- 수직방향으로의 속성값을 지정하지 않았으므로 default 값으로 상단에 붙어 있습니다. 

<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:padding="10dp"
android:background="#b0e70a"
android:text="속성09-1"
android:layout_toRightOf="@id/tv_07"
/>


속성09-2

- layout_toRightOf 속성을 주고 속성07의 바로 오른쪽에 위치하고 있습니다. 

- layout_alignBottom 속성값을 지정하여 속성07의 한단과 속성09-2의 하단을 같은 위치에 배치 했습니다. 

- 속성09-2 의 높이가 길어 속성07보다 위로 치솟아 오른것을 확인 하실 수 있습니다. 

<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:padding="10dp"
android:background="#b0e70a"
android:text="속성09-2"
android:layout_toRightOf="@id/tv_07"
android:layout_alignBottom="@id/tv_07"
/>


속성10-1

- layout_above 속성을 주고 속성07의 바로 위에 위치하고 있습니다. 

- 수평방향으로의 속성값을 지정하지 않았으므로 default 값으로 좌측에 붙어 있습니다. 

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#955ed9"
android:text="속성10-1"
android:layout_above="@id/tv_07"
/>


속성10-2

- layout_above 속성을 주고 속성07의 바로 위에 위치하고 있습니다. 

- layout_alignRight 속성값을 지정하여 속성07의 오른쪽 끝과 속성10-2의 오른쪽 끝을 일치 시켰습니다. 

- 속성10-2 의 길이가 길어 속성07의 좌측으로 벗어나 있는 것을 확인 하실 수 있습니다.  

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#955ed9"
android:text="속성10-2"
android:layout_above="@id/tv_07"
android:layout_alignRight="@id/tv_07"
/>


속성11-1

- layout_below 속성을 주고 속성07의 바로 아래에 위치하고 있습니다. 

- 수평방향으로의 속성값을 지정하지 않았으므로 default 값으로 좌측에 붙어 있습니다. 

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#d58a65"
android:text="속성11-1"
android:layout_below="@id/tv_07"
/>


속성11-2

- layout_below 속성을 주고 속성07의 바로 아래에 위치하고 있습니다. 

- layout_alignLeft 속성을 지정하여 속성07의 좌측끝에 속성11-2의 좌측 끝을 일치 시켰습니다.

- 속성11-2 의 길이가 길어 속성07의 우측으로 벗어나 있는 것을 확인 하실 수 있습니다. 

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#d58a65"
android:text="속성11-2"
android:layout_below="@id/tv_07"
android:layout_alignLeft="@id/tv_07"
/>





아래는 이번 예제를 위해 작성한 전체 레이아웃 입니다. 



아래는 위 레이아웃을 구성하기 위해 작성한 xml 코드 전문입니다. 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tutorial.james.tutorial_linearlayout.MainActivity"
>

<RelativeLayout
android:id="@+id/rl_top"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#11cc99"
android:layout_marginTop="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#933c3c"
android:text="속성01"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#ce5d24"
android:text="속성02"
android:layout_alignParentRight="true"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#980cd9"
android:text="속성03"
android:layout_alignParentBottom="true"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#f9f902"
android:text="속성04"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#d52d9a"
android:text="속성05"
android:layout_centerHorizontal="true"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#abf902"
android:text="속성06"
android:layout_centerVertical="true"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#e7110a"
android:text="속성07"
android:layout_centerInParent="true"
/>

</RelativeLayout>

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#7ee3ef"
android:layout_below="@id/rl_top"
android:layout_margin="5dp"
>

<TextView
android:id="@+id/tv_07"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#e7110a"
android:text="속성07"
android:layout_centerInParent="true"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:padding="10dp"
android:background="#0ae733"
android:text="속성08-1"
android:layout_toLeftOf="@id/tv_07"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:padding="10dp"
android:background="#0ae733"
android:text="속성08-2"
android:layout_toLeftOf="@id/tv_07"
android:layout_alignTop="@id/tv_07"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:padding="10dp"
android:background="#b0e70a"
android:text="속성09-1"
android:layout_toRightOf="@id/tv_07"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:padding="10dp"
android:background="#b0e70a"
android:text="속성09-2"
android:layout_toRightOf="@id/tv_07"
android:layout_alignBottom="@id/tv_07"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#955ed9"
android:text="속성10-1"
android:layout_above="@id/tv_07"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#955ed9"
android:text="속성10-2"
android:layout_above="@id/tv_07"
android:layout_alignRight="@id/tv_07"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#d58a65"
android:text="속성11-1"
android:layout_below="@id/tv_07"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#d58a65"
android:text="속성11-2"
android:layout_below="@id/tv_07"
android:layout_alignLeft="@id/tv_07"
/>

</RelativeLayout>

</RelativeLayout>

참고로 android:text 값을 하드코딩으로 입력 한것이 보이실 겁니다. 

이는 레이아웃 구조 설명을 위해 입력한 방식입니다. 

string.xml 에 문장을 지정하고 해당 id 값을 호출하여 사용하는 방식을 사용하는 것을 권해 드립니다. 

참고하세요 :)



 도움이 되셨다면 로그인이 필요 없는 

▼ 하트 클릭 한번 부탁 드립니다 

감사합니다 :D




블로그 이미지

쉬운코딩이최고

Android, Java, jsp, Linux 등의 프로그래밍 언어를 소개 합니다.

,

안녕하세요. 제임스 입니다. 


Android 개발 중에 DP, SP, PX 등의 치수 단위를 많이 보게 됩니다. 

일전에 개념 정리한 내용이 있으니 참조 하시면 좋을 것 같구요.

http://jamesdreaming.tistory.com/41


이번에는 이 단위 변환 방법에 대해 정리해 보겠습니다. 



■ DP 를 PX 로 변환

import android.util.DisplayMetrics;
import android.util.TypedValue;
public static int convertDpToPixels(float dp, Context context) {
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
return px;
}



■ SP 를 PX 로 변환

public static int convertSpToPixels(float sp, Context context) {
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, context.getResources().getDisplayMetrics());
return px;
}



■ DP 를 SP 로 변환???

public static int convertDpToSp(float dp, Context context) {
int sp = (int) (convertDpToPixels(dp, context) / (float) convertSpToPixels(dp, context));
return sp;
}

코드를 위와 같이 작성 하긴 했지만 실제로 사용할 일이 없습니다. 


sp 는 텍스트 사이즈를 정의 할때 사용하고 dp 는 그 이외 모든 사이즈를 정의할때 사용합니다. 

만약 텍스트 사이즈를 dp 로 정의 했다면 문제가 될 수도 있겠지만 sp 로 정의 했다면 특별히 문제가 될 것은 없을 것이며 변환식 자체가 의미 없습니다. 



 도움이 되셨다면 로그인이 필요 없는 

▼ 하트 클릭 한번 부탁 드립니다 

감사합니다 :D


블로그 이미지

쉬운코딩이최고

Android, Java, jsp, Linux 등의 프로그래밍 언어를 소개 합니다.

,

안녕하세요. 제임스 입니다. 


이번에는 안드로이드 DP 및 DPI 의 개념에 대해 정리 하겠습니다. 


■ Dimension Units (치수, 크기 단위) 

안드로이드 에서 유저 인터페이스를 xml 에서 생성하거나 또는 java 코드로 생성 할 수 있습니다. 이때 크기, 거리, 길이, 넓이, 높이, 마진, 패딩 등등을 표현하기 위해 여러가지 치수, 크기 단위를 사용할 수 있습니다. 


아래는 안드로이드에서 사용하는 기본 단위들입니다. 


px - 화면상의 실제 픽셀입니다. 단일 픽셀의 물리적 크기는 화면 밀도에 따라 달라집니다. 


in - 화면의 물리적 인치 단위 입니다. 단일 인치의 픽셀 수는 화면 밀도에 따라 달라지게 되는데 이는 픽셀수가 화면 밀도에 따라 달라지기 때문입니다. 


mm - in 과 마찬가지로 화면의 물리적 밀리미터 단위 입니다. 1 inch 는 25.4 mm 입니다. 


pt - Point 로 불리며 텍스트의 폰트 사이즈를 의미 합니다. 1 inch 는 72 pt 입니다. 


dp - 단일 dp 의 물리적 사이즈는 모든 화면 밀도에서 거의 동일 합니다. 1 inch 는 거의 160 dp 입니다. 


sp - 비율 독립 픽셀단위로 특별히 텍스트 크기를 위해 사용합니다. 단일 sp 의 물리적 사이즈는 모든 화면 밀도에서 겅의 동일 합니다. 1 inch 는 거의 160 sp 입니다. 


< 이미지 출처 : https://www.captechconsulting.com/blogs/understanding-density-independence-in-android >



■ DPI (Dots Per Inch) 란? 

안드로이드 리소스에서 사이즈 구분을 mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi 등으로 하고 있습니다. 

여기서 dpi 라는 단위에 대해 설명 드리겠습니다. 

DPI (Dots per Inch) 즉, 인치당 들어가는 픽셀을 의미합니다. 


mdpi ---> 48 px

hdpi ---> 72 px

xhdpi ---> 96 px

xxhdpi ---> 144 px

xxxhdpi ---> 192 px 


이 됩니다. 


DPI <---> Pixel 간 변환은 아래 사이트에서 하실 수 있습니다. 

https://pixplicity.com/dp-px-converter/

아래 이미지와 같은 사이트로 DPI 와 PX 사이의 값 뿐만 아니라 다른 단위에 대한 값들도 자동 산정되니 개발 시 참조 하세요.



http://www.gargasz.info/android/

아래 사이트에서도 상기 사이트와 같이 converter 를 제공하고 있으며 dimension uint 에 관한 설명도 같이 보실 수 있습니다. 



■ Density (밀도) & DPI

밀도는 DPI 를 일정 단위로 나눈 것입니다. 

여석 가지 일반화된 밀도는 아래와 같습니다. 


~ 120dpi > ldpi (저밀도) 

~ 160dpi > mdpi (중간 밀도) - baseline

~ 240dpi > hdpi (고밀도) 

~ 320dpi > xhdpi (초고밀도)

~ 480dpi > xxhdpi (초초고밀도)

~ 640dpi > xxxhdpi (초초초고밀도)


MDPI 의 경우 1 sp = 1 px = 1dp 가 되어 기준점이 됩니다. 

이후 HDPI, XHDPI .... 로 올라 갈 수록 sp 대비 dp 비율이 증가 하게 되는 내용을 정리 한 이미지 입니다. 




위 이미지는 안드로이드에서 실제 크기와 밀도가 일반화된 크기와 밀도로 대략적으로 맵핑되는 방식을 보여주고 있습니다. 



다른 화면 크기에 맞게 UI 작업을 하다보면 각 디자인에 최소한의 공간 크기가 필요 합니다. 따라서 위 이미지에서 나타난 각 일반화된 화면 크기는 시스템이 정의하는 최소 해상도를 가지게 됩니다. 이 최소 크기의 단위는 dp 이며 이 경우 시스템이 화면 밀도의 변화를 걱정할 필요가 없습니다. 



현재 사용중인 단말의 DPI 는 아래와 같은 코드를 이용하여 구할 수 있습니다. 

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int deviceDpi = metrics.densityDpi;

deviceDpi 값이 바로 사용중인 단말의 DPI 값입니다. 




이번에는 안드로이드에서 사용하는 기본적인 치수 단위들과 DP 및 DPI 에 대해 정리 했습니다. 

도움이 되었으면 하는 바램과 함께... 저는 이만 잠자리로 :)


블로그 이미지

쉬운코딩이최고

Android, Java, jsp, Linux 등의 프로그래밍 언어를 소개 합니다.

,


안녕하세요. 제임스 입니다. 


앞번에 안드로이드 리소스에 관해 개념적인 부분을 설명 했는데요. 

내용 참 길고 어렵게 느껴 지시죠? 


이번에는 샘플 코드와 함께 한번 이전 내용을 요약해보겠습니다. 

이글을 읽고 나면 리소스를 어떻게 사용하는지에 대해 이해를 하실수 있으리라 믿습니다. 



■ 리소스 파일 작업



※ values 디렉토리




colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="reousrce_tut_color">#FF4081</color>
</resources>

<resources></resources> 태그 안에 <color></color> 로 묶어 원하는 컬러 값을 정의해주면 됩니다. 

컬러값은 인터넷등에서 색상표를 참조하여 원하는 색으로 설정 하시면 됩니다. 



dimens.xml

<resources>
<dimen name="one_pixel">1px</dimen>
<dimen name="double_density">2dp</dimen>
<dimen name="eleven_sp">11sp</dimen>
<dimen name="fab_margin">10dp</dimen>
<dimen name="thirty_density">30dp</dimen>
</resources>

colors 와 동일하게 <resources></resources> 태그 안에 정의를 하지만 <dimen></dimen> 이라는 태그를 이용하여 사이즈를 설정 한다고 생각하시면 됩니다. 단위는 px (Pixel), dp 또는 dip (Density-independent Pixels), sp (Scale-independent Pixels) 등을 사용하고 있습니다. 단위에 대한 내용은 별도로 정리 한번 하도록 하겠습니다. 



strings.xml

<resources>
<string name="app_name">Android Resources Tutorial</string>
<string name="resource_string_from_xml">리소스 string 값 XML 파일에서 설정</string>
<string name="resource_string_from_code">리소스 string 값 Java Code 에서 설정</string>
</resources>

문자열을 정의하는 리소스로 <string></string> 태그 안에 정의 하여 사용합니다. 



※ drawable 디렉토리



앱 내에서 사용할 이미지를 drawable 디렉토리 아래에 저장하면 됩니다. 



※ layout 디렉토리


위 values 디렉토리 내 xml 리소스에서 정의하고 있는 값들을 실제 화면 레이아웃에서 아래와 같이 사용 합니다.



activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tutorial.james.androidresourcestut.MainActivity"
android:orientation="vertical"
android:layout_gravity="center">

<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/android_drawable"
android:layout_marginTop="@dimen/thirty_density"
android:layout_marginBottom="@dimen/eleven_sp"
android:layout_gravity="center_horizontal"/>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:id="@+id/textView_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/thirty_density"
android:layout_marginRight="@dimen/thirty_density"
android:textColor="@color/reousrce_tut_color"
android:text="@string/resource_string_from_xml" />

<Button
android:id="@+id/btn_set_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/thirty_density"
android:text="Java Code 로 텍스트 셋팅하기기"/>

<TextView
android:id="@+id/textView_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="30dp"
/>

</LinearLayout>

</LinearLayout>

사용자 인터페이스를 구성하는 화면 레이아웃 파일입니다. 


<ImageView> 를 이용하여 drawable 디렉토리에 있는 이미지를 불러 옵니다. 

android:background="@drawable/android_drawable"


바로 아래에 <TextView> 를 이용하여 문자열을 보여 줍니다. 

여기서 좌우로 마진 30dp 로 설정하는데 이것을 dimen.xml 에 정의한 thirty_density 라는 값으로 정의 했습니다. 

android:layout_marginLeft="@dimen/thirty_density"
android:layout_marginRight="@dimen/thirty_density"

또한 문자열 색상을 colors.xml 에 정의한 resource_tut_color 라는 값으로 정의 했으며, 

문자열은 strings.xml 에 정의한 resource_string_from_xml 이라는 값으로 정의 했습니다. 

android:textColor="@color/reousrce_tut_color"
android:text="@string/resource_string_from_xml"


그 아래 <Button> 을 위치 시켜 자바코드에서 문자열을 표기 할때 리소스를 사용하는 방법을 보여 드릴겁니다 

버튼에도 문자열이 표기 할 수 있는데요 여기서는 strings.xml 에 정의 한 값이 아니라 직접 하드코딩으로 텍스트를 입력 했습니다. 

android:text="Java Code 로 텍스트 셋팅하기기"

위와 같이 사용 할 수는 있지만 지양하시길 권합니다. 유지 보수 측면에서 본다면 앱내 모든 문자열들을 stirngs.xml 파일 내에 저장하여 사용하는 것이 좋습니다. 또한 다중 언어를 지원하는 경우라면 거의 필수라고 생각 하시면 됩니다. 

다중 언어 지원에 대한 내용은 추후 별도로 다루도록 하겠습니다. 


그리고 마지막으로 <TextView> 를 하나 더 만들고 id 값을 부여하여 java code 에서 해당 id 값을 이용하여 텍스트 입력을 할 수 있도록 하였습니다. 

<TextView
android:id="@+id/textView_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="30dp"
/>


※ Java 소스




자바소스 위치는 위 이미지와 같으며 여기서는 MainActivity.java 소스를 아래와 같이 작성 하였습니다.

package com.tutorial.james.androidresourcestut;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// activity_main 을 액티비티의 레이아웃으로 정의
setContentView(R.layout.activity_main);

// btn_set_text 라는 id 값에 클릭리스너를 추가
findViewById(R.id.btn_set_text).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 클릭 되었을 경우 ...
// textView_2 라는 id 값을 가진 TextView 의 텍스트를
// strings.xml 에 있는 resource_string_from_code 값으로 적용
((TextView)findViewById(R.id.textView_2)).setText(R.string.resource_string_from_code);
}
});

}

}

소스내에 주석을 간단히 작성했으니 참조하세요 :)


문자열을 TextView 에 set 할때는 위와 같이 setText(R.string.표시할문자열_ID값) 으로 호출 하면 됩니다. 

각 객체의 사용법에 대해서는 별도 내용으로 정리할 예정입니다. 



위와 같이 작성 후 앱을 빌드 합니다. 

Android Studio 단축키 Alt+Shift+X 를 이용하거나 아래 버튼을 클릭 합니다. 




■ 앱 실행 결과

최상단에 drawable 디렉토리에 있던 이미지가 노출되고 그 하단에 strings.xml 에 정의한 문자열 및 colors.xml 에 정의 한 색상이 적용되어 표시 됩니다. 

그 하단에 버튼이 노출되고 이 버튼을 클릭 시 아래와 같이 문자열이 나타나게 됩니다. 




리소스를 이용하여 간단한 앱을 만들어 봤습니다. 

개념만 설명 하던것과 달리 샘플을 보시면 좀더 쉽게 이해가 되실겁니다. 

도움이 되셧길 기도하면서 저는 다른 이야기를 준비하겠습니다. 


블로그 이미지

쉬운코딩이최고

Android, Java, jsp, Linux 등의 프로그래밍 언어를 소개 합니다.

,

■ 안드로이드 8.0 정식 명칭 오레오 확정 공개




안녕하세요. 제임스 입니다. 


구글이 새 운영체제 안드로이드 8.0 의 명칭을 확정했습니다. 

미 공개 상태에서 안드로이드 O 로 명명 되었던 명칭이 이번에도 디저트 이름을 따 Oreo - 오레오 로 확정 되었습니다. 



네... 저 오레오 맞습니다. :)


사실 오레오가 디저트라기 보다는 특정 회사의 제품명인데요, 일전에 KitKat 과 같이 제품명을 사용한 예가 있어 이번에도 어느정도 예상되긴 했었습니다. KitKat 이 발표 되었을때와 비슷한 형태로 오레오 제품에 안드로이드 관련 광고가 들어 가거나 또는 KitKat 시절과 같이 유사 이벤트를 진행 할 가능성도 점쳐 집니다. (제 개인적인 생각이니 어디 소문 내지는 마세요 ^^;)



■ 안드로이드 8.0 오레오 특징은?


안드로이드 8.0 오레오의 특징은 아래 Android official 사이트의 내용 및 이미지를 참조 했습니다. 

https://www.android.com/versions/oreo-8-0/


공식 사이트에서 소개하고 있는 내용을 순서대로 정리 하면 아래와 같습니다. 


안드로이드 소개 시작인데요. 첫 이미지 부터 더 스마트해지고, 빨라지고 더 강력하고 그 어느때보다 더 좋아 졌다는 문구를 넣어 안드로이드 8.0 오레오에 대한 기대감을 극대화 시켜 주고 있습니다.


구글 픽셀(레퍼런스폰) 기준으로 부팅속도가 최대 2배 빨라지고, 앱들의 백그라운드 사용을 최소화 하여 사용환경을 최고로 제공합니다. 


사용자 승인하에 로그인 정보를 기억 하고 로그인이 필요한 경우 로그인 정보를 자동으로 채워 주는 Autofill 기능을 제공하여 앱을 초고속으로 이용하실 수 있습니다.


PIP (Picture-in-Picture) 모드를 지원하여 기존 단말 제조사 (삼성, LG 등등)가 개별적으로 지원하던 팝업이나 멀티태스킹 기능을 OS 차원에서 제공하여 한번에 구개의 앱을 볼 수 있도록 합니다. 


푸시 알림 내요을 바로 확인하고 스와이프(옆으로 밀기) 해서 지울 수 있습니다. 또한 안드로이드 인스턴트 앱을 지원하여 새로운 앱을 설치하지 않고 브라우저 상에서 바로 이동 할 수 있습니다.


매일 500억개 이상의 앱을 스캔하여 해킹, 악성코드 감염 등의 부정 행위를 하는 앱들로 부터 사용자의 단말과 데이터를 안전하게 보호합니다. 


통화를 하거나, 게임 플레이, 작업 또는 스트리밍을 통해 동영상이나 음악을 들을때에도 배터리 수명 관리가 한층 강화 되었다는 것을 확신할 수 있을 것입니다. 


구글 메신저에 60개의 신규 이모티콘 (Emoji)이 추가 되었습니다. 


여기까지가 안드로이드 공식 사이트에서 제공하고 있는 안드로이드 8.0 오레오의 특징인데요. 

생각보다 뭔가 눈에 확 띄는 기능은 없는 것 같습니다. 하지만 아직 직접 사용해보기 전이므로 속단하기는 이르겠죠? 


주말쯤 넥서스에 개발자용 팩토리 이미지 다운받아 설치 해봐야 겠습니다 :D


그럼 저는 20000!



블로그 이미지

쉬운코딩이최고

Android, Java, jsp, Linux 등의 프로그래밍 언어를 소개 합니다.

,

Android Resources



안녕하세요. 제임스 입니다. 

이번에는 Android 의 Resource 에 관한 내용을 다루고자 합니다. 



■ Android Resources 란?

안드로이드에서 리소스란 이미지, 텍스트, 화면 구조 등 화면을 그리는데 필요한 요소들을 통틀어 리소스라 칭합니다. 



위 이미지중 res 폴더 아래 있는 것들이 모두 안드로이드 리소스 입니다. 

안드로이드 리소스에는 이미지, xml  형식의 레이아웃, 앱 아이콘, value 로 정의 되는 arrays, strings, styles, dimens, colors 등이 있습니다. 


모든 리소스는 res 폴더 아래에 있어야 하며 그 아래에 drawable, layout, menu, mipmap, values 등의 디렉토리를 제공하여 각각의 특징에 맞는 리소스를 관리하고 있습니다. 



■ Resources 유형

res 디렉토리 내부에서 지원되는 리소스 디렉토리 구조 및 유형은 아래와 같습니다. 


res/ 

animator/    속성 애니메이션을 정의하는 XML 파일

anim/         두 가지 이상의 속성 애니메이션을 정의하는 XML 파일

color/         색상의 상태 목록 정의 XML 파일

drawable/    이미지 (.png, .9.png, .jpg, .gif) 또는 XML 파일

mipmap/     단말 해상도에 따른 런처 아이콘 이미지 지정 디렉토리

layout/        화면 인터페이스 레이아웃을 정의하는 XML 파일

menu/         옵션 메뉴, 컨텍스트 메뉴 또는 하위 메뉴 등과 같은 애플리케이션 메뉴를 정의하는  XML 파일

raw/           원시 형태로 저장하기 위한 임의의 파일 저장

value/         문자열, 색, 치수(길이, 사이즈), 스타일 등을 정의한 XML 파일 

xml/           Resources.getXML() 을 호출하여 런타임에 읽을 수 있는 임의의 XML 파일


주의 할 점은 리소스 파일을 res 폴더 아래에 직접 저장할 경우 컴파일러 오류를 초래하게 되므로 꼭 지정된 디렉토리 아래에 저장 하셔야 합니다. 



■ 대체 리소스 제공

기본적으로 Defalt 리소스를 제공하지만 대체 리소스 역시 제공해야 하는 경우가 대부분입니다. 

예를 들면 단말 해상도에 따라 사이즈가 다른 이미지를 제공해야 하며, 단말 설정 언어값에 따라 다른 언어 문자열을 제공해야 하기도 합니다. 

Android 가 런타임에 현재 기기 구성을 감지하고 적절한 리소스를 로드합니다. 


대체 리소스 구성 방법은 아래과 같습니다. 


res/ 디렉토리 아래에 <resources_name>-<config_qualifier> 형식으로 이름을 지정하여 새 디렉토리를 만듭니다. 

☞ <resources_name> 은 위에 언급한 유형별 디렉토리 명칭을 의미합니다 (color, layout, value 등등) 

☞ <qualifier> 는 개별 구성을 지정하는 이름입니다. 

☞ 하나 이상의 <qualifier> 를 추가 할 수 있으며 각기 대시(-) 로 구분합니다. 

☞ <qualifier>에는 아래와 같은 값들이 있습니다. 

구성Qualifier 값설명
MCC 및 MNC예:
mcc310
mcc310-mnc004
mcc208-mnc00

이동통신 국가 코드(MCC)에 선택적으로 이동통신 네트워크 코드(MNC)가 이어지는 형태로, 기기의 SIM 카드에서 가져옵니다. 예를 들어, mcc310은 모든 이동통신사를 포함한 미국이고, mcc310-mnc004는 Verizon을 사용하는 미국, mcc208-mnc00은 Orange를 사용하는 프랑스입니다.

기기가 무선 연결(GSM 전화)을 사용할 경우, MCC와 MNC 값은 SIM 카드에서 가져옵니다.

MCC만 단독으로 사용할 수도 있습니다(예를 들어, 애플리케이션에 국가별 합법적 리소스를 포함하는 경우). 언어에 기초해서만 지정해야 할 경우, 언어 및 지역 한정자를 대신 사용합니다(아래에 설명). MCC와 MNC 한정자를 사용할 경우, 조심해서 사용하고 예상한 대로 작동하는지 테스트해야 합니다.

또한, 구성 필드 mcc와 mnc를 참조하세요. 이 구성 필드는 각각 모바일 국가 코드와 모바일 네트워크 코드를 나타냅니다.

언어 및 지역예:
en
fr
en-rUS
fr-rFR
fr-rCA

언어는 두 글자의 ISO 639-1 언어 코드로 정의되고, 뒤이어 두 글자의 ISO 3166-1-alpha-2 지역 코드(앞에 소문자 'r'이 추가됨)가 선택적으로 따라옵니다.

코드는 대소문자를 구별하지 않습니다r 접두어는 지역 부분을 구별하기 위해 사용됩니다. 지역만 지정할 수는 없습니다.

사용자가 시스템 설정에서 언어를 변경할 경우 애플리케이션 수명 중에 변경될 수 있습니다. 런타임에서 애플리케이션에 어떤 영향을 미치는지 자세히 알아보려면 런타임 변경 처리를 참조하세요.

다른 여러 언어에 맞게 애플리케이션을 현지화하기 위한 전체 지침은 현지화를 참조하세요.

또한, 현재 로케일을 나타내는 locale 구성 필드도 참조하세요.

레이아웃 방향ldrtl
ldltr

애플리케이션의 레이아웃 방향입니다. ldrtl은 "오른쪽에서 왼쪽 방향 레이아웃"을 나타냅니다. ldltr은 "왼쪽에서 오른쪽 방향 레이아웃"을 나타내고 기본 암시적 값입니다.

이는 레이아웃이나 드로어블, 값 등의 모든 리소스에 적용할 수 있습니다.

예를 들어, 아랍어에 대한 특정 레이아웃을 제공하고 다른 "오른쪽에서 왼쪽으로 쓰는" 언어(히브리어 또는 페르시아어)에 제네릭 레이아웃을 제공하고 싶다면 다음과 같이 해야 합니다.

res/
    layout/   
        main.xml  (Default layout)
    layout-ar/  
        main.xml  (Specific layout for Arabic)
    layout-ldrtl/  
        main.xml  (Any "right-to-left" language, except
                  for Arabic, because the "ar" language qualifier
                  has a higher precedence.)

참고: 앱에서 오른쪽에서 왼쪽 레이아웃 기능을 활성화하려면 supportsRtl을 "true"로 설정하고 targetSdkVersion을 17 이상으로 설정해야 합니다.

API 레벨 17에서 추가되었습니다.

smallestWidthsw<N>dp

예:
sw320dp
sw600dp
sw720dp

화면의 기본 크기로, 사용 가능한 화면 영역의 가장 짧은 치수로 나타냅니다. 구체적으로 기기의 smallestWidth는 해당 화면의 이용 가능한 높이와 너비의 가장 짧은 치수를 말합니다(이것을 화면에 대한 "가능한 한 가장 좁은 너비"로 생각해도 됩니다). 이 한정자를 사용하면 화면의 현재 방향에 관계없이 애플리케이션이 해당 UI에서 이용 가능한 너비 중 최소 <N> dps를 확보하도록 할 수 있습니다.

예를 들어, 레이아웃에 언제나 600dp 이상의 화면 최소 치수가 필요하다면, 이 한정자를 사용하여 레이아웃 리소스 res/layout-sw600dp/를 만들 수 있습니다. 시스템이 이러한 리소스를 사용하는 것은 사용 가능한 화면의 최소 치수가 적어도 600dp가 되는 경우뿐이며, 이때 600 dp라는 크기가 사용자 쪽에서 보기에 높이이든 너비이든 관계 없습니다. 이 smallestWidth는 기기의 고정된 화면 크기 특성입니다. 기기의 smallestWidth는 화면 방향이 변경되어도 바뀌지 않습니다.

기기의 smallestWidth는 화면 장식과 시스템 UI를 감안합니다. 예를 들어, 화면 상에서 최소 너비의 축 주변 공간을 차지하는 영구 UI 요소가 있다면, 시스템은 smallestWidth를 실제 화면 크기보다 작게 선언합니다. 이것은 개발자의 UI가 사용할 수 없는 화면 픽셀이기 때문입니다. 따라서 개발자가 사용하는 값은 레이아웃에서 요구하는실제 최소 치수여야 합니다. (일반적으로 이 값은 화면의 현재 방향과 관계없이 레이아웃이 지원하는 "최소 너비"가 됩니다.)

다음의 몇몇 값은 일반적인 화면 크기에 대해 사용할 수 있습니다.

  • 화면 크기 320에 화면 구성이 아래와 같은 기기:
    • 240x320ldpi(QVGA 핸드셋)
    • 320x480mdpi(핸드셋)
    • 480x800hdpi(고화질 핸드셋)
  • 480x800mdpi(태블릿/핸드셋) 등의 화면에는 480을 사용합니다.
  • 600x1024mdpi (7인치 태블릿) 등의 화면에는 600을 사용합니다.
  • 720x1280mdpi (10인치 태블릿) 등의 화면에는 720을 사용합니다.

애플리케이션이 smallestWidth 한정자의 여러 값이 포함된 여러 리소스 디렉터리를 제공하면, 시스템은 기기의 smallestWidth에 가장 가까운(그러나 이를 초과하지 않는) 값을 사용합니다.

API 레벨 13에서 추가되었습니다.

이외에도 애플리케이션과 호환되는 최소한의 smallestWidth를 선언하는 android:requiresSmallestWidthDp특성과 기기의 smallestWidth 값을 유지하는 smallestScreenWidthDp 구성 필드도 참조하세요.

여러 가지 화면에 맞는 디자인과 한정자 사용에 관한 자세한 정보는 다중 화면 지원 개발자 가이드를 참조하세요.

이용 가능한 너비w<N>dp

예:
w720dp
w1024dp

리소스를 사용해야 하는 dp 단위에서 최소 이용 가능한 화면 너비를 지정합니다. 이는 <N> 값으로 정의됩니다. 이 구성 값은 현재 실제 너비에 맞추기 위해 화면 방향이 가로와 세로 사이를 오가며 바뀔 때 변경됩니다.

애플리케이션이 이 구성에 대해 서로 다른 값이 포함된 여러 개의 리소스 디렉터리를 제공하면, 시스템은 기기의 현재 화면 너비에 가장 가까운(그러나 이를 초과하지 않는) 값을 사용합니다. 이 값은 화면 장식을 감안한 것이므로, 기기의 왼쪽이나 오른쪽 가장자리에 영구 UI 요소가 있을 경우, 기기는 이러한 UI 요소를 감안하여 애플리케이션의 이용 가능한 공간을 줄여서 실제 화면 크기보다 작은 너비 값을 사용합니다.

API 레벨 13에서 추가되었습니다.

현재 화면 너비를 보유한 screenWidthDp 구성 필드도 참조하세요.

여러 가지 화면에 맞는 디자인과 한정자 사용에 관한 자세한 정보는 다중 화면 지원 개발자 가이드를 참조하세요.

이용 가능한 높이h<N>dp

예:
h720dp
h1024dp

리소스가 사용되어야 하는 최소한의 사용 가능한 화면 높이를 "dp" 단위로 나타냅니다. 이는 <N> 값이 정의합니다. 이 구성 값은 현재 실제 높이에 맞추기 위해 화면 방향이 가로와 세로 사이를 오가며 바뀔 때 변경됩니다.

애플리케이션이 이 구성에 대해 서로 다른 값이 포함된 여러 개의 리소스 디렉터리를 제공하면, 시스템은 기기의 현재 화면 높이에 가장 가까운(그러나 이를 초과하지 않는) 값을 사용합니다. 이 값은 화면 장식을 감안한 것이므로, 기기의 상단이나 하단 가장자리에 영구 UI 요소가 있을 경우, 기기는 이러한 UI 요소를 감안하여 애플리케이션의 이용 가능한 공간을 줄여서 실제 화면 크기보다 작은 높이 값을 사용합니다. 상태 표시줄에 고정되지 않은 화면 장식(예를 들어 전화 상태 표시줄은 전체 화면에서 숨길 수 있음)은 여기에서 감안하지 않았고, 제목 표시줄이나 작업 모음 등의 창 장식도 감안되지 않았으므로, 애플리케이션 입장에서는 자신이 지정한 것보다 어느 정도 작은 공간을 받아들일 대비를 해야 합니다.

API 레벨 13에서 추가되었습니다.

현재 화면 너비를 보유한 screenHeightDp 구성 필드도 참조하세요.

여러 가지 화면에 맞는 디자인과 한정자 사용에 관한 자세한 정보는 다중 화면 지원 개발자 가이드를 참조하세요.

화면 크기small
normal
large
xlarge
  • small: 저밀도 QVGA 화면과 비슷한 크기의 화면입니다. 작은 화면의 최소 레이아웃 크기는 약 320x426 dp단위입니다. 이 화면의 예시로는 QVGA 저밀도 및 VGA 고밀도가 있습니다.
  • normal: 중밀도 HVGA 화면과 비슷한 크기의 화면입니다. 정상 화면의 최소 레이아웃 크기는 약 320x470 dp 단위입니다. 이 화면의 예로는 WQVGA 저밀도, HVGA 중밀도, WVGA 고밀도 등이 있습니다.
  • large: 중밀도 VGA 화면과 비슷한 크기의 화면입니다. 큰 화면의 최소 레이아웃 크기는 약 480x640 dp 단위입니다. 이 화면의 예시로는 VGA 및 WVGA 중밀도 화면이 있습니다.
  • xlarge: 일반적인 중밀도 HVGA 화면보다 상당히 큰 화면을 말합니다. 초대형 화면의 최소 레이아웃 크기는 약 720x960 dp 단위입니다. 대부분의 경우, 초대형 화면 기기는 주머니에 넣어 다니기에 너무 큽니다. 따라서 태블릿 스타일의 기기일 가능성이 높습니다. API 레벨 9에서 추가되었습니다.

참고: 크기 한정자를 사용하더라도 해당 리소스가 그 크기의 화면 전용이라는 뜻은 아닙니다. 현재 기기 구성과 더욱 잘 맞는 한정자가 포함된 대체 리소스를 제공하지 않으면, 시스템이 가장 잘 일치하는 리소스를 사용합니다.

주의: 모든 리소스가 현재 화면보다  크기 한정자를 사용하는 경우, 시스템은 리소스를 사용하지 않으며 애플리케이션은 런타임에 작동이 중단됩니다(예: 모든 레이아웃 리소스에 xlarge 한정자가 태그로 지정되어 있지만 기기는 일반 크기 화면일 경우).

API 레벨 4에서 추가되었습니다.

자세한 정보는 다중 화면 지원을 참조하세요.

screenLayout 구성 필드도 참조하세요. 이것은 화면이 소형, 일반 크기 또는 대형인지를 나타냅니다.

화면 비율long
notlong
  • long: WQVGA, WVGA, FWVGA 등의 긴 화면
  • notlong: QVGA, HVGA 및 VGA 등의 길지 않은 화면

API 레벨 4에서 추가되었습니다.

이것은 순전히 화면 비율에만 기초합니다("긴" 화면이 더 넓습니다). 이는 화면 방향과 관계가 없습니다.

screenLayout도 참조하세요. 이것은 화면이 긴 화면인지 여부를 나타냅니다.

원형 화면round
notround
  • round: 원형 화면(예: 원형 웨어러블 기기)
  • notround: 사각형 화면(예: 전화 또는 태블릿)

API 레벨 23에서 추가되었습니다.

isScreenRound() 구성 메서드도 참조하세요. 이것은 화면이 원형 화면인지 여부를 나타냅니다.

화면 방향port
land
  • port: 기기가 세로 방향(수직)입니다.
  • land: 기기가 가로 방향(수평)입니다.

이것은 사용자가 화면을 돌리는 경우 애플리케이션 수명 중에 변경될 수 있습니다. 이것이 런타임에 애플리케이션에 어떤 영향을 미치는지 알아보려면 런타임 변경 처리를 참조하세요.

orientation 구성 필드도 참조하세요. 이는 현재 기기 방향을 나타냅니다.

UI 모드car
desk
television
appliancewatch
  • car: 기기가 차량용 도크에서 표시되고 있습니다.
  • desk: 기기가 데스크용 도크에서 표시되고 있습니다.
  • television: 기기가 텔레비전에서 표시되고 있으며, UI가 큰 화면에 있고 사용자가 여기에서 멀리 떨어져 있는 "텐 풋(ten foot)" 환경을 제공하고 있습니다. 이는 주로 DPAD 또는 기타 비-포인터 상호작용 주변을 가리킵니다.
  • appliance: 기기가 가전 제품 역할을 하고 있으며, 디스플레이 화면이 없습니다.
  • watch: 기기에 디스플레이 화면이 있고 손목에 착용됩니다.

API 레벨 8에서 추가되었고, 텔레비전은 API 13에서, 시계는 API 20에서 추가되었습니다.

기기가 도크에 삽입되거나 제거될 때 앱이 응답하는 방식에 관한 정보는 도킹 상태 및 유형 판별과 모니터링을 읽어보세요.

이것은 사용자가 기기를 도크에 놓는 경우 애플리케이션 수명 중에 변경될 수 있습니다. 이러한 모드 중 몇 가지는 UiModeManager를 사용하여 활성화 또는 비활성화할 수 있습니다. 이것이 런타임에 애플리케이션에 어떤 영향을 미치는지 알아보려면 런타임 변경 처리를 참조하세요.

야간 모드night
notnight
  • night: 야간
  • notnight: 주간

API 레벨 8에서 추가되었습니다.

이것은 야간 모드가 자동 모드인 상태(기본)에서 애플리케이션의 수명 중에 변경될 수 있습니다. 이 경우 모드는 하루 중 시간대를 기반으로 변경됩니다. 이 모드는 UiModeManager를 사용하여 활성화 또는 비활성화할 수 있습니다. 이것이 런타임 중 애플리케이션에 어떤 영향을 미치는지 알아보려면 런타임 변경 처리를 참조하세요.

화면 픽셀 밀도(dpi)ldpi
mdpi
hdpi
xhdpi
xxhdpi
xxxhdpi
nodpi
tvdpi
anydpi
  • ldpi: 저밀도 화면, 약 120 dpi.
  • mdpi: 중밀도(일반적인 HVGA에서) 화면, 약 160 dpi.
  • hdpi: 고밀도 화면, 약 240 dpi.
  • xhdpi: 초고밀도 화면, 약 320 dpi. API 레벨 8에서 추가되었습니다.
  • xxhdpi: 슈퍼 초고밀도 화면, 약 480 dpi. API 레벨 16에서 추가되었습니다.
  • xxxhdpi: 울트라 슈퍼 초고밀도 화면 사용(런처 아이콘만 해당, 다중 화면 지원의 참고 참조), 약 640 dpi. API 레벨 18에서 추가되었습니다.
  • nodpi: 이것은 기기 밀도에 일치하도록 크기를 조정하고자 하지 않는 비트맵 리소스에 사용할 수 있습니다.
  • tvdpi: Mdpi와 hdpi 사이 어딘가에 해당되는 화면, 약 213 dpi. 이것은 "기본" 밀도 그룹으로 간주되지 않습니다. 이는 대체로 텔레비전용으로 만들어진 것이며 대부분의 앱에는 필요하지 않는 것이 정상입니다. mdpi 및 hdpi만 제공하면 대부분의 앱에는 충분하고 시스템이 필요에 따라 크기를 조정해줍니다. API 레벨 13에서 추가되었습니다.
  • anydpi: 이 한정자는 모든 화면 밀도와 일치하고 다른 한정자보다 우선합니다. 이는 벡터 드로어블에 유용합니다. API 레벨 21에서 추가되었습니다.

여섯 가지 기본 밀도간에 3:4:6:8:12:16 비율 척도가 있습니다(tvdpi 밀도는 무시). 그러므로 ldpi의 9x9 비트맵은 mdpi에서 12x12이고, hdpi에서 18x18, xhdpi에서 24x24 등, 이런 식으로 적용됩니다.

이미지 리소스가 텔레비전이나 특정 기기에서 제대로 보이지 않는다고 결정하고 tvdpi 리소스를 사용하려 할 경우, 배율은 1.33*mdpi입니다. 예를 들어, mdpi 화면의 100px x 100px 이미지는 tvdpi에서 133px x 133px가 되어야 합니다.

참고: 밀도 한정자를 사용하더라도 해당 리소스가 그 밀도의 화면 전용이라는 뜻은 아닙니다. 현재 기기 구성과 더욱 잘 맞는 한정자가 포함된 대체 리소스를 제공하지 않으면, 시스템이 가장 잘 일치하는 리소스를 사용합니다.

다양한 화질을 처리하는 방법과 Android가 현재 화질에 맞춰 비트맵을 축소하는 방법에 관한 자세한 정보는 다중 화면 지원을 참조하세요.

터치스크린 유형notouch
finger
  • notouch: 기기에 터치 스크린이 없습니다.
  • finger: 기기에 터치 스크린이 있으며 이를 사용자의 손가락을 사용한 방향 지시 상호작용을 통해 쓰도록 되어 있습니다.

touchscreen 구성 필드도 참조하세요. 이는 기기에서 사용되는 터치 스크린의 유형을 나타냅니다.

키보드 가용성keysexposed
keyshidden
keyssoft
  • keysexposed: 기기에서 키보드를 사용할 수 있습니다. 키보드에 소프트웨어 키보드가 활성화되어 있으면(이럴 가능성이 큽니다), 하드웨어 키보드가 사용자에게 노출되어 있지 않거나 기기에 하드웨어 키보드가 없더라도 이 리소스를 사용할 수 있습니다. 소프트웨어 키보드가 제공되어 있지 않거나 비활성화되어 있는 경우 이것은 하드웨어 키보드가 노출되어 있을 때에만 사용할 수 있습니다.
  • keyshidden: 기기에서 하드웨어 키보드를 사용할 수 있지만 숨겨져 있고 이에 더하여 기기에 소프트웨어 키보드가 활성화되어 있지 않습니다.
  • keyssoft: 기기에 활성화된 소프트웨어 키보드가 있습니다(표시 여부는 무관).

keysexposed 리소스를 제공하지만 keyssoft 리소스는 제공하지 않는다면, 시스템은 소프트웨어 키보드가 활성화되어 있는 동안은 키보드가 보이는지 여부와 관계없이 keysexposed 리소스를 사용합니다.

이것은 사용자가 하드웨어 키보드를 여는 경우 애플리케이션 수명 중에 변경될 수 있습니다. 이것이 런타임에 애플리케이션에 어떤 영향을 미치는지 알아보려면 런타임 변경 처리를 참조하세요.

또한, 구성 필드 hardKeyboardHidden 및 keyboardHidden도 참조하세요. 이 필드는 각각 하드웨어 키보드의 가시성과 모든 종류의 키보드(소프트웨어 포함)의 가시성을 나타냅니다.

기본 텍스트 입력 방법nokeys
qwerty
12key
  • nokeys: 기기에 텍스트 입력을 위한 하드웨어 키가 없습니다.
  • qwerty: 기기에 하드웨어 쿼티 키보드가 있습니다(이것이 사용자 에게 표시되는지 여부는 무관).
  • 12key: 기기에 하드웨어 12-키 키보드가 있습니다(이것이 사용자에게 표시되는지 여부는 무관).

구성 필드 keyboard도 참조하세요. 이는 기본 텍스트 입력 메서드를 사용할 수 있는지 여부를 나타냅니다.

플랫폼 버전(API 레벨)예:
v3
v4
v7

기기에서 지원하는 API 레벨입니다. 예를 들어, v1는 API 레벨 1용이고(Android 1.0 이상 기기), v4는 API 레벨 4용(Android 1.6 이상 기기)입니다. 이러한 값에 관한 자세한 정보는 Android API 레벨 문서를 참조하세요.

<테이블 출처 : https://developer.android.com/guide/topics/resources/providing-resources.html#ResourceTypes >

관련 내용이 너무 많아 안드로이드 개발자 오피셜 사이트에서 긁어 왔습니다 ^^;;


<qualifier>는 한번에 여러개를 사용할 수 있으며 대시로 구분하면 됩니다. 

또한 이 값들의 순서는 위 표의 상단부터 하단으로 추가 하면 됩니다. 


drawable-hdpi-port/ 잘못된 표기 

drawable-port-hdpi/ 맞는 표기


port 값이 hdpi 보다 상위에 있는 qualifier 입니다. 


그럼 리소스 구조에 위와 같은 방식으로 대체 리소스를 추가(붉은 색이 대체 리소스 디렉토리) 한 예를 보여 드리겠습니다. 


res/ 

color/         

drawable/

drawable-hdpi/

drawable-mdpi/

drawable-xhdpi/

drawable-xxhdpi/

mipmap/    

layout/

value/

value-en/

value-ko/

value-w820dp/


지금까지 Android Resources 에 대해 알아 봤습니다. 

개념적인 부분만 정리를 했는데요, 다음에는 샘플 코드를 참조 하여 어떤식으로 사용하는지 알아 보겠습니다. 

블로그 이미지

쉬운코딩이최고

Android, Java, jsp, Linux 등의 프로그래밍 언어를 소개 합니다.

,

앞번에 Intent 와 Intent Filter 에 관한 개념에 대한 설명을 했습니다. 


이번에는 앞서 언급한 명시적 인텐트 와 암시적 인텐트의 사용 예를 보여 드리겠습니다. 


■ 명시적 인텐트 예제


명시적 인텐트는 시작할 구성 요소(호출될 Activity)의 이름을 지정 하는 것입니다. 

아래는 ActivityA 에서 ActivityB를 명시적으로 호출 하는 예제 입니다. 


activity_a.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tutorial.james.androidtutorialtest.MainActivity"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Activity A 입니다."/>

<Button
android:id="@+id/btn_goto_activityb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Activity B 로 이동"/>

</LinearLayout>

</LinearLayout>

Activity A 화면이라는 내용의 TextView 를 제공하고 바로 아래에 Button 컴포넌트를 두어 Activity B 로 이동 하는 이벤트를 걸도록 하겠습니다. 


ActivityA.java

package com.tutorial.james.androidtutorialtest;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

public class ActivityA extends AppCompatActivity {

Intent intent;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a);

intent = new Intent(this, ActivityB.class);
(findViewById(R.id.btn_goto_activityb)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
intent.putExtra("messageStr", "Activity B 에 전송하는 문자 메세지입니다.");
intent.putExtra("messageInt", 7);
startActivity(intent);
}
});
}

}

btn_goto_activityb 라는 id 값을 가진 컴포넌트가 클릭 될 경우 intent 에 putExtra 를 이용하여 ActivityB 로 전달하고 싶은 내용을 추가 했습니다. 

messageStr 이라는 key 값에는 string 형태로 전달하고, messageInt 라는 Key 값에는 inter 형태로 전달 했습니다. 

이 값들을 Activity B 에서 사용 하는 방법도 아래에서 보여 드리겠습니다. 


activity_b.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tutorial.james.androidtutorialtest.MainActivity"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Activity B 입니다."/>

<TextView
android:id="@+id/tv_getintent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>

</LinearLayout>

Activity B 화면임을 알려 주고 바로 아래 tv_getintent 라는 id 값의 TextView 를 제공하여 여기에 앞에서 전달흔 값들을 셋팅해 보겠습니다. 


ActivityB.java

package com.tutorial.james.androidtutorialtest;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

public class ActivityB extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);

if(getIntent().getExtras() != null){
String str = "Activity A 에서 전달한 Int 값 = "+getIntent().getExtras().getInt("messageInt")
+"\nActivity A 에서 전달한 string 값 = "+ getIntent().getExtras().getString("messageStr");
((TextView)(findViewById(R.id.tv_getintent))).setText(str);
}

}
}

getIntent().getExtra() 값이 null 이 아닌 경우 이전 Activity 에서 intent 에 데이터를 전달 했다는 것을 알 수 있습니다. 

putExtra 할 때 int 값을 던졌으면 getIntent().getExtra().getInt("키값") 으로 받아야 하고, 만약 string 값을 던졌으면 getIntent().getExtra().getString("키값") 으로 받으면 됩니다. 


참고로 이 getIntent().getExtra() 는 데이터를 포함하는 Intent 의 Bundle 객체를 반환합니다. 


이를 실행 해보면 아래와 같은 결과를 얻으실 수 있습니다. 


Activity A 화면으로 Activity B 로 이동하는 버튼을 제공하고 있습니다. 


위 ActivityB.java 파일에서 getIntent().getExtra() 한 값들을 문자열로 조합하여 찍어 낸 결과 입니다. 


명시적 인텐트는 아주 간단하지만 또 한편으로는 데이터 전달 방식이 생각보다 종류가 많아 잘 봐두셔야 합니다. 

실제로 앱 개발중 Intent 를 활용하여 데이터를 쉬지 않고 나르고 받아 오는 작업을 할 겁니다. 



■ 암시적 인텐트 예제

암시적 인텐트는 호출될 Activity 명을 참조하는 명시적 인텐트와 달리 수행될 액션과 수신 Activity 에 의해 처리되는 데이터 타입을 지정하여 호출 될 Activity 를 식별합니다. 


아래는 email 를 보내는 기능을 하는 Activity를 검색하여 실행 하는 예제입니다. 


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tutorial.james.androidtutorialtest.MainActivity"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>

<Button
android:id="@+id/btn_send_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_send_email"
/>

</LinearLayout>

</LinearLayout>

레이아웃에 버튼 하나만 배치 했습니다. 

id 값을 btn_send_email 로 설정 하였습니다. 

text 값은 string.xml 파일의 btn_sent_email 이라는 값을 참조 하도록 했으며 이 값은 아래와 같습니다. 

<string name="btn_send_email">Send email</string>



IntentActivity.java

package com.tutorial.james.androidtutorialtest;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

/**
* Created by James on 2017-08-09.
*/

public class IntentActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

(findViewById(R.id.btn_send_email)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/html");
intent.putExtra(Intent.EXTRA_EMAIL, "beardog78@gmail.com");
intent.putExtra(Intent.EXTRA_SUBJECT, "제목");
intent.putExtra(Intent.EXTRA_TEXT, "메일 내용 입력");
startActivity(Intent.createChooser(intent, "Send Email"));
}
});


}
}

IntentActivity 의 레이아웃은 activity_main.xml 이라고 설정 했습니다. 

이메일을 전송하기 위해서는  Intent.ACTION_SEND 값을 전달해야 합니다. 

btn_send_email 이라는 id 값을 가지는 컴포넌트를 찾아 View.OnClickListener 를 붙여 클릭 이벤트가 발생 할 경우 이메일을 전송합니다. 


위 소스를 실행 시 아래와 같은 결과를 확인 할 수 있습니다. 


SEND EMAIL 이라는 텍스트 있는 버튼을 클릭 시 아래와 같이 현재 단말에서 ACTION_SEND 를 할 수 있는 모든 애플리케이션 목록이 아래와 같이 나타납니다. 사용자는 이중 본인이 원하는 애플리케이션을 사용하여 이메일 전송을 할 수 있습니다. 




지금까지 명시적 인텐트 및 암시적 인텐트의 사용 예제를 살펴 봤습니다. 


Gooooooooooooooooooood Bye :)


블로그 이미지

쉬운코딩이최고

Android, Java, jsp, Linux 등의 프로그래밍 언어를 소개 합니다.

,

안드로이드 인텐트와 인텐트 필터 (Android Intent & Intent Filter)

 

Intent ?

 

Android App 하나 이상의 Activity 구성되어 있습니다. 두개 이상의 Activity 있는 App 경우 하나의 액티비티가 다른 액티비티를 론칭할때 사용하는 것이 Intent 입니다.

Intent 사전적 의미는 명사로서 의지,의향, 목적, 계획 등이 있습니다.

여기서 의지라는 단어가 Intent 가장 설명해주는 단어 입니다.

1 액티비티가 2 액티비티를 호출 할때 어떤 의지(요청 데이터) 담아서 호출 하는가 하는 것이 Intent 담기는 것입니다.

 

Intent 수신 액티비티에게 데이터를 전달 하기만 수도 있지만 요청된 작업이 완료되면 작업 결과 데이터를 반환하도록 구성 수도 있습니다.

 

Intent Filter ?

앱의 AndroidManifest.xml파일에 정의 되는 표현으로 해당 구성요소가 수신하고자 하는 Intent 유형을 나타냅니다.

 

 

Intent 이용한 호출 종류

 

    • 액티비티(Activity) 시작

시작할 Activity 필수 데이터를 담아 startActivity() 함수를 통해 전달 합니다.

Activity에게 요청한 작업의 결과를 수신하려면 startActivityForResult() 호출하면 됩니다. 결과 값은 onActivityResult()콜백함수에 별도의 Intent 객체로 수신됩니다.

 

    • 서비스(Service) 시작

Service 사용자 인터페이스 없이 백그라운드에서 작업을 수행하는 구성 요소로 서비스를 시작하여 작업을 수행하도록 하려면 Intent startService() 전달하면 됩니다.

다른 구성 요소로부터 서비스에 바인드하려면 Intent bindService() 전달하면 됩니다.

서비스에 관한 내용은 아래 링크를를 참조하세요

[Android강좌_007] Android Service (1회)

[Android강좌_008] Android Service (2회)

 

    • 브로드캐스트(Broadcast) 전달

브로드캐스트는 모든 앱이 수신할 있는 메시지로 시스템은 여러 시스템 이벤트에 대해 다양한 브로드캐스트를 전달 합니다. 다른 앱에 브로드캐스트를 전달 하려면 Intent sendBroadcast(), sendOrderedBroadcast() 또는 sendStickyBroadcast() 전달하면 됩니다.

 

 

Intent 유형

인텐트에는 두가지 유형이 있습니다.


    • 명시적 인텐트

시작할 구성 요소를 이름을 지정합니다.

일반적으로 본인의 안에서 구성 요소를 시작할 씁니다. 시작하고자 하는 Activity 또는 Service class명을 알고 있기 때문에 직접 호출이 가능합니다.

사용자가 Activity 시작하거나 백그라운드에서 파일을 다운로드하기 위해 Service 시작하는 등이 여기에 해당합니다.


    • 암시적 인텐트

특정 구성 요소의 명을 사용하지 않고 수행할 일반적인 작업을 선언하여 다른 앱의 구성 요소가 이를 처리 있도록 해주는 것을 의미합니다.

사용자에게 지도에 있는 위치를 표시해주고자 하는 경우, 암시적 인텐트를 사용하여 해당 기능을 갖춘 다른 앱이 지정된 위치를 지도에 표시하도록 요청할 있습니다.

 

암시적 인텐트를 생성하면 Android 시스템이 시작시킬 적절한 구성 요소를 찿습니다.

각각의 앱들은 모두 AndroidManifest.xml 파일을 가지고 있으며 여기에 Intent Filter 정의해 두고 있습니다.

Intent Filter 비교하여 일치하는 인텐트가 있으면 Android 시스템이 해당 구성요소를 시작하고 이에 Intent 객체를 전달합니다.

호환되는 인텐트 필터가 여러 개인 경우, 시스템은 대화상자를 표시하여 사용자가 실행할 앱을 직접 선택하게 있게 합니다.

예를 들어 작성한 글을 SNS 통하여 공유하고자 할때 암시적 인텐트를 사용하여 모바일에 설치 되어 있는 해당 인텐트를 받아주는 모든 SNS 뿐만 아니라 기타 다른 앱들도 선택 대상 목록으로 나타나게 됩니다.

 

만약 Activity 대한 인텐트 필터를 선언할 경우 다른 여러 앱들이 동일 인텐트를 가지고 해당 앱을 호출 있습니다.

반대로 Activity 대한 인텐트 필터를 선언하지 않을 경우 명시적 인텐트로만 Activity 시작할 있습니다



암시적 인텐트가 시스템을 통해 전달되어 다른 액티비티를 시작하는 방법을 보여주는 그림.

[1] Aactivity A 가 startActivity()를 통해 Intent를 전달

[2] Android System이 해당 인텐트와 일치하는 인텐트 필터를 찾아 모든 앱을 검색하고 일치하는 항목을 찾으면

[3] 시스템이 일치하는 Activity를 시작하기 위해 Activity B의 onCreate() 함수를 호출하여 Intent 를 전달


앱의 보안을 보장하려면 Service 를 시작할 때엔느 항상 명시적 인텐트만 사용하고 서비스에 대한 인텐트 필터는 선언하지 않는 것이 좋습니다. 암시적 인텐트를 사용하여 서비스를 시작하면 보안 위험을 초래 합니다. 

위 그림에서는 Activity 를 기준으로 설명 되어 있으나 Service 도 동일합니다. 

인텐트에 어느 서비스가 응답할 것인지 확신할 수 없고, 사용자가 어느 서비스가 시작되는지 볼 수 없기 때문입니다. Android 5.0 (API 레벨 21)부터 시스템은 개발자가 암시적 인텐트로 bindService()를 호출하면 예외를 발생 시킵니다. 하지만 이전 버전에서 호환성을 생각 한다면 암시적 인텐트 사용은 자제 하는 것이 좋습니다. 









블로그 이미지

쉬운코딩이최고

Android, Java, jsp, Linux 등의 프로그래밍 언어를 소개 합니다.

,

ANDROID Service (2)




소멸된 서비스 재시작 옵션 제어

onStartCommand() 메서드는 반드시 정수를 반환해야 합니다. 정수는 안드로이드 시스템이 서비스를 중단시킨 경우 시스템이 해당 서비스를 어떻게 것인가를 정의하는 값입니다.

반환 가능한 값은 반드시 다음 상수 하나여야 합니다.

 

START_NOT_STICKY

  • 전송 대기중인 Intent 있는 경우가 아니라면 서비스 중단 다시 시작시키지 말라고 시스템에게 전달합니다.

  • 이는 서비스가 불필요하게 실행되는 일을 피할 있게 해주는 가증 안전한 옵션입니다.

  • 애플리케이션이 완료되지 않은 모든 작업을 단순히 재시작 있을 좋습니다.


START_STICKY

  • 시스템이 onStartCommand() 메서드 반환 후에 서비스를 중단시키는 경우 서비스 소멸 최대한 빠르게 서비스가 다시 시작되어야 한다는 것을 의미 합니다.
  • 전송 대기중인 Intent 없다면 null Intent 값을 인자로 받는 onStartCommnad() 콜백 메서드가 호출됩니다.
  • 전송 대기중인 Intent 있다면 해당 Intent 전달 됩니다
  • 무기한으로 실행 중이며 작업을 기다리고 있는 미디어 플레이어 같은 애플리케이션에 적합합니다.

 

START_REDELIVER_INTENT

  • 만약 onStartCommand() 메서드의 실행 서비스를 중단시키는 경우 마지막으로 전달된 Intent onStartCommand() 호출하여 서비스가 다시 시작되어야 한다는 것을 의미 합니다.
  • 모든 전송 대기중이던 Intent 순차적으로 전달 됩니다.
  • 파일 다운로드와 같이 즉시 재개되어야 하는 작업을 수행중인 서비스에 적합합니다. 

 

■ 매니페스트 파일에 서비스 선언

MyService.java 로 정의한 서비스가 있을 경우 <application> 항목에 추가 하면 됩니다. 

아래 샘플에서는 <application> 항목 안에 <activity> 속성 아래에 추가 했습니다. 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tutorial.james.androidtutorialtest">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

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

<service android:name=".MyService" />

</application>

</manifest>

service 는 기복적으로 public 으로 선언 됩니다. 즉, 서비스가 애플리케이션 패키지 외부의 컴포넌트들이 액세스 할 수 있다는 의미 입니다. 서비스를 private 로 만들려면 android:exported 속서을 false로 추가 하시면 됩니다. 

<service android:name=".JamesService" 
android:exported="false"/>



서비스 시작

Activity 다른 구성 요소에서 서비스슬 시작하려면 Intent(시작할 서비스) startService() 함수에 전달 하면 됩니다.

그러면 Android 시스템이 서비스의 onStartCommand() 호출하고 여기에 Intent 전달합니다. (절대로 onStartCommand() 직접 호출하면 안됩니다.)

MyService.java 정의된 서비스가 있다고 가정 하고 이를 Activity 시작하려면 startService() 인텐트를 전달하면 됩니다

Intent intent = new Intent(this, MyService.class);
startService(intent);


■ 서비스 중단

시작된 서비스는 자신만의 Service Lifecycle(생명주기)를 직접 관리해야 합니다. 즉, 안드로이드 시스템이 메모리가 부족하여 서비스를 중단 시키거나는 경우가 아니라면 직접 stopSelf() 를 호출하거나 다른 구성 요소가 stopSevice() 를 호출하여 이를 중단 시킬수 있습니다. 

stopService(intent);


■ 시스템 구동 시 서비스 시작 시키기

안드로이드 시스템이 최초 부팅되는 시점에 자동으로 서비스가 시작되도록 하는 방법입니다. 

이는 BroadcastReceiver 를 이용하여 처리 가능합니다. 


방법은 다음 링크를 따라 이전에 작성한 포스팅 참조 하세요 :)

☞ 포스팅 보러 가기 



블로그 이미지

쉬운코딩이최고

Android, Java, jsp, Linux 등의 프로그래밍 언어를 소개 합니다.

,

Android Service


Android Service 사용자가 응용프로그램을 종료 하거나 다른 응용프로그램으로 전환을 하더라도 백그라운드(화면으로 보이지 않는 뒷단)에서 장시간 계속해서 동작하도록 제공하는 기능입니다. 또한 구성 요소를 서비스에 bind하여 서비스와 상호작용할 있으며 다른 프로세스간의 통신을 수행 수도 있습니다.


미디어플레이어, MP3 플레이어, 알람앱 등이 Android Service 이용한 App입니다.


Service Thread 아니며, 아래와 같이  가지 형식을 제공합니다.

 

Started Service (시작된 서비스)

Activity 또는 BroadCastReceiver 같은 다른 애플리케이션 요소들이 Context.startService() 함수를 호출 함으로써 시작되게 됩니다. Service 한번 시작되면 Service 중단되거나 리소스 해제를 위해 안드로이드 런타임 시스템에 의해 해제 되는 시점까지 백그라운드에서 무한정 실행됩니다. Service 자신을 실행시킨 애플리케이션이(우리가 일반적으로 이야기하는 App) 이상 포그라운드(사용자 입장에서 봤을 실행 - 화면을 있는 상태) 있지 않아도 백그라운드에서 실행되고 있습니다.

 

Service Context.stopService() 또는 stopSelf() 함수가 호출 되기 전까지 지속적으로 동작하게 됩니다.

Context.startService() 중복 호출의 결과로 여러 차례 호출 결과를 받게 되더라도 중복 Context.startService() 호출이 중첩되지 않아 Context.stopService() 또는 stopSelf() 한번이라도 호출 되면 Service 중단되게 됩니다.

 

Service 안드로이드 시스템에 의해 높은 우선순위가 부여되며 리소스 해제를 위해 종료될 때도 가장 마지막에 고려 대상이 됩니다.

 

Bound Service (바인드된 서비스)

애플리케이션의 구성 요소가 자신에게 바인드될 있도록 허용하는 서비스이며, bindService() 호출하여 오래 지속되는 연결을 생성합니다.

 

Started Service 유사하지만 Started Service 결과를 반환하지 않으며 자신을 호출한 컴포넌트와의 상호작용도 허용하지 않는 반면 Bound Service 자신을 호출한 컴포넌트와의 상호작용을 허용하고 결과를 받을 있습니다. , Activity Application 다른 구성요소에서 Service 상호작용하기를 원하는 경우 바인드된 서비스(Bound Service) 생성해야 합니다. Application 기능 가지를 프로세스 통신 (IPC : Interprocess Communication) 통해 다른 Application 노출하고자 하는 경우에도 좋은 선택입니다

 

클라이언트가 시작되어 bindService() 함수를 호출하면 Bound Service 바인딩 됩니다.

 

Bound Service onBind() 콜백 함수를 구현하여야 합니다. Service 최초 생성될 때와 이후에 다른 클라이언트들이 Service 바인딩 모두  onBind()  함수가 자동 호출됩니다. onBind() 함수의 목적은 바인딩한 클라이언트들에게 IBinder 타입의 객체를 반환하는 것입니다.

다시 정리 하자면 클라이언트와 Service 사이에서 쓰이는 인터페이스는 반드시 IBinder 타입의 객체의 구현이어야 하며 이를 서비스가 onBind() 콜백 메서드에서 반환해야 합니다. 클라이언트가 IBinder 수신하면 해당 인터페이스를 통해 서비스와 상호작용을 시작할 있습니다.

 

클라이언트는 바인드된 서비스를 이상 필요로 하지 않을 unbindService() 호출해야 합니다. 마지막 바인딩 클라이언트가 Service 에서 바인딩을 해제하면 안드로이드 런타임 시스템이 해당 Service 종료 시킵니다.

 

 

Service Lifecycle (서비스 생명주기)

Service 생명 주기는 Activity 생명 주기보다 훨씬 간단하지만 Service 생성하고 해제하는 방법에 특히 주의 해야 합니다. Service 사용자가 모르는 채로 백그라운드에서 실행될 있기 때문입니다.

 

Service Lifecycle  아래 이미지와 같이 서로 다른 가지 경로를 따를 있습니다. 왼쪽이 Serviced Service 이며 오른쪽이 Bound Service 입니다. 참고하세요.




1. Started Service (시작된 서비스)

다른 구성 요소가 startService() 호출하면 Service 생성됩니다. Service 무한정 실행 있으며 stopSelf() 호출하여 자체적으로 중단해야 합니다. 다른 구성 요소도 Context.stopService() 호출하여 Service 중단할 있습니다. 서비스가 중단되면 안드로이드 런타임 시스템이 이를 소멸 시킵니다.


2. Bound Service (바인드된 서비스)

클라이언트가 bindService() 호출하면 서비스가 생성됩니다. 클라이언트가 IBinder 인터페이스를 통해 서비스와 통신을 주고 받을 있으며 클라이언트가 연결을 종료하려면 unbindService() 호출하면 됩니다. 여러 클라이언트가 같은 Service 바인드될 있으며, 모두가 바인딩을 해제하면 시스템이 해당 서비스를 소멸시킵니다. (Started Service 달리 Service 스스로를 중단시키지 않아도 됩니다)

 

 

내용이 어렵게 느껴질 있겠는데요 ^^;

마지막 Service Lifecycle 부분이 Service 대한 요약이라 보시면 무방합니다.

 

 

 

Referenced By -

https://developer.android.com/reference/android/app/Service.html

https://www.tutorialspoint.com/android/android_services.htm

블로그 이미지

쉬운코딩이최고

Android, Java, jsp, Linux 등의 프로그래밍 언어를 소개 합니다.

,