이번에는 Activity 를 새로 만들고, 만든 Activity 를 시작하는 방법에 대해 알아본다.

Android 는 Activity 를 시작시킨 때 Intent 를 기반으로 하여 시작시킨다. 이 Intent 에 메인 뷰의 EditText 로 입력받은 String 을 추가하여 새로 만든 Activity 를 시작할 때 넘겨주고, Activity 는 TextView 를 포함하는 Layout (ViewGroup)을 통해 전달받은 메시지를 표시해주는 방식이다.

▌버튼 눌렸을 때 호출 될 메소드 정의하기

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/button_send"
    android:onClick="sendMessage"/>


▌새로운 Activity 실행위한 Intent 생성하기

public void sendMessage(View view) {
    Intent intent = new Intent(this, DisplayMessageActivity.class)// Intent 를 신규 생성, DisplayMessageActivity 를 실행하기 위한 Intent 를 생성함
    EditText editText = (EditText) findViewById(R.id.edit_message)// 현재 Activity 의 OnCreate 에서 처리된 Bundle 의 XML 내에 있는 id 값에 해당하는 View 를 가져옴
    String message = editText.getText().toString()// EditText 의 값 가져옴
    intent.putExtra(EXTRA_MESSAGEmessage)// EXTRA_MESSAGE 를 Key 로 하고 내용을 message 로 하는 데이터를 Intent 에 추가 함. Key-Value Pair 의 extra 를 Intent 에 추가함
    startActivity(intent);
}

public final static String EXTRA_MESSAGE "com.goodjoon.helloandroid.MESSAGE";


▌Activity 추가를 위한 과정

  1. Activity XML 생성
  2. strings.xml 에 Activity Title 추가
  3. Content XML 생성
  4. Android Manifest 에 Activity 등록
  5. Activity 클래스 작성

▌신규 Activity 추가 - Studio 의 New Activity 기능 사용하여 추가하기


원하는 Package 에서 우측클릭>New>Activity>Blank Activity 를 눌러서 Activity 를 추가한다.


Activity 이름을 주고, 중간의 Hierarchical Parent 에서 "..." 을 눌러 메인 Activity 인 HelloActivity 를 선택한다.


Hierarchical Parent

Activity 를 추가할 때 Hierarchical Parent 를 주면, 기본적인 Navigation 동작이 추가된다. up Navigation 버튼이 Navigation Bar 에 추가되고, Back 버튼을 눌렀을 때 Parent Activity 가 호출되는 등의 Action 이 실행된다.

<androidManifest.xml> 내용 중
<activity
    android:name=".DisplayMessageActivity"
    android:label="@string/title_activity_display_message"
    android:parentActivityName=".HelloActivity"
    android:theme="@style/AppTheme.NoActionBar">
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="com.goodjoon.helloandroid.HelloActivity" />
</activity>

위에서 android:parentActivityName=".HelloActivity" 가 추가된 것을 볼 수 있다.
나중에 수동으로 Activity 를 추가하면 저렇게 parentActivity 를 주면 된다.

위 과정으로 추가하면

  1. Activity XML 생성
  2. Content XML 생성
  3. AndroidManifest.xml 에 Activity 등록
  4. string.xml 에 Activity Title 등록
  5. Activity 클래스 추가

와 같은 과정이 자동으로 실행된다

  1. Activity XML 생성


  1. Content XML 생성

Content XML 이 생성되면 아래와 같이 RelativeLayout 요소의 마지막에 android:id="@+id/content" 를 하여 id 를 하나 부여해주어 Code 에서 findViewById() 로 쉽게 Layout 을 갖고오게 하자.
<?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"
    ...
    android:id="@+id/content">


  1. Activity 클래스에서 메시지 받아 출력해주기

TextView 뷰를 하나 추가하고, Intent 의 Message 를 TextView 에 출력하도록 할 것이다.
Layout XML 에 추가하는 방법 말고, Activity 클래스에서 코드로 추가하는 방법으로 해본다.

일단, 자기 Activity 를 실행시킨 Intent 내에 Extra 데이터(메시지)를 가져오고,
TextView 뷰를 생성한 다음, 이 뷰를 Layout 을 가져와 그 Layout 에 추가하는 작업을 한다.

코드는 아래와 같다. 자동 생성된 Activity 클래스의 onCreate 의 하단에 해당 내용을 추가하면 된다.
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_display_message);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view"Replace with your own action"Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    // Activity 는 자신을 시작시킨 Intent 를 가져올 수 있음
    // Intent 에서 메시지를 가져오도록 함
    Intent intent = this.getIntent();
    String message = intent.getStringExtra(HelloActivity.EXTRA_MESSAGE);

    // TextView Object 를 만든다
    TextView textView = new TextView(this);
    textView.setTextSize(40);
    textView.setText(message);

    // 만들어진 TextView 를 RelativeLayout 에 붙인다
    RelativeLayout layout = (RelativeLayout) findViewById(R.id.content);
    layout.addView(textView);

}


▌실행 결과

 


실행 결과는 위와 같다. 텍스트를 입력하고 "보내기" 버튼을 누르면 Intent 를 생성하여 ExtraData 로 Message 를 추가하고, DisplayMessageActivity 를 생성한 Intent 로 시작시킨다.(실행 보다는 '시작' 이 적합한 단어라고 생각한다)










반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,
 Auto Completion, Code Assist, Code Suggestion, Parameter Info 등등의 이름으로 불리우는 자동 완성 기능. Visual Studio 와 Visual AssistX 플러그인은 아마 현존 최고의 Assist 기능이 아닐까 생각된다. 

 XCode 의 자동완성 기능도 매우 훌륭한 편이며, Eclipse 또한 많이 괜챦아졌다. IntelliJ 를 기반으로하는 Android Studio 의 자동완성 기능이 어느정도일지 궁굼했는데, 잠깐 사용해본 결과 Eclipse 보다는 낫다는 생각이다. ^^

□ TIP - Auto Completion 관련한 단축키들

Auto Completion / Suggestion / Assist 기능들은 IDE 를 쓰는 큰 이유중의 하나이다. Android Studio 는 IntelliJ 기반의 IDE 이며, 아래와 같은 기능들을 제공한다.

- ALT+Enter (Show Intention Action)
Import 되지 않은 클래스를 Import 하려면 이 키를 사용한다. 매우 자주 사용하는 키 이다. 클래스 import 이외에도, 현재 상황에서 무언가 의도한 액션을 수행하고자 하면 가능한 액션들이 보여진다.
단순히 import 를 편하게 하려면 Settings... 메뉴에서, Editor>General 의 Auto Import 기능에서 on the fly 기능들을 켜놓으면 즉시 Import 되도록 할 수 있다.


- Ctrl+Q (Quick Documentation)
현재 Caret 이 위치한 Class 나 method 의 Document 를 보여준다.


- Ctrl+P (Parameter Info)
현재 Method 의 파라미터 정보를 보여준다. Overload 된 Method 의 Parameter Info 까지 모두 한눈에 볼 수 있어서 편리하고 자주쓰는 기능이다.


- Ctrl+Space (Basic Completion)
Basic Auto Completion 기능으로, 입력중인 내용의 자동완성 목록을 보여준다. 가장 많이 쓴다.
그런데 불행하게도 한글 키보드를 쓰는 나같은 경우는 Ctrl+Space 가 "한자" 기능에 키보드 맵핑이 되어있어 이 Basic Completion 기능이 동작하지 않는다. 그래서 나같은 경우는 Ctrl+, 로 변경해서 사용중이다.


- Shift+Ctrl+Space
SmartType Auto Completion 기능으로, Basic Auto Completion 대비 현재 Context 에 더욱 맞는 Type Completion List 를 보여준다는데, 아직까지는 잘 사용하지 않고있다. 향후에 많이 써보면서 더 알아보도록 하겠다.




□ 주의 - 자동으로 import 가 갱신되지 않을 때, 즉시 자동으로 Import 되도록 하는 방법

Eclipse 플러그인으로 동작하던 때에는 사용하는 클래스에 따라 자동으로 import 문도 optimize 해주고 했었는데, 이상하게 Android Studio 는 Optimize Import (Ctrl+Alt+O) 를 눌러도 자동으로 Import 를 시켜주지 않는다.
이럴때에는 Settings... 메뉴에서, 아래 두개 옵션을 체크해주면 일단 해결된다.


이상 단축키와 관련 메뉴에 대해서 살펴보았다. 필요한 때에 적절하게 단축키를 눌러서 생산성 있는 개발이 되도록 하자~


반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,
안드로이드의 GUI 는 View 와 ViewGroup 의 계층으로 구성된다. View 는 Button 이나 Text Field 와 같은 UI Widget 들이다. (Windows 의 UI Component 들과 같은 개념이다). View Group 은 보이지 않는 컨테이너로, Child View 들이 어떻게 배치(Lay Out) 되는지 (Grid 나 Vertical List 같이)를 정의한다.

안드로이드는 View 와 ViewGroup 의 Subclass 들을 XML 의 Vocabulary 로 제공한다. 이 XML 로 UI 요소들의 계층을 쉽게 정의할 수 있다.

Layout 은 ViewGroup 의 Subclass 들이다. 대표적으로 LinearLayout 과 같은 Subclass 가 있다.

위 그림은 View 와 View Group 의 계층적인 관계도를 도식화 한 것이다.


Linear Layout  생성

res/layout 디렉토리에서 content_hello.xml 을 연다. 기본적으로 RelativeLayout과 TextView Child View 를 사용하도록 되어있다. 현재 코드를 수정해서 Linear Layout 과 EditText View 를 사용하도록 하겠다.

현재 안드로이드가 지원하는 Layout 에 대해서는 ViewGroup 클래스의 Child Class 들을 보면 알 수 있다.

  1. XML 에서 <TextView> 요소를 삭제한다
  2. <RelativeLayout> 요소를 <LinearLayout> 요소로 변경한다
  3. Layout 요소의 android:orientation 속성을 추가하고 "horizontal" 로 값을 준다
  4. Layout 요소의 android:padding 과 tools:context 속성들을 모두 삭제한다

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="horizontal"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/activity_hello">

위와 같은 코드로 Layout 정의가 변경되어야 한다.

LinearLayout 은 View Group 이며 (ViewGroup의 Subclass), View 들을 android:orientation 속성값에 따라 Vertical 이나 Horizontal 하게 레이아웃 할 수 있다. Linear Layout 의 Child 요소들은 XML 에 정의된 순서대로 표시된다.

android:layout_width, android:layout_height 는 ViewGroup 의 Nest 클래스인 LayoutParams 클래스의 XML 속성으로, 모든 View 들은 이 속성을 사용하여 Size 를 지정하여야 한다.

LinearLayout 이 Layout 의 Root View 이므로, 앱 이 가능한 전체 스크린 사이즈로 크기를 지정한다 ("match_parent" 를 쓰면, 부모 뷰의 크기와 동일한 크기의 width 와 hegith 를 지정하게 된다).


Text Field 추가

모든 View 가 그렇듯, EditText 객체에도 특정 XML 속성을 추가해주어야 한다.

  1. content_hello.xml 에서 <LinearLayout> 요소의 하위 요소로 <EditText>요소를 추가한다.
  2. <EditText> 요소의 속성에 id 를 추가하고, 값을 @+id/edit_message 로 입력한다
  3. layout_width 와 layout_height 는 wrap_content 로 정의한다.
  4. hint 속성으로 edit_message 라는 String 객체를 값으로 넣어준다 (@string/edit_message)

<EditText android:id="@+id/edit_message"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:hint="@string/edit_message" />

그러면 위와 같은 코드가 될것이다.

각 속성에 대한 설명을 하면, 

  • android:id
    View 에 대한 유일한 식별자를 부여하는 것이다. 이 ID 를 통해 View 객체로부터 값을 읽거나 객체를 조작할 수 있다.
    @ 는 XML 에서 모든 리소스 객체를 참조할 때 사용하는 식별자이다.
    android:id="@<리소스타입>/<리소스이름>" 의 형태로 사용한다.
    + 는 리소스 ID 를 처음으로 정의할 때에만 사용한다. 앱을 컴파일할 때 SDK 툴은 프로젝트의 gen/R.java 파일에 EditText 를 참조하는 새로운 리소스 ID 를 만들 때 이 식별자를 사용한다.
    그러나, 리소스 ID 가 생성된 이후 부터는 + 기호를 붙이지 않는다. 또한 String 이나 layout 같은 실체가 있는 리소스에는 사용하지 않는다.

  • android:layout_width, android:layout_height
    특정 사이즈를 입력하는 대신에 "wrap_content"를 사용하면 View 의 Content 크기에 맞게 View 크기가 결정된다. 만약 "match_parent"를 썼다면 View 는 전체 스크린 사이즈로 생성될 것이다. 왜냐하면, EditText의 부모 View 가 LinearLayout 이고 이 Size 는 앱의 전체 화면크기가 되기 때문이다.

  • android:hint
    Text Field 에 값이 없을 때 기본으로 표시되는 값이다. 값을 하드코딩 하는 대신에 "@string/edit_message"와 같이 해주면, 값은 String 리소스가 정의된 분리된 파일을 참조한다.

    hint 의 리소스 객체 이름이 위의 ID 요소와 같다(edit_message). 그러나 리소스 타입이 다르므로 충돌이 발생하지 않는다.


리소스 객체

리소스 객체(Resource Object)는 앱 리소스와 연관된 비트맵, Layout 파일, String 등의 유일한 Integer 이름이다.
모든 리소스는 gens/R.java 내에 상응하는 리소스 객체가 정의된다. R 클래스 내의 객체 이름을 사용하여 android:hint 와 같은 리소스를 참조할 수 있다.
또한 View 와 연계되는 임의의 리소스 ID 를 android:id 를 통해 생성할 수 있다. 
SDK Tool 은 매 컴파일 마다 R.java 파일을 생성한다. 이 파일을 수동으로 편집하지 말아야 한다. 


String Resource 추가

기본적으로 프로젝트에는 res/values/strings.xml 파일이 추가되어있다. 여기에 "edit_message" 라는 리소스 이름의 새로운 String 객체를 만들고, 값을 "메시지 입력" 이라고 설정할 것이다.

<resources>
    <string name="app_name">Hello Android</string>
    <string name="edit_message">메시지 입력</string>
    <string name="button_send">보내기</string>
    <string name="action_settings">설정</string>
</resources>

위와 같이 res/values/strings.xml 파일을 편집한다. 이후에 할 작업들이 더 있는데, 여기에서 사용할 추가적인 String 리소스 객체들도 넣어주었다.

Button 추가

메시지 Send 버튼을 하나 추가해본다. 아래와 같이 context XML 에 Edit Text 다음에 Button 요소를 하나 추가한다.
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/button_send" />

버튼 Size 는 wrap_content 로 버튼 내부의 컨텐츠 사이즈에 자동으로 버튼 크기를 맞추도록 했다.

Preview 에서 보이는 화면의 일부이다. 


그런데 영 모양이 좋지가 않다. 메시지 입력하는 부분이 wrap_content 사이즈를 갖기때문인데, 다음 과정에서 좀더 보기좋게 모양을 변경해 보도록 한다.

화면 넓이 만큼 Input Box 채우기

Android 의 View 들은 layout_weight 라는 개념이 있다.
특정 수치에 의한 고정값을 사이즈로 주는것이 아니라 한줄에 들어갈 View 간에 사이즈 비율을 주는 것이다. 예를 들어 EditText 의 Weight 가 2 이고 Button 이 1 이면 2:1 의 화면 비율로 채우란 이야기이다.
기본값은 0 으로, weight 의 비율이 설정되지 않는다.

만약 여기에, EditText 를 weight 1 로 주고, Button 의 width 가 wrap_content 라면, Button 의 wrap_content 에 의해 계산된 사이즈를 뺀 나머지 크기를 EditText 가 모두 채우게 된다.
<EditText android:id="@+id/edit_message"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:hint="@string/edit_message"
    android:layout_weight="1"/>

위와 같이 코드를 작성하되, EditText 의 layout_width 가 기존의 wrap_content 에서 0dp 로 변경된것을 유의해서 보아야 한다. EditText 의 weight 를 주었으므로 궂이 layout_width 를 wrap_content 로 하여 컨텐츠 영역의 넓이를 계싼하게 할 필요가 없다. 이는 성능상의 이유로 0dp 를 주어 계산을 건너뛰게 한것이다.


Preview 에서 위와 같이 보이게 되고,


실제 디바이스에서는 위와 같이 표시된다. (갤럭시 노트 4 / 안드로이드 5.1.1 Lollipop MR1 / API Level 22)


반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,
안드로이드 프로젝트가 생성 되었으니, 이번에는 바로 실행으로 들어가본다. 일단 환경 설정이 잘 되었는지 확인도 할 겸~

디바이스 설정

USB 디버깅 옵션을 켜놓아야 함
 - Android 3.2 이전 버전은 주로 Settings>Applications>Development 
 - Android 4.0 이상은 Settings>Developer options 로 있음
   4.2 이상의 디바이스 에서는 Developer Option 이 숨겨져 있는 경우가 많은데, Settings>About Phone 안에서 Build Number 을 7번 탭하면 Developer Option 이 나타난다.

PC 에 연결하기 위해 Vendor 에서 제공되는 드라이버를 설치해야 하는 경우도 있다.

Android Studio 에서 실행

Run 버튼 

 을 눌러서 실행시키거나 Shift+F10 으로 실행하면 Run 이 실행되고, Debug Run 하고 싶다면 Run 옆의 Debug 버튼(Shift+F9)을 누른다.


Command Line 에서 실행

Project 루트 디렉토리 안에 gradlew.bat 파일을 이용하여 Gradle 을 통해 빌드할 수 있다.

디버그 모드로 빌드하려면
> gradlew.bat assembleDebug

릴리즈 모드로 빌드하려면
> gradlew.bat assembleRelease

빌드 된 .apk 파일은 <프로젝트루트>/app/build/outputs/apk 안에 위치한다.

디바이스에 설치하려면
> adb install app/build/outputs/apk/app-debug.apk

와 같이 한다. 단, 이때 adb 는 <Android SDK>/platform-tools 디렉토리가 PATH 에 잡혀있어야 한다


Emulator 로 실행

아래 이미지 캡춰만으로도 이해가 충분히 갈테니 긴 설명은 하지 않겠다.







그런데 이렇게 만들어놓은 AVD 가 실행을 해보면...


뭐 이런경우가 있나 하고 찾아보니, x86 CPU/ABI 가 AVD 만들 때 기본 선택되었고, 이때는 Intel HAXM 을 별도로 설치 해주어야 한단다.


이렇게 Extras 에서 추가요소를 선택하여 설치하고나면,


SDK\extras\intel\Hardware_Accelerated_Execution_Manager\intelhaxm-adnroid.exe 파일이 있다. 이걸 실행시켜서 설치하면..

위처럼, 내 컴퓨터는 AMD CPU 이고, VT-x 를 지원하지 않는다. 이럴때는 별 수 없다. 그냥 AVD 만들 때 ARM 기반의 Device 를 만들어서 쓰는 수밖에 없다. Hardware Acceleration 을 쓸 수 없고, 그나마 AMD 는 Linux 에서만 이 기능이 지원된단다.

Hardware Acceleration 을 쓸 수 있는 Intel Machine 이라면 여기를 참조한다.

다른 방법은 Genymotion 과 같은 별도의 Emulator 를 다운로드 받는 방법이 있다.
(조만간 내 구닥다리 AMD 에서 Hardware Acceleration 이 가능해지면 내용을 추가하겠다)


반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,
이번에는 이전에 생성한 프로젝트 내부의 구조에 대해 살펴보도록 한다.

Project 를 만들고 나면, 좌측의 Project View 를 통해서 res/layout 디렉토리에 생긴 메인 Activity (New Project 에서 생성한)를 열어본다.

위와 같은 구조의 프로젝트 내 파일들이 보이게 된다.


Activity Layout

Activity 의 Layout 을 정의하는 XML 이며, Design 과 Text (코드)를 볼 수 있는 Tab 이 모두 존재한다.


이 Activity Layout XML 에는 앱 상단의 앱바와 Floating Action Button 같은 (향후에 더욱 자세히 보도록 하고) 컴포넌트의 속성이 XML 의 Element 와 Attribute 로 설정되어있다

위 처럼 기본적인 Blank Activity 를 생성하면 Action Bar, Content, Floating Action Button 이 생성된다.

Activity 의 전체적인 Layout 은 activity XML 에 정의가 되고, TextView 로 구성된 Content 영역은 content XML 에 정의되어있다. 

Activity XML 의 중간 쯤에 보면

<include layout="@layout/content_hello" />

이 들어가 있고, 이렇게 content_hello 라는 Layout 요소를 추가적으로 포함(include) 하도록 되어있다. 그리고, content_hello.xml 파일을 보면

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
</RelativeLayout>

위 처럼 TextView Element 로 추가적인 Layout 이 구성됨을 볼 수 있다. 텍스트 내용으로 "Hello World!" 라는 텍스트도 보인다.


Main Activity.java

app\src\main\java\com\goodjoon\helloandroid\HelloActivity.java 파일을 열어본다. 
현재 Main Activity 는 HelloActivity 로 등록되어 있으며. Activity XML 리소스 파일이 이 java 파일에 연결되어 있음을 확인할 수 있다.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_hello); 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

앱을 실행시키면 이 Activity 클래스가 실행되고 Main Activity XML 리소스가 로드되어 Hello World! 가 출력되는 메인 Activity 가 나옴을 확인할 수 있다.


앱 Manifest

app\src\main\AndroidManifest.xml 파일은 앱의 기초적인 특성과 각 컴포넌트를 정의하는 파일이다. 컴포넌트를 추가하면 이 파일이 지속적으로 변경되게 된다.


Gradle 빌드파일

app\build.gradle 파일은 Project View 에서는 "Gradle Scripts" 라는 별개의 그룹으로 표시되는데, 실제 위치는 app\ 디렉토리 밑에 존재한다.

Android Studio 는 앱을 컴파일 하고 빌드하는데에 Gradle 을 사용한다. 

프로젝트의 각 모듈 별로 build.gradle 파일이 존재하며 프로젝트 전체에 또 하나의 build.gradle 파일도 존재한다. 보통 각 모듈 내의 build.gradle 파일이 주요 관심 대상이 된다. 지금 모듈은 app 모듈이다.


위의 build.gradle 은 프로젝트 전체에 대한 build.gradle 스크립트 (프로젝트디렉토리\build.gradle)이고, app 모듈에 대해 build.gradle 파일(프로젝트디렉토리\app\build.gradle)이 추가적으로 존재한다.

Module build.gradle 파일 안에 보면 defaultConfig 을 포함한 몇가지 설정이 있다


apply plugin'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.goodjoon.helloandroid"
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir'libs'include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
}

  • compileSdkVersion 
    앱을 Compile 하기 위해 사용하는 Platform SDK 의 버전을 명시한다. 기본적으로 설치되어있는 SDK 버전 중 가장 최신의 SDK 를 사용하도록 설정되어있다. 위 설정에서는 API Level 23 (=SDK Version 23 = Android 6.0 = 마쉬멜로우) SDK 를 사용하도록 되어있으므로, 만약 SDK 가 설치되어있지 않다면, SDK Manager로 SDK 를 설치해야 한다.
    SDK 버전이 높다고 해서 구버전 앱을 빌드할 수 없는게 아니며(하위호환성 유지) 오히려 낮은 버전의 SDK 로 빌드하게 되면 더 높은 버전의 Platform 에서는 새로운 기능을 사용할 수 없거나 더 좋은 UX 를 사용할 수 없게된다.
  • applicationId
    New Project Window 에서 지정했던 Package 이름으로, App 의 유일한 식별자이다.
  • minSdkVersion
    현재 앱이 지원하는 가장 낮은 SDK 버전을 지정
  • targetSdkVersion
    현재 앱이 지원하는 가장 높은 SDK 버전. 자신이 테스트해본 가장 높은 버전을 명시하면 된다


기타 리소스

  • drawable-<density>/ 리소스 디렉토리 <ldpi(0.75), mdpi(1.0), hdpi(1.5), xhdpi(2.0)>
    이 디렉토리에는 밀도 독립 픽셀(DIP: Density Independent Pixel)별 drawable 이미지나 아이콘 같은 "그려지는" 리소스가 위치한다. DIP 에 대해서는 나중에 더 설명하도록 하자. 일단, Android 는 다양한 해상도를 갖는 기기가 많으므로, pixel (px) 단위가 아닌 dp 나 sp 단위로 크기를 지정해야 한다.
    참조는 @drawable/image.png 와 같이 사용한다.

  • layout/
    activity XML 과 같이 앱의 UI 를 정의하는 파일들이 위치한다. 

  • menu/
    앱의 메뉴 아이템을 정의하는 파일들이 위치

  • mipmap/
    Launcher 아이콘(앱아이콘)으로, drawable/ 폴더 대신 이 폴더를 사용한다. ic_launcher.png 아이콘 이미지들이 해상도별로 들어있다.

  • values/
    String 이나 Color 정의와 같은 리소스 컬렉션을 포함하는 XML 파일들이 위치하는 디렉토리 이다.




반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,


 4년 간 Hybrid Mobile App 개발도구를 포함한 MEAP 솔루션 개발을 리딩해왔지만 모바일쪽 개발은 주로 iOS 만을 해왔다. 안드로이도 개발은 직접 하지 않았는데, 올해 사적인 프로젝트를 하나 진행하기 위해 안드로이드쪽 앱을 직접 개발하지 않으면 안되는 상황이다.

 작년 초반 까지만 해도 Eclipse에 Android Development Tools 플러그인을 설치하고, XCode 의 Command Line Build 를 함께 쓰도록 하여 Hybrid App 개발툴킷을 만들었지만 작년 중반 이후에 Google에서 Android Studio 만을 사용하도록 강력히 밀고있는 상황이라 난 Android Studio 를 사용하기로 결정했다.

 일단, Android Studio 를 다운로드 받는다


■ 신규 프로젝트 생성

Android Studio를 설치 후 실행하면, 아래 처럼 New Project Window 가 실행된다

처음 프로젝트를 시작하므로, "Start a new Android Studio Project" 를 선택


New Project 화면에서의 요소별 설명은 다음과 같다

  • Application Name - 사용자에게 보여질 앱 이름이다
  • Company Domain - 실제 Domain 일 필요는 없고, App 을 구별하기 위한 Package ID 의 base 값 정도로 생각하면 된다. goodjoon.com 을 넣으면 자동으로 Package Name 이 com.goojoon.<소문자 기반으로한 앱 이름>
  • Package Name - Application Name 과 Company Domain 을 조합하여 만든 Package 이름이다. 이게 Android App 을 식별하는 유일한 이름이 된다

※ 한글 앱 이름

앱 이름이 한글이면, Package Name 이 자동생성 되지 않는다 이때는 Package Name 우측에 보이는 "edit" 를 클릭하여 수동으로 패키지 이름을 변경해주면 된다.

또한 가급적이면 Project location 에 한글명이 들어가는 경로는 피하도록 하자.


이제 Target Android Device 를 선택한다. Minimum SDK 목록을 보면 이제 친절하게도 API Level 과 함께 OS 이름도 나온다. 이 SDK 를 잘 설정해주어야 나중에 어떤 버전 기기에서는 보이네 안보이네 하는 문제에서 자유로울 수 있다.


더 놀라운것은, SDK 를 선택하면, 세계적으로 해당 SDK 버전 이상의 OS 사용자 비율을 보여준다는 것이다. 위 화면에서는 4.2 젤리빈으로 개발하면 전세계 약 81.4% 의 Android 기기에 설치될 수 있는 앱을 개발할 수 있음을 보여준다


이제 이렇게 SDK 까지 선택한 후, 처음 실행 될 Activity 를 선택하는 화면이 나온다. 다음 편에서는 Android 의 Activity 가 무엇인가 부터 찬찬히 살펴보도록 하겠다





반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,
오늘 코딩을 하다가, retainCount 값을 찍어보는 테스트 코드를 작성했다.
그런데, 예상하지 못한 결과가 나온다..

코드는 이렇다.

- (IBAction) onTouchUpTest:(id) sender
{
    // NSString Object
    NSString* pString = [[NSString alloc] initWithString:@"Some String"];

    NSLog(@"String ==> %@", pString);
    NSLog(@"Retain : %08X", [pString retainCount]);
    [pString release];
    NSLog(@"Released .. Retain 2 : %d", [pString retainCount]);
    pString = nil;
    NSLog(@"Released .. Retain 3 : %d", [pString retainCount]);
    NSLog(@"Release again");
    [pString release];
    NSLog(@"Second Release OK");
   
   
    //=== 일반 Object
    LHttpCommManager* pManager = [[LHttpCommManager alloc] initWithServerInfo:@"ABC"];
    NSLog(@"Retain for Manager : %d", [pManager retainCount]);
    [pManager release];
    NSLog(@"Retain after release : %d", [pManager retainCount]);
    pManager = nil;
    NSLog(@"Retain after allocating nil : %d", [pManager retainCount]);
}

출력 결과는 참으로 웃긴다.

2010-10-12 23:14:54.331 TestBed[9108:207] String ==> Some String
2010-10-12 23:14:54.332 TestBed[9108:207] Retain : 7FFFFFFF
2010-10-12 23:14:54.333 TestBed[9108:207] Released .. Retain 2 : 2147483647
2010-10-12 23:14:54.334 TestBed[9108:207] Released .. Retain 3 : 0
2010-10-12 23:14:54.335 TestBed[9108:207] Release again
2010-10-12 23:14:54.335 TestBed[9108:207] Second Release OK

2010-10-12 23:14:54.336 TestBed[9108:207] Retain for Manager : 1
2010-10-12 23:14:54.337 TestBed[9108:207] Retain after release : 1
2010-10-12 23:14:54.337 TestBed[9108:207] Retain after allocating nil : 0

결과를 보면, 몇가지 주의해야 할 점들이 보인다.

1. NSString 의 경우, retainCount 가 7FFFFFFF 값으로, 양의 정수 최대치가 들어온다.
2. NSString 을 Release 하더라도, retainCount 가 줄어들지 않는다.
3. nil 을 할당 한 후에도, release 나 retainCount 함수가 nil 인 Object 에 대하여 실행 된다
4. 일반 Object 는 retainCount 가 최초 1이 제대로 들어온다.
5. release 를 한다고 해도, 바로 retainCount 가 줄어들지 않는다.

==> 결론은, retainCount 를 너무 의식하거나, 이를 기반으로 코딩하지 말아야 한다.
==> release 할 Object 가 nil 인지 검사하고 release 를 호출 할 필요는 없다

위 두가지의 값진 교훈을 오늘 얻게 되었다.!
반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,

출처 : http://www.iwiz.pe.kr/bbs/zboard.php?id=webdev&page=1&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=headnum&desc=asc&no=4

 

IE6에서의 개인정보보호(P3P) 구현과 쿠키 관련 문제점

1. P3P

(1) P3P의 개념

  P3P(Platform for Privacy Preferences)는 W3C에서 개발한 프라이버시 보호 관련 표준 기술이다.  P3P에 대한 상세한 설명은 뉴스&이슈란을 참고하면 되며, 그 개념을 쉽게 설명하자면 식품등에 붙어있는 일종의 "성분표시"라고 할 수 있다.  P3P를 적용한 사이트에서는 HTTP 헤더 또는 링크된 XML 파일을 통해 해당 사이트에서 취급하는 게인정보의 레벨이나 성격 등을 웹브라우져에게 알려주고 있다.  실제 사이트상에서의 P3P의 적용은 기술적으로는 별로 어렵지 않으나 "개인정보보호"라는 용어에서 느껴지듯 정책적인 측면이 매우 강하고 까다롭다.  또 계속 읽다보면 느끼겠지만 부적절한 번역 등으로 인해 각종 용어들이 무척 어렵게 느껴질 것이다.  그러나 실제로 그렇게 어려운 개념은 아니다.  단지 이해하기 힘들뿐...

  현재 우리나라에서는 회원들이나 방문객들의 개인정보를 보유하고 있는 웹사이트들은 의무적으로 "개인정보보호지침"을 기재하도록 법률로 정해져 있다.  이런 개인정보보호지침은 사람이 그 내용을 읽고 이해할 수 있도록 되어있지만, P3P는 이와는 반대로 웹브라우져 등의 소프트웨어에서 해당 사이트의 개인정보보호 지침을 인식할 수 있도록 규정되어 있다.  즉, 기계 차원에서 접속한 사이트의 개인정보 보호지침을 인식하고 현재 사용자가 설정해둔 허용값과 비교해본 후 허용, 제한, 강등, 금지 등의 조치를 자동으로 취하게 되는 것이다.

  P3P는 아직 법률과 같은 규정에 의해 강제되고 있는 사항이 아니기 때문에 모든 사이트에 적용해야할 의무는 없으나, 현재 MSIE 6.0에서 이 기능이 부분적으로 탑재되어 있기 때문에 웹프로그래머로서는 이를 무시할 수 없다.  MSIE 6.0에서부터 발생하는 쿠키 관련 문제 등의 상당 부분이 바로 이 P3P와 연관되어 있기 때문이다.

(2) P3P의 구현

  실제 웹사이트에서 P3P를 구현하기 위해서는 개인정보 보호정책이 담긴 XML 파일을 페이지에 링크하거나, 또는 압축된(Compact) 개인정보보호정책이라 불리는 HTTP 헤더값을 이용하는 방법이 있다.  XML의 경우에는 다음과 같은 방법으로 XML 파일의 URL을 지정하면 P3P를 지원하는 브라우져에서 해당 파일을 읽어와 사이트의 개인정보보호정책을 이식하게 된다. (XML파일의 스펙은  http://www.w3.org/TR/P3P 참고)

  • HTTP 헤더 이용 방법 : P3P: policyref="http://test.com/p3p.xml"
  • 태그 이용법1 : <meta http-equiv="P3P" content='policyref="http://w.about.com/w3c/p3p.xml"'>
  • 태그 이용법2 : <link rel="P3Pv1" href="http://w.about.com/w3c/p3p.xml" type="text/xml"> 

  그리고 압축된 정책은 HTTP 헤더값에 한줄로 간략하게 넣는 형태로서 헤더값은 [P3P: CP='CAO PSA CONi OTR OUR DEM ONL'] 과 같은 형식으로 구성되어 있다.  실제로 우리가 사용하고자 하는 것도 바로 이 압축된 정책이다.  지금 IE에서 [도구]-[인터넷 옵션]-[개인정보] 메뉴를 보라.  개인정보 설정이 디폴트값인 보통으로 되어 있다면 "압축된 개인정보 보호정책이 없는 제3사 쿠키를 차단합니다"라는 문구를 볼 수 있을 것이다.  이제 "압축된 개인정보 보호정책"이란 무엇인지 이해가 되는가? (굵은 글자는 꼭 외워야 한다.)

  우리의 목적은 P3P를 실제 사이트에 적용하는 것이 아니라 P3P의 개념을 이해하여 웹프로그램상의 쿠키 적용 등에 있어 IE6에서 발생하는 문제를 막고자하는데 있으므로 굳이 P3P의 스펙을 이해할 필요는 없다. (그러기엔 너무 난해하고 까다롭다. 고로 나도 모른다.)  따라서 개인적으로 개인정보보호에 각별한 관심이 있다면 이쯤에서 이 글을 읽는 것을 중단하고 MSDN이나 W3C의 P3P 공식 사이트를 뒤져보기 바란다.

2.  MSIE 6에서의 P3P 구현

  마이크로스프트에서는 IE6에서 구현된 개인정보 보호기능과 관련해 공식적으로 다음과 같이 밝히고 있다.  (귀찮으면 읽지 않아도 된다.  한마디로 요약하자면 IE6로 쿠키를 보내려면 P3P 압축 정책을 사용하라는 말이다.)

"Internet Explorer 6의 개인 정보 기능에서 쿠키를 성공적으로 사용하려면 웹 서비스는 W3C(World Wide Web Consortium)에서 개발한 개인 정보 기본 설정용 플랫폼(P3P: Platform for Privacy Preferences) 프로젝트에 정의된 대로 압축 정책을 구축해야 합니다. Internet Explorer 6 개인 정보 기능은 이러한 압축 정책과 사용자의 개인 정보 설정에 기초하여 쿠키를 필터링합니다. 이 문서는 해당 사이트와 연관된 쿠키의 개인 정보 요구 사항 및 Internet Explorer 6에서 구현되는 쿠키 필터링에 대해 설명합니다. 일부 쿠키에는 압축 정책이 필요하지 않을 수도 있지만, 모든 쿠키에서 정책을 구현하는 것이 바람직합니다."

  IE6에서는 P3P를 이용해 개인정보 보호기능을 구현하고 있으며, 이에 따라 압축정책이 없는 쿠키들은 경우에 따라 거부될 수도 있다.  IE 6 발표 후 기존 사이트에서 빈번한 쿠키 관련 문제들이 바로 여기에 기인하고 있다.  IE6의 개인정보 보호기능은 [도구]-[인터넷 옵션]-[개인정보]를 통해 그 레벨을 조절할 수 있는데, 레벨별 제한 수준은 다음과 같다.

선택 지정
모든 쿠키 차단 - 모든 웹 사이트의 쿠키를 차단합니다.
- 사용자 시스템에 있는 쿠키는 웹 사이트에서 읽을 수 없습니다.
높음 - 압축 정책(컴퓨터가 읽을 수 있는 압축된 개인 정보 보호 정책)을 갖고 있지 않은 모든 웹 사이트의 쿠키를 차단합니다.
- 사용자의 명시적 동의 없이 개인 식별 정보를 사용하는 모든 웹 사이트의 쿠키를 차단합니다.
보통 높음 - 압축 정책(컴퓨터가 읽을 수 있는 압축된 개인 정보 보호 정책)을 갖고 있지 않은 제 3 사 웹 사이트의 쿠키를 차단합니다.
- 사용자의 명시적 동의 없이 개인 식별 정보를 사용하는 제 3 사 웹 사이트의 쿠키를 차단합니다.
- 사용자의 묵시적 동의 없이 개인 식별 정보를 사용하는 제 1 사 웹 사이트의 쿠키를 차단합니다.
보통 - 압축 정책(컴퓨터가 읽을 수 있는 압축된 개인 정보 보호 정책)을 갖고 있지 않은 제 3 사 웹 사이트의 쿠키를 차단합니다.
- 사용자의 명시적 동의 없이 개인 식별 정보를 사용하는 제 3 사 웹 사이트의 쿠키를 차단합니다.
- 사용자의 묵시적 동의 없이 개인 식별 정보를 사용하는 제 1 사 웹 사이트의 쿠키를 Internet Explorer를 닫을 때 사용자 시스템에서 삭제합니다.
낮음 - 압축 정책(컴퓨터가 읽을 수 있는 압축된 개인 정보 보호 정책)을 갖고 있지 않은 제 3 사 웹 사이트의 쿠키를 차단합니다.
- 사용자의 묵시적 동의 없이 개인 식별 정보를 사용하는 제 3 사 웹 사이트의 쿠키를 Internet Explorer를 닫을 때 사용자 시스템에서 삭제합니다
모든 쿠키 허용 - 모든 쿠키를 사용자 시스템에 저장합니다.
- 사용자 시스템에 있는 쿠키는 이 쿠키를 만든 웹 사이트에서 볼 수 있습니다.

  여기에서 배경색이 다른 "보통" 레벨이 바로 대부분의 IE6 이용자들의 설정이다. (이유는 단지 디폴트값이므로...)  여기에서 MS식 번역으로 쿠키의 종류를 알아볼 필요가 있다.

  • 제1사 쿠키 : 현재 보고 있는 사이트에서 제공하는 쿠키이다.  즉 현재 sme.or.kr을 보고 있다면 sme.or.kr에서 보내온 쿠키가 바로 제1사 쿠키이다.
  • 제3사 쿠키 : 현재 보고 있는 사이트가 아닌 다른 사이트에서 보내온 쿠키이다.  이것은 img 태그나 frame 또는 iframe 등을 통해 다른 사이트의 컨텐츠를 링크해왔을 경우 해당 컨텐츠에서 쿠키를 보내오면 제3사 쿠키로 취급된다. (제2사 쿠키가 없는 이유는 제3사 라는 용어가 바로 third-party의 번역이기 때문이다 -_-)
  • 영구쿠키(지속성쿠키) : 쿠키의 만료일자가 지정되어 임시파일 디렉토리에 텍스트 파일 형태로 남게되는 쿠키로서 브라우져가 닫혀도 삭제되지 않는다. (그러나 만료일자가 되면 삭제되므로 엄밀히 따지면 영구히 존재하지는 않는다.  이 세상에 영원한 것은 없는 법...)
  • 임시쿠키(세션쿠키) : 쿠키의 만료일자가 지정되지 않아 브라우저가 닫히면 자동으로 삭제되는 쿠키로 메모리상에만 존재한다.
Internet Explorer 6은 제1 컨텐트를 호스트 도메인과 연관된 것으로 정의합니다. 제3 컨텐트는 호스트 도메인 이외의 도메인에서 만들어집니다. 예를 들어, 주소 표시줄에 www.wideworldimporters.com을 입력하여 이동했더니 이 사이트에 www.wingtiptoys.com의 배너 광고가 떠있다고 가정해 보십시오. 이 두 사이트에 쿠키를 설정할 경우, www.wideworldimporters.com의 쿠키가 제1 컨텍스트 쿠키이고 www.wingtiptoys.com의 쿠키가 제3 컨텍스트 쿠키가 됩니다.

이따금 상업용 웹 페이지에는 제1 컨텐트와 제3 컨텐트가 혼재해 있습니다. Internet Explorer 6 개인 정보 기능은 제1 컨텐트와 제3 컨텐트를 구별합니다. 이 때 근간이 되는 가정은 사용자의 제1 및 제3과의 관계가 서로 다르다는 것입니다. 실제로 사용자는 제3을 알지 못할 수도 있고 제3과 새로운 관계를 설정할 것인지 선택할 수도 있습니다. 이러한 이유 때문에 제3 컨텐트에 대한 기본 개인 정보 설정은 제1에 대한 설정보다 엄격합니다.

참고 www.wideworldimporters.com 및 toys.wideworldimporters.com은 둘 다 wideworldimporters.com이라는 동일한 최소 도메인을 갖고 있습니다. 동일한 최소 도메인을 호스트 도메인으로 공유하는 컨텐트를 제1 컨텐트로 간주하며, 마찬가지로 이러한 도메인에서 설정된 쿠키는 제1 쿠키로 간주합니다. 최소 도메인은 동일한 최상위 도메인(TLD)을 가져야 합니다. .com, .net, .org 등을 일반적인 TLD의 예로 들 수 있습니다.

참고 사용자가 HTTPS(Secure Hypertext Transfer Protocol)을 사용하여 보안 연결을 통해 www.wideworldimporters.com을 방문할 경우, HTTPS를 사용하지 않는 이 페이지의 컨텐트를 제3 컨텐트로 간주합니다.

  이제 용어가 정리되었으면 다시 보통 수준의 개인정보 보호 레벨을 보자.  "압축 정책을 갖고 있지 않은 제 3 사 웹 사이트의 쿠키를 차단합니다."라는 말이 무슨 뜻인지 이해가 되는가?  이게 도대체 우리와 무슨 관계가 있을까?  매우 중요한 관계가 있다.

  이 P3P를 처음으로 들여다보게 된 계기는 수록업체 홈페이지들의 게시판에 글을 쓸때 에러가 나는 문제로 인해 정대리님의 지시를 받아 조사에 착수했었다.  현재 업체 게시판의 경우에는 게시판 자동등록기를 막기 위해 글 입력 폼에 들어가면 쿠키를 하나 보내고, 이후 폼이 submit 되면 해당 쿠키가 존재하는지 여부를 확인해 실제로 글을 등록하게 되어 있다.  따라서 글쓰기 폼을 거치지 않고 자동등록기 등을 통해 바로 submit 하게 되면 차단이 되게 만들어져 있다.  그러나 IE6 이용자의 경우에는 개인정보 보호기능 때문에 쿠키가 차단되어 정상적으로 글쓰기 폼을 거쳐와도 쿠키가 없기 때문에 에러가 난다.  바로 "압축 정책을 갖고 있지 않은 제 3 사 웹 사이트의 쿠키"이기 때문이다.  홈페이지 URL은 업체명을 딴 aaa.co.kr이지만 게시판 부분은 sme.or.kr에서 링크해오기 때문에 제3사 쿠키가 되버리기 때문이다.

  비단 게시판 문제뿐 아니라 아직 리포트되진 않았지만 sme.or.kr, smipc.or.kr, koreasme.org 등 여러가지 도메인이 혼용되어 서로 링크를 걸어가며 사용하는 사이트의 성격상 어느곳에서 이와 유사한 문제가 나타날지는 알 수 없다.  따라서 쿠키를 보낼때는 반드시 "압축된 정책"을 사용하는 것이 문제를 피할 수 있다.  이것은 매우 간단하게 프로그램 앞 줄에 다음과 같은 한줄만 추가시켜 주면 된다.

[PHP] header ("P3P: CP='ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI'");

  다른 언어도 이와 유사하게 HTTP 헤더값을 추가시켜주면 된다.  그런데 문제는 PHP에서 이 코드를 넣고 헤더분석 프로그램으로 테스트해본 결과 이 헤더값이 실제로 브라우져로 날아가지 않았다. (이유는 모른다... -_-)   더군다나 중기관의 수많은 프로그램 코드중 어떤 프로그램 소스에서 쿠키를 발급하는지 찾는것도 쉬운 일이 아니다.  따라서 가장 확실한 방법은 웹서버 차원에서 이 헤더를 뿌려주는 방법이다.  웹서버에서 뿌려주면 기존 프로그램 소스 수정없이 모든 프로그램에 적용될 것이다.   Apache에서는 httpd.conf에 다음과 같은 라인을 추가시켜 주면 된다.  (현재 SME 서버에 적용되어 있다)

<IfModule mod_headers.c>
Header add P3P "CP='ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI'"
</IfModule>

  Header add 라인은 한 줄로 주욱 써야 하며, 물론 사전에 apache_root/libexec/mod_headers.so 파일이 존재하고 LoadModule과 AddModule을 통해 모듈이 정상적으로 로드되어 있어야 한다.  (mod_headers.so는 아파치 기본 컴파일 옵션으로는 설치되지 않는다.)

  이제 마지막 남은 한가지 의문은 암호문같이 길게 나열된 코드가 도대체 무엇이냐는 것이다.  바로 이것이 압축된 개인정보 정책인데, 그 의미는 솔직히 본인도 모른다.

  P3P Spec을 보고 본인 나름대로 정책을 구성해가며 계속 시도해 보았으나 무심한 IE6는 배가 불렀는지 상태바에 빨간아이콘을 내보이며 계속 쿠키 받기를 한사코 거부했다.  그래서 '이런 괴물을 만든 MS 사이트에서는 어떤 정책을 사용하나?'라는 의문이 들어 헤더분석기를 이용해 MS 사이트의 압축정책을 조사해본 결과 상기와 같은 정책이 들어있길래 Copy해서 그대로 헤더로 뿌려봤더니 드디어 빨간아이콘이 나타나지 않아서 채택한 것일 뿐이다. (무려 25개나 되는 압축된 정책들의 의미를 찾아볼 엄두가 나지 않았음... 불성실의 극치임.  -_-  본받지 맙시다!)

  압축 정책의 스펙에 대해서는 아래에서 간략히 소개할 것이며, 여기에 나와있지 않은 내용은 P3P 공식 사이트를 되져보면 된다.

3. P3P의 압축정책 Spec

개인 정보 태그 압축 토큰
<contact-and-other/> CAO
<pseudo-analysis/> PSA
<contact required="opt-in"/> CONi
<other-recipient/> OTR
<ours/> OUR
<demographic/> DEM
<online/> ONL

범주 압축 토큰 설명
<physical/> PHY 연락처 또는 위치 정보
<online/> ONL 인터넷 상의 연락처 또는 위치 정보(예: 전자 메일 주소)
<government/> GOV 정부에서 발급한 ID(예: 사회 보장 번호)
<financial/> FIN 개별 재무 정보

용도 압축 토큰 설명
<customization/> CUS 사용자에 의해 명시적으로 요청된 사이트 수정
<individual-analysis/> IVA 개별 사용자와 관련될 수 있는 분석
<individual-decision/> IVD 사용자 기록에 기초한 동작 수행
<contact/> CON 개별 사용자에게 연락하는 데 사용할 수 있는 정보
<telemarketing/> TEL 전화 판촉에 사용할 수 있는 정보
<other-purposes/> OTP 다른 P3P 용도 이외의 기타 용도

수신인 압축 토큰 설명
<same/> SAM 일관된 관례에 따라 고유한 목적에 데이터를 사용하는 정식 항목
<delivery/> DEL 주어진 용도 이외에 목적에 데이터를 사용할 수 있는 배달 서비스를 수행하는 정식 항목
<other-recipient/> OTR 공급자에게 책임이 있지만 알려지지 않은 방법으로 데이터를 사용할 수 있는 항목
<unrelated/> UNR 공급자에게 알려지지 않은 방법으로 데이터를 사용하는 항목
<public/> PUB 공개 포럼

  짧은 시간내에 P3P를 파헤치다보니 미흡한 점이나 잘못된 부분도 많으리라 봅니다.  편의상 존칭어를 생략한 점 사과드리고, 앞으로 보충설명이나 문제점 지적 부탁드립니다.

반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,
모든 브라우저 (IE,FF,Chrome,Opera) 그냥 무시된다.
<body> 
 
제품이름 : <tr> 
    <td class="tdLabel"></td> 
    <td 
><label id=""></label></td> 
</tr> 
 
MP3 플레이어
<br/> 
제품 모델번호 : <tr> 
    <td class="tdLabel"></td> 
    <td 
><label id=""></label></td> 
</tr> 
 
MP3-070701
	
</body>

위와 같은 페이지는 그냥
제품이름 : MP3 플레이어
제품 모델번호 : MP3-070701
요렇게 표시된다.
반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,