반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

이제 실제 메소드들을 보면서 분석해 보겠습니다.
일단 제일 먼저 실행 될 것 같은 init() 메소드를 보죠. 주석에도 Initialize (초기화)라고 돼 있으니까 왠지 이게 제일 먼저 실행 될 것 같네요.
(오버로딩 된 ScreenViewFlipper 메소드를 봐도 이 init() 메소드를 불러오는 것 만 있습니다.)


이 그림은 viewFlipper를 잘 보여주는 것 같아 구글에서 갖다 썼습니다.

이 화면에 대한 소스나 설명은 여기로 가시면 보실 수 있습니다.



    public void init(Context context) {
        setBackgroundColor(0xffbfbfbf);

        // Layout inflation
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.screenview, this, true);

        buttonLayout = (LinearLayout) findViewById(R.id.buttonLayout);
        flipper = (ViewFlipper) findViewById(R.id.flipper);
        flipper.setOnTouchListener(this);

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        params.leftMargin = 50;

        indexButtons = new ImageView[countIndexes];
        views = new TextView[countIndexes];
        for(int i = 0; i < countIndexes; i++) {
            indexButtons[i] = new ImageView(context);

            if (i == currentIndex) {
                indexButtons[i].setImageResource(R.drawable.green);
            } else {
                indexButtons[i].setImageResource(R.drawable.white);
            }

            indexButtons[i].setPadding(10, 10, 10, 10);
            buttonLayout.addView(indexButtons[i], params);

            TextView curView = new TextView(context);
            curView.setText("View #" + i);
            curView.setTextColor(Color.RED);
            curView.setTextSize(32);
            views[i] = curView;

            flipper.addView(views[i]);
        }
    }



    우선 화면의 배경색을 세팅했네요. 0xffbfbfbf 이게 무슨 색인지는 잘 모르겠습니다. 나중에 실행 시켜보면 알겠죠.
    그 다음 LayoutInflater 의 instance를 만들고 여기에 context의 SystemService 에서 layout inflater를 대입했습니다.
   
    이 LayoutInflater에 대해 google developer 사이트에서는 아래와 같이 설명해 놓았습니다.
    layout XML 파일을 해당하는 View object로 초기화 하는 것. getLayoutInflater()나 getSystemService(String)을 가지고 standard LayoutInflater 인스턴스를 가져옴.
    이 standard LayoutInflater 인스턴스는 현재의 context에 이미 있고 디바이스에 맞게 configure 된 것들 입니다.
   
    즉 XML에서 선언된 어떤 view를 가져와서 그 위에 object들을 배열할 때 사용되는가 봅니다.
   
    그 아래 줄을 보시면 이 inflater에 아까 봤던 screenview.xml을 넣었습니다.
    이 xml 에는 <LinearLayout> (id=buttonLayout)과 <ViewFlipper> (id=flipper)가 들어 있었죠.
    이제 이 inflater가 이것들을 구체적으로 어떻게 사용하는지 볼까요?
   
    아까 예상했던 대로 buttonLayout 에는 screenview.xml에 있는 id가 buttonLayout 이라는 LinearLayout 을 세팅합니다.
    다음줄엔 flipper 에 id가 flipper 인 ViewFlipper를 세팅하구요. 이 flipper에는 touchListener를 세팅합니다.
   
    예상컨데 이 buttonLayout에는 button들 (3개로 선언했었죠?)이 배치되겠고 flipper에는 표시될 screen들이 들어가겠네요.
    이 screen을 손가락으로 touch(slide) 하면 화면이 바뀌겠구요.
   
    이것을 구체적으로 어떻게 코딩하는지 계속 알아 보겠습니다.



   
    LinearLayout.LayoutParams 인스턴스를 만들고 여기에 이 view에 대한 width와 height 가 Wrap_content 인 LayoutParams를 대입시킵니다.
    그리고 이 params 에 leftMargin을 50으로 세팅하구요.
   
    이 값은 나중에 아까 선언했던 buttonLayout 에 적용이 되겠죠.
   
    다음에는 indexButtons에 new ImageView[countIndexes]를 대입합니다. countIndexes는 제일 처음에 3으로 선언했었죠?
   
    그리고나서 이 countIndexes 만큼 for문을 돌립니다.
    그 for문을 돌고 나면 3개의 ImageView 가 만들어 질 거고 이 이미지 뷰들은 indexButtons 배열에 담길겁니다.
    만약 i가 0이면 즉 제일 첫번째 것이면 그 ImageView에는 green.png 가 대입 되겠고 그렇지 않으면 white.png가 대입이 될 겁니다.
    그러니까 첫번째는 초록색 버튼이 되고 나머지 두 버튼은 흰색이 되겠네요.
    이 ImageView에 padding 값을 주고 buttonLayout에 지금까지 세팅한 ImageView(indexButtons)를 넣습니다.
    buttonLayout.addView(indexButtons[i], params);
    보시면 params 도 pass 하죠? 이 params는 아까 leftMargin을 50으로 세팅한 겁니다.
   
    그 다음엔 TextView 를 하나 만드네요.
    이 텍스트 뷰에는 View # = i 라는 텍스트가 있고 색은 빨간색이고 size는 32 라고 세팅이 돼 있습니다.
    이 값을 views 배열에 넣는데요.
   
    저 for 문 바로 위에 보니까 vews 라는 TextView 배열이 선언돼 있네요. 배열 크기도 countIndexes 즉 3개로 선언돼 있구요.
    이 부분을 보지 못하고 그냥 넘어갔네요.
   
    이 text를 가진 views 배열을 flipper에 넣는 것이 이 for 문의 마지막이자 이 init메소드의 마지막 입니다.
   
    자 여기까지가 바로 screenview.xml에서 그냥 내용 없이 선언된 LinearLayout 과 ViewFlipper에 내용을 채워 넣은 겁니다.
    LinearLayout 에는 세개의 버튼이 놓여지게 되고 버튼 색은 녹색, 흰색, 흰색이 세팅됐습니다.
    그리고 ViewFlipper 에도 3개의 내용이 들어가 있는데 View #1, View #2, View #3 이라는 텍스트가 있습니다.
    그 텍스트들은 빨간색이고 크기가 32입니다.
   
    이제 display 하는 것은 모두 완료 됐습니다.
   
    이제 볼 것은 뭘까요?
    아까 ViewFlipper에 touch 리스너를 달았습니다.
   
    그러면 ViewFlipper에 어떤 touch 이벤트가 발생했을 때 다른 동작을 할 수 있도록 코딩을 할 수 있는데요.
    바로 그 코딩을 하는 onTouch() 메소드를 분석해 봐야 할 차례입니다.

반응형


반응형

지난 월요일 화요일 이틀동안 POC (Proof of Concept)용으로 안드로이드 Native App 을 하나 개발 했습니다.

Native App 은 거의 2년만에 개발하는 것 같은데..

이번에 새로운 개념들도 여러개 배웠습니다.

그 내용들을 정리해 볼까 하는데요.


오늘은 그 중에 ViewFlipper 에 대해 정리해 보겠습니다.


공부하는 방법은 제가 Do It 안드로이드 앱 프로그래밍이라는 책에서 제공하는 동영상을 보고 개념도 다시 잡고 거기서 제공하는 소스를 다운받아서 보기도 하고 했는데요.


그 책에서 제공하는 viewFlipper 관련 예제 소스를 자세히 분석하면서 공부를 하겠습니다.


예제소스는 http://android-town.org/ 로 가면 무료로 제공하고 있으니 필요하신 분들은 받으셔서 보셔도 됩니다.

동영상강좌는 http://www.youtube.com/user/easyspub 에서 제공되고 있습니다.

책을 직접 구입하셔서 보시면 훨씬 더 도움이 될 것 같네요.


그럼 그 책에서 제공하고 있는 SampleViewFlipper 를 보겠습니다.


우선 첫번째 실행되는 layout xml을 보겠습니다.


activity_main.xml


<RelativeLayout 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" >

    <org.androidtown.ui.flipper.ScreenViewFlipper
        android:id="@+id/screen"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp" />
</RelativeLayout>


Launcher Activity 의 Layout xml 은 위와 같이 돼 있습니다.
이 RelitiveLayout 의 대상 공간은 화면 전체이구요.
RelativeLayout 으로 세팅하고 그 내부에는 ScreenViewFlipper 클래스를 import 하는 태그만 있습니다.
이 flipper의 id 는 screen 이고 margin 10dp 로 한채로 대상 공간이 그 parent 인 RelativeLayout 을 꽉 채웁니다.


이클립스에 있는 Graphical Layout 을 통해 보면 아래와 같은 화면이 나옵니다.




이제 JAVA 소스코드를 봐야겠네요.


public class MainActivity extends Activity {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}


바로 이 MainActivity 가 첫번째 화면인데요. onCreate() 메소드내에 위에서 본 activity_main.xml 을 Content View로 세팅을 했습니다.
그게 다 입니다.

밑에 있는 onCreateOptionMenu() 메소드는 override 한 것인데 안드로이드 디바이스 밑의 menu 버튼을 누르면 나오는 메뉴들을 세팅하는 메소드 입니다.
실제 이 앱과는 관련이 없으니까 무시하셔도 됩니다.

결국은 앱을 실행하는 첫번째 Activity에는 아무론 것도 화면에 표시를 하지 않네요.
이제 activity_main.xml에서 import한 ScreenViewFlipper.java 를 봐야겠습니다.




그럼 우선 이 ScreenViewFlipper에서 사용하는 layout 파일인 screenview.xml을 보겠습니다.


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <LinearLayout
        android:id="@+id/buttonLayout" 
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        >
    </LinearLayout>   
    <ViewFlipper
        android:id="@+id/flipper" 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >   
    </ViewFlipper>
</LinearLayout>


일단 LinearLayout 을 사용했습니다. width와 height가 match_parant니까 위의 xml 파일에서 세팅된 <org.androidtown.ui.flipper.ScreenViewFlipper ...... />의 크기 만큼 그 대상 공간이 됩니다.
여기서는 계속 화면 전체가 되겠죠.

그 다음 LinearLayout 내부에 또 LinearLayout이 있습니다. 그 크기는 wrap_content 로 돼 있는데 그것은 이 LinearLayout에 들어가는 내용의 크기 만큼 설정을 하겠다고 세팅돼 있습니다.
그런데 그 안에 아무것도 없네요. 즉 화면에 표시할 게 아무것도 없습니다. 나중에 혹시 java 파일에서 이 LinearLayout을 불러내서 다른 object를 setting 하면 그 때 화면에 뭔가가 표시 될 수는 있을 겁니다.
(id가 buttonLayout 이니까 이 id로 불러낼겁니다.)

그 아래는 <ViewFlipper> 태그가 있습니다. 여기에 오늘 공부하는 ViewFlipper를 표시할 겁니다.

여기까지 보니까 위에는 버튼이 달릴거고 (내부 LinearLayout id 가 buttonLayout인것을 가지고 아직까지는 그냥 추정해 보는 겁니다.) 그 아래에 ViewFlipper 가 달려서 페이지 전환이 이뤄질 것 같습니다.


아직까지는 이 Layout에 어떤 VIew나 Widget이 표시되지는 않습니다.




ViewFlipper에 대한 Android Developer 싸이트의 설명은 이렇습니다.
두개 이상의 View들이 add돼 있고 이 view들이 animate 될 간단한 ViewAnimator. 한번에 한 child만 보인다. 설정을 한다면 일정한 interval을 두고 각각의 child 를 자동으로 flip 되도록 할 수 있다.

flip이라는 의미가 뒤집다라는 거니까 페이지들을 child로 설정했다면 이 페이지가 뒤집히는 효과를 주면서 화면이 전환되게 할 수 있겠네요.
또 view에는 여러개가 해당 될 수 있으니까 다른 object 별로도 이런 flip 효과를 줄 수 있겠습니다.

그럼 이제 본격적인 내용이 있는 ScreenViewFlipper를 한번 분석해 보죠.



public class ScreenViewFlipper extends LinearLayout implements OnTouchListener {

    /**
     * Count of index buttons. Default is 3
     */
    public static int countIndexes = 3;

    /**
     * Button Layout
     */
    LinearLayout buttonLayout;

    /**
     * Index button images
     */
    ImageView[] indexButtons;

    /**
     * Views for the Flipper
     */
    View[] views;

    /**
     * Flipper instance
     */
    ViewFlipper flipper;

    /**
     * X coordinate for touch down
     */
    float downX;

    /**
     * X coordinate for touch up
     */
    float upX;

    /**
     * Current index
     */
    int currentIndex = 0;


    public ScreenViewFlipper(Context context) {
        super(context);
       
        init(context);
    }

    public ScreenViewFlipper(Context context, AttributeSet attrs) {
        super(context, attrs);
       
        init(context);
    }

    /**
     * Initialize
     *
     * @param context
     */
    public void init(Context context) {
        setBackgroundColor(0xffbfbfbf);

        // Layout inflation
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.screenview, this, true);

        buttonLayout = (LinearLayout) findViewById(R.id.buttonLayout);
        flipper = (ViewFlipper) findViewById(R.id.flipper);
        flipper.setOnTouchListener(this);

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        params.leftMargin = 50;

        indexButtons = new ImageView[countIndexes];
        views = new TextView[countIndexes];
        for(int i = 0; i < countIndexes; i++) {
            indexButtons[i] = new ImageView(context);

            if (i == currentIndex) {
                indexButtons[i].setImageResource(R.drawable.green);
            } else {
                indexButtons[i].setImageResource(R.drawable.white);
            }

            indexButtons[i].setPadding(10, 10, 10, 10);
            buttonLayout.addView(indexButtons[i], params);

            TextView curView = new TextView(context);
            curView.setText("View #" + i);
            curView.setTextColor(Color.RED);
            curView.setTextSize(32);
            views[i] = curView;

            flipper.addView(views[i]);
        }
    }
   
    /**
     * Update the display of index buttons
     */
    private void updateIndexes() {
        for(int i = 0; i < countIndexes; i++) {
            if (i == currentIndex) {
                indexButtons[i].setImageResource(R.drawable.green);
            } else {
                indexButtons[i].setImageResource(R.drawable.white);
            }
        }
    }

    /**
     * onTouch event handling
     */
    public boolean onTouch(View v, MotionEvent event) {
        if(v != flipper) return false;

        if(event.getAction() == MotionEvent.ACTION_DOWN) {
            downX = event.getX();
        }
        else if(event.getAction() == MotionEvent.ACTION_UP){
            upX = event.getX();

            if( upX < downX ) {  // in case of right direction
 
                flipper.setInAnimation(AnimationUtils.loadAnimation(getContext(),
                        R.anim.wallpaper_open_enter));
                flipper.setOutAnimation(AnimationUtils.loadAnimation(getContext(),
                        R.anim.wallpaper_open_exit));

                if (currentIndex < (countIndexes-1)) {
                    flipper.showNext();

                    // update index buttons
                    currentIndex++;
                    updateIndexes();
                }
            } else if (upX > downX){ // in case of left direction

                flipper.setInAnimation(AnimationUtils.loadAnimation(getContext(),
                        R.anim.push_right_in));
                flipper.setOutAnimation(AnimationUtils.loadAnimation(getContext(),
                        R.anim.push_right_out));

                if (currentIndex > 0) {
                    flipper.showPrevious();

                    // update index buttons
                    currentIndex--;
                    updateIndexes();
                }
            }
        }
        return true;
    }
}



우선 메소드들을 선언하기 전에 나오는 object들을 선언하는 것부터 보겠습니다.
첫번째는 countIndexes=3; 인데 주석을 보니까 index 버튼들의 숫자라고 하네요. 디폴트는 3이구요.
그 다음 LinearLayout을 buttonLayout 이라는 이름으로 하나의 객체를 만들어 놨습니다.
아직 정확하게는 모르지만 이 객체에 screenview.xml 에 있었던 buttonLayout 이라는 id를 가진 LinearLayout 을 세팅할 것 같네요.
그리고 indexButtons 라는 이름으로 ImageView 배열을 선언했구요. 여기에는 위에서 3개로 선언된 index button 이미지가 세팅될것 같습니다.
그 다음에는 views라는 이름으로 View 배열이 있습니다. 주석에는 Flipper들을 위한 View들이라고 돼 있네요.
다음줄에서 ViewFlipper의 instance를 만들었습니다. 그 이름은 flipper 이구요.
그 다음은 down시 x 좌표를 받을 downX라는 이름으로 float 객체를 만들었고 up시 x 좌표를 받을 upX도 있습니다.
그리고 현재의 index는 0이라고 선언한 줄이 나옵니다. 이름은 currentIndex 이고 정수형입니다.


메소드에 대한 분석들은 다음 글에서 이어나가겠습니다.

반응형


반응형

이번 주말은 안드로이드 동영상 강좌만 들으면서 보냈습니다.

이지스퍼블리싱 출판사에서 만든 Do it 안드로이드 앱 프로그래밍이란 책을 바탕으로 제공하는 동영상 강좌 입니다.


카페 주소는 http://cafe.naver.com/easyispub/945 이고

유투브 주소는 http://www.youtube.com/watch?v=Xb9300qU52Y&list=PL5C6E85EFC6E406EF 입니다.





금요일에 안드로이드 관련 업무를 하나 받았거든요.

기존에 개발된 앱을 보여주면서 안드로이드 태블릿 버전으로 POC (Proof of Concept)를 하나 만들어 보라고요. 수요일 오전까지요.


Android Native App Programming 을 잠시 떠나 있어서 예전에 했던것을 다시 떠올리기 위해 자료를 찾다가 이 동영상 강좌를 보게 됐습니다.


1편부터 10편까지 봤습니다. 개념정리에 아주 도움이 됐습니다.

안드로이드 앱 프로그래밍에 관심 있으신 분들께 적극 추천 합니다.


한국에 있다면 당장에 저 책 사서 활용했을 텐데 여기서는 그 책을 구할 수가 없어서... ;;


거의 토요일 하루 종일 봤는데요. 아마 10시간 가까이 봤을 것 같습니다.

오늘 (일요일)에는 법륜 스님이 이 먼 미국까지 오셔서 더군다나 제가 사는 지역까지 오셔서 즉문즉설을 해 주신다고 해서 거기 갈 계획입니다.


그 즉문즉설 다녀온 다음 화요일까지 빡세게 해서 POC를 위한 안드로이드 태블릿 앱을 하나 만들겁니다.


살짝 긴장되는데 기분 좋은 긴장이네요.


아래 글은 동영강강좌 10편을 들으면서 그냥 끄적거린 메모 입니다.

나중에 다시 기억 떠올리는데 도움이 될 것 같아서 이 블로그에 정리해 둡니다.



* 안드로이드 태블릿

허니컴 부터 시작 : 안드로이드 3.0 (Level 11,12,13)
아이스크림 샌드위치부터 phone + Tablet 시작 : 안드로이드 4.0 (Level 14,15)
현재는 젤리빈 : 안드로이드 4.1,4.2,4.3 (Level 16,17,18)
차후 KitKat 예정 : 안드로이드 4.4 (Level 19)

* 기억해야 할 것들


리스너 달기 : setOnClickListener
intent
화면 전환하기 : intent(intent.ACTION_VIEW,Uri.parse("웹사이트 주소 or tel:전화번호 etc."));

layout 에 있는 객체 불러오기 : (Button) findViewById(R.id.buttonname);

* Activity 간 전환
- layout 에 xml 하나 더 만듬
- Intent myIntent = new Intent(getApplicationContext(), NewActivity.class);
- startActivity(myIntent)
- Manifest 파일에 새로운 Activity 등록
=> 이러면 NewActivity.class 액티비티가 호출 됨

* 안드로이드 버전별 주요 기능

Proyo (2.2) : Flash, SD 카드에 설치, Backup API, Push Message 지원
GengerBread (2.3) : NFC (전자 결재), front Camera, 자이로스코프 센서, Internet 전화(SIP) 지원
HoneyComb (3.0) : Tablet UI, 화면 분할, HTTP Live Streming 지원
Icecream Sandwich (4.0) : 홀로그래픽 UI 와 버추얼 키, 얼굴인식과 음성인식 텍스트 입력, NFC 빔 공유와 WiFi 다이렉트 지원

* Structure of Android Project folder
/src
/Android <version>
/res
/gen
/assets
AndroidManifest.xml
default.properties


sdk/tools/hierarchyviewer.bat - 해당 액티비티의 구조도를 볼 수 있음

* apk 만들기
Android tools - export signed application - keystore 제공 - ....

* 화면구성 - View,Layout,Widget

* Widget - fill_parent, wrap_content etc.

* Layout 종류
LinearLayout : android:orientation = vertical, horizontal
Releative Layout
Frame Layout : 여러개의 View를 중첩시킨 후 각각의 뷰에 대해 보이거나 보이지 않게 하면 뷰 전환 가능. object.setVisibility(View.)
Table Layout
Scroll View

* setContentView(R.Layout.main);

* DDMS - LogCat 로그 보기

* startActivityForResult(intent,constant)
  - 다른 액티비티에서 데이터를 받기 위해 사용. (onActivityResult())
  setResult(code,resultIntent), resultIntent.putExtra("name","john");

* parent class 의 method override 하기
  - right mouse button - source - override/Implement method - select method

* Toast.makeText(context,text,duration);

* startActivity(), startService(), bindService(), broadcastIntent()

* ACTION_DIAL tel:1111111, ACTION_VIEW tel:1111, ACTION_EDIT content://contacts/people/2, ACTION_VIEW

content://contacts/people

* Implicit Intent : Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://m.yahoo.com");
* Explicit Intent : Intent myIntent = new Intent(getApplicationContext(),NewActivity.class);

* FLAG_ACTIVITY_SINGLE_TOP, FLAG_ACTIVITY_CLEAR_TOP, FLAG_ACTIVITY_NO_HISTORY

* Parcelable : 전달하는 데이터가 선언한 객체일 경우, bundle.getParcelable();




* Shared Preference : 간단한 정보 저장했다 불러올 때 사용. Cache 같은 것 (onPause())
  SharedPreference myPref = getSharedPreferences("myPref",Activity_MODE_WORLD_WRITEABLE);
  SharedPreferences.Editor myEditor = myPref.edit();
  myEditor.putString("name","Tom");
  myEditor.commit();
* onResume()
  SharedPreferences myPref = getSharedPreference("myPref",Activity.MODE_WORLD_WRITEABLE);
  if(myPref != null && myPref.contains("name")){
    String name = myPref.getString("name");
  }

* 로그 출력 : Log.d("tag","Message");

* Service : startService(), stopService()
            android:process=":remote" - Manifesto 에 별도의 프로세스를 선언할 수 있음 -> 앱이 Destroy 되도 계속 동작함

* Content Provider
  CONTENT_URI , content://... 로 접근., http:// 로 웹사이트 접근
  Cursor를 이용해 결과 데이터 확인 (Database)
  ContentResolver : getContentResolver(), query()

  ex) ContentResolver resolver = getContentResolver();
      resolver.query(uri,projection,selection,selectionArgs,sortOrder);
      Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI,null,null.null.null);
      int count = cursor.getCount();
      Toast.makeText(this,"text",duration);
      => add permissions : READ_CONTACTS
      for(int i = 0; i<count; i++){
        cursor.moveToNext();
        String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
        Toast.makeText(this,"name " + i + name,duration);
    }

* Manifest
  <activity>,<intent-filter><action android:name = ".... .MAIN"> <category android:name = "......LAUNCHER>,

<style ....>

* AlertDialog
  AlertDialog dialog = null;
  switch(id){
      case 1:
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("");
         builder.setPositiveButton("",new DialogInterface.OnClickListener())
        
        public void onClick(DialogInterface dialog, int which) {
            Toast.makeText.....
        }
        });
        builder.create();
  }

* AlertDialog 를 Activity 로 만들기 (로그인 화면??)
  AlertDialog가 떠야 되는 장소에 코딩
  setContentView(R.layout.dialog); // dialog.xml 만들기 (바탕화면,로그인 창 - 바탕화면은 이미지를 매번 바꿀 것)
  Manifest - <activity android:name="DialogActivity" android:theme="@android.style/Theme.Dialog"></activity>
  => AlertDialog box 디자인 하는 방법
 


반응형


반응형

이번 국정원의 이석기와 RO에 대해 내란음모죄를 적용하고 공개 수사하는 것과 관련... 진보 세력 내에서 이석기와 RO 에 대한 비판을 비판하는 의견이 있습니다.

옛날 반독재 시대때 대동단결을 외치는 모습을 아직도 보는 듯 한데요.


이런 의견이 오마이뉴스의 한 기사로 올라왔습니다.


'이석기'를 대하는 진보의 자세, 이게 최선인가

[주장] 세상을 바꾸고자 하는 당신의 양심은 어디로 향하는가


이석기를 비판하면 부활하는 수구 독재 세력에 놀아나는 것처럼 얘기들을 하는데..

저는 오히려 80년대의 저 대동단결의 수준에서 벗어나지 못하는 진보 세력들이 수구 독재 권력에 놀아나는 것이라고 생각합니다.


그 생각을 바탕으로 이 글에 대해 댓글을 달았는데요.


이 댓글을 제 블로그에 정리하고 싶네요.


나중에 제대로 정리해서 아티클을 하나 써서 주위분들과 같이 공유하고 토론해봤으면 좋겠다라는 생각이 들어서요.



  • 뿌네 2013-09-07 23:13:37

자 글쓴이가 무엇을 비판하는 건지 명확히 해 보겠습니다. 사상의 자유는 100% 지켜질 수 밖에 없습니다. 사람 머리속에 뭐가 있는지 알 수 없으니까요. 일반적으로 말할 때 사상의 자유에는 표현의 자유까지 포함 되는 겁니다. 표현의 자유는 100% 허용될 수는 없습니다. 바로 이 표현의 자유를 어디까지 허용할 것인가가 핵심입니다. 이석기 및 그 부류에게 국가 보안법의 고무 찬양죄 등이 적용될 수 있다는데는 이견이 없습니다. 하지만 이게 이슈가 되지는 않습니다. 이미 국가보안법은 많은 사람들에게 법으로서의 권위를 크게 인정받지 못하고 있습니다. 글쓴이가 말하는 진보는 거의 100% 이 국가보안법 폐지를 요구하는 사람들 일 겁니다.


  • 뿌네 2013-09-07 23:18:43

두번째는 내란 음모죄입니다. 이 내란 음모죄에 대해서는 글쓴이가 말하는 진보들이 모두들 말도 안되는 혐의이고 법원 판결에서는 이 죄목이 적용되지 않을 것이라고 말하고 있습니다. 일부 보수들조차 그렇게 얘기하고 있습니다. 글쓴이가 말하는 진보세력들은 대부분 국정원이 불법선거개입으로 위기에 처하자 이를 모면하기 위해 이 사건을 꺼내 들었다라고 비판하고 있습니다. 그런데 그 진보세력들이 뭘 비판하는 걸까요? 주사파들의 사상 자체를 비판하는것이 아닙니다. 그들이 수령론에 입각한 조직체계와 실천론이 민주화 이후 얻어낸 합법공간에서의 활동에서 진보세력에 방해가 됐기 때문에 그 점을 비판하는 겁니다. 그들의 행동이 불법이라 법적용을 해야 한다고 비판하는 것이 아니라 그들의 행동이 진보진영에서 올바르지 않았기 때문에


  • 뿌네 2013-09-07 23:23:57

세번째글 입니다. 그 올바르지 않은 실천을 비판하는 겁니다.

글쓴이는 왜 그걸 비판하는 거죠? 획일주의와 진영주의에 입각한 합리적이고 논리적이지 않은 비판이십니다.
지금의 실천은 독재 권력과 비합법, 반합법적으로 투쟁하던 시기와 다릅니다. 의회내에서 국민의 지지(투표로 표현되는)를 받기 위한 실천이 우리의 임무입니다. 그것이 선배들의 피로 얻은 공간을 더욱 더 풍부한 민주화의 공간으로 만들어 가야 할 우리의 의무입니다.

이 공간에서의 파트너는 보수입니다. 진보의 파트너는 보수입니다. 그리고 적대적인 관계에 있는 이들이 이 합법공간을 부정하는 권위주의 독재 세력과 구태를 못벗은 시대착오적인 세력입니다. 선배들의 피로 얻은 성과물을 흐트려뜨리는 부활하는 독재세력과 잔존하는 시대착오세력이 우리가 척결해야 할 대상입니다


  • 뿌네 2013-09-07 23:28:45


네번째 글입니다.
그러니까 글쓴이의 글은 시대착오적인 구시대의 관념에서 나온 잘못된 판단입니다. 그런 판단과 주장은 도리어 부활하는 독재세력들에게 정당성을 주는 자양분이 될 뿐입니다. 글쓴이가 말하는 진보세력은 이석기 부류의 인간들에게 국가보안법을 적용하거나 내란음모죄를 적용해야 한다고 주장하거나 그런 주장에 동조하지 않습니다.

진보세력은 선배들의 민주화를 위한 피로 만들어낸 성과물인 이 공간을 다시 해치려는 독재 부활 세력과 일부 운동권의 구시대적인 실천에 대한 비판을 하는 것입니다. 부디 시대착오적인 관념에서 벗어나서 올바른 판단을 하는 진정한 진보의 입장을 계속 성장시켜 나가는 글쓴이가 되기를 바랍니다.
감사합니다.


  • 소도리 2013-09-07 23:38:18


제가 이해하기로는... 이석기에대한 비판은 모두 인정한다고 하더라도 작금의 본질은 이석기에 있는것이 아니라 수구세력들의 진보세력 죽이기에 나름 현명한 사람들 이라고 생각했던 사람들도 꼬랑지를 내리는데 그 모습에 피실피실 웃을 수구공작세력들을 상상하니 등골이 오싹해진다~~~ 라는걸로 이해 됩니다만...


  • 뿌네 2013-09-08 01:43:11

제 이해로도 수구세력들의 합리를 추구하는 세력들을 무력화 시키는 과정이 이번일의 본질이라고 생각합니다. 저는 이 수구세력에 선배들의 피로 만든 합법적인 공간을 무시하는 수구 부패 세력과 구시대 조직관과 실천관을 가지고 있는 운동권내의 기득권인 수구 운동권 세력이 다 포함 됩니다. 이 둘은 서로가 존재의 전제 조건이 되는 세력들 입니다. 수구 기득권 세력들의 존재를 위협하는 것은 합리적인 상식의 공간 입니다. 이 공간을 확보하려고 선배들이 피를 흘린 겁니다. 이 공간은 합리적인 진보와 합리적인 보수가 같이 지켜야 합니다. 진보세력들이 그 공간을 지키지 못하고 공간 밖에 있는 수구 부패 세력의 부활이 점점 손 쉬워져서 수구공작세력들이 피실피실 웃는 것 아닐까요? 합리적인 상식과 함께 민주주의를 성장시킵시다.



  • 뿌네 2013-09-08 02:40:08

저는 수구세력들의 진보세력 죽이기에 나름 현명한 사람들이라고 생각했던 사람들이 꼬랑지를 내린다는 표현은 별로 동의가 되지 않습니다.

현실을 진지하게 고민하지 않고 옛날의 타성에만 젖어서 덜 선명하게 보일까봐 과거 이미 정해진 틀에 현실을 그대로 끼워 맞춰서 비판하는 성의 없는 진보들의 자세가 비겁해 보일 뿐입니다.


-----------------------------


facebook에서 이어진 논의 계속


Hee Kim 음.. 제 생각으로는, 이건 어느 문제에 집중하느냐 하는 '우선순위'의 문제이고 언제 무엇을 하느냐 하는 '타이밍'의 문제이지, 진보의 운동방식에 대한 반성을 아예 하지말자는 이야기는 아닌 듯 한데요..


Changsoo Park 이 건 꾸준한 실천의 문제라고 생각합니다. 타이밍의 문제라고 보는 자세는 너무 단기적인 시각에 매몰돼 있는 자세가 아닌가 싶네요. 깊고 진지한 고민 없이 가벼운 전술만 판치는 그런 자세들이 바로 외부 요건에 쉽게 휘둘리도록 만드는 자세 아닐까요?


Hee Kim 아마도 현시점을 반여권의 동력이 완전히 죽을 수도 있는 터닝 포인트로 보느냐 아니냐 하는 위기감 판단의 차이일지도 모르겠네요.


Hee Kim 노대통령이 진짜 뭘 잘못해서 그 수모와 죽음까지 당하신 게 아니니, 이젠 일단 저들의 프레임을 깨는 것이 먼저가 아닐까 하는..


Changsoo Park 민 주화 운동으로 어떤 큰 틀은 바꿨습니다. 외형적인 부분이요. 선배들의 선도적인 투쟁과 희생의 도움이 컸더는 것은 누구도 부정할 수 없을 겁니다.... 내용적이고 근본적인 부분들은 사람들이랑 같이 채워 나가야 한다고 봅니다. 합리적인 상식을 가진 사람들이요. 보수이던 진보이던..말씀하신 그 프레임을 깨는 것도 그 사람들이랑 같이 해야 한다고 봅니다. 사람사는세상을 만들려면 그 세상에 같이 살아야 할 사람들을 주체로 서게 만들어야 하지 않을까요? 지금의 실천에서 희수님에게 합리적인 보수는 어디에 있나요? 그 사람들과 함께 사람사는세상을 만드는 일을 해야 하지 않을까 하는.... 수구친일부패 세력에 거의 흡수되서 그 존재감도 없는 합리적인 보수에게도 우리가 있다는 것을 알려야 하지 않을까요? 그들에게 우리가 믿음의 존재로 다가가야 하지 않을까요? 그런 생각을 진지하게 해 보자고 많은 사람들에게 얘기하고 싶은게 제 마음 입니다.


Hee Kim 동의합니다. 함께 고민해봐요 (^^).


Changsoo Park 예.. 그래요.. 좀 더 덧붙이고 싶은건.. 그 프레임을 깨는건 나나 어느 일부에 의해서가 아니라 프레임을 깨고 같이 세상을 살아갈 사람들과 함께해야 의미가 있다는 것...아니면 계속 반복될 뿐일 것이라는 것을...

반응형

안드로이드 개발 환경 구축하기

2013. 9. 6. 21:32 | Posted by 솔웅


반응형

안드로이드 개발 환경 구축



오랜만에 다시 안드로이드 애플리케이션 개발을 위한 글을 올리기로 했습니다.


지금 하는 TDD 일을 계속 할 지 아니면 Android App 개발 팀으로 옮길지 아직 모르는데요.

다시 Android 개발 관련해서 이야기가 나오니까 준비도 하고 싶고 또 개발도 하고 싶고 하네요.


당분간 Native Android App 개발 관련해서 공부를 할 것 같습니다.


우선 개발 환경부터 구축을 해 보겠습니다.


아래 싸이트로 가서 Android SDK 툴을 다운 받으세요.


http://developer.android.com/sdk/index.html




32bit 64bit 둘 중 하나 선택해서 다운 받으시면 됩니다.


다운 다 받은 후 적당한 곳에 압축을 풀어 주세요.




압축 푼 다음에 SDK Manager 실행을 하세요.




저는 모든 것 다 선택하고 Install Package 했어요. 그거 누르면 License 에 동의하겠느냐고 물어오는데 동의 한다고 한 다음에 Install 버튼 누르시면 됩니다.




Install 이 다 됐으면 이제 eclips 를 실행하시면 됩니다.



이제 HelloWorld 앱을 하나 만들어 보겠습니다.




New - New Android Application을 선택하시고 Application Name 에는 아무 이름이나 넣으세요. 그리고 Next 버튼을 누르세요.

다음 나오는 화면에서도 계속 Next 버튼을 누르세요.


Configure Project - Next
Configure Launcher Icon - Next
Create Activity - Next




그러면 이와 같이 애플리케이션이 만들어 집니다.


이 앱은 화면에 HelloWorld 를 display 해 주는 앱입니다.


이제 이 앱을 한번 실행해 봐야 할 텐데요.

에뮬레이션을 실행하도록 하겠습니다.




우선 에뮬레이터인 Android Vertual Device를 만들어야 하는데요.

메뉴바 밑에 있는 아이콘들 중 핸드폰 모양의 아이콘을 클릭하시면 위 화면이 나옵니다.

여기서 New를 누르시고 적당한 모델을 선택하시면 됩니다.


그리고 나서 Cntl-11 을 누르거나 Run을 누르시면 되는데요.


저는 Failed to allocate memory: 8 이런 메세지가 뜨네요.


이런 경우 해당 avd 폴더로 가서 config.ini 파일을 열어보세요.



이 파일은 C:\Users\본인\.android\avd\test.avd 경로에 있습니다.




빨간 줄 있는 부분이 1024MB가 아니라 1024로 돼 있을 겁니다.

만역 그렇다면 위에 보이는 것 처럼 고쳐 주세요.


그리고 나서 Run 을 실행하시면 됩니다.


에뮬레이터로 하면 시간이 조금 걸리는데요.

실제 개발 하실 때는 에뮬레이터 보다는 디바이스로 실행시켜서 테스트 해 보시는게 좋을 겁니다.





반응형

java memo 두 날짜 사이 일 수 구하기

2013. 9. 5. 01:15 | Posted by 솔웅


반응형
처음으로 모바일로 글을 올리네요.

일 하다가 기억해 두고 싶은 로직이 나와서.....

두 날짜 사이의 일 수 구하는 공식

public int daysBetween (Date d1, Date d2) {
return (int)((d2.getTime() - d1.getTime()) / (1000*60*60*25));
}

포물선 운동 표현 하는 공식

h=vo.sin@.t-1/2.g.t**2(g:gravity acceleration constant 9.8)
I=vo.cos@.t


iPhone 에서 작성된 글입니다.
반응형


반응형



Woman : I can't trust in Obama.
I have read about him and he is not.. is not...
um. He is an Arab..... He is not....

McCain : Nope, No ma'am. No ma'am.
He is a decent family man and citizen and that I I just happen to have disagreement with on fundamental issue and that's what this campaign is all about. He is not. Thank you.

할머니 : 난 오바마 못 믿어요. 내가 읽어 봤는데... 오바마는.. 오바마는... 그 사람은 아랍인 이예요.. 그 사람은 (미국인이) 아니예요.


McCain : 아닙니다. 아닙니다. 오바마는 올바른 가장이고 미국의 시민입니다. 저는 그 의견에 동의할 수 없습니다. 그는 아랍인이 아닙니다. 감사합니다.


======================================================================


지난 대선에서 공화당 대통령 후보 예비선거 과정에서 후보로 나선 존 매케인이 어느 한 타운홀 미팅에서 지지자와 나눈 대화일 겁니다.

존 매케인은 미국의 대표적인 보수주의자이며 공화당 당원이고 월남전에 참전해 포로로 잡혔고 5년만에 풀려난 전쟁 영웅입니다. 2008년에는 공화당 대통령 후보로 대선에 참여하기도 했습니다.


이런 미국의 대표적인 보수주의자가 상대당 후보인 오바마를 미국인이 아니고 아랍인이라고 비방하는 지지자의 말에 그 자리에서 반박합니다.

오바마는 올바른 가장이며 미국의 시민이라구요.


이 타운홀에 모인 사람들도 매케인의 이 발언에 환호와 박수를 보내며 지지합니다.


이렇게 상식적으로 말도 안 되는 소리마저도 발언의 기회가 주어지는것이 민주주의 입니다.

그리고 이렇게 공개적인 공간에의 의견 교환을 통해 이렇게 비상식적인 주장은 자연스럽게 사그러 들게 됩니다.

이게 민주주의의 힘입니다.


-----------------------------------------------------------


김대중, 노무현 대통령 시절에 한국의 일부 극우 인사들이 한국의 군대에 구테타를 일으켜 국가를 전복하라고 선동을 했습니다.

누가 봐도 상식적으로 납득할 수 없는 발언들 이었습니다.

이들은 자신들이 확보한 언론 매체를 통해서... 그것도 주류 언론 매체를 통해서 이런 비상식적인 주장을 했습니다.

하지만 공개적인 광장에서 이러한 주장들은 곧바로 사그러 들었습니다.

이게 민주주의의 힘입니다.


-----------------------------------------------------------


지금 국정원이 통진당의 5월 회합과 발언에 대해 내란음모 혐의를 두고 공개적으로 수사를 진행하고 있습니다.

법조인을 포함해 대부분의 사람들이 그 발언에 대해 내란 음모를 적용하는 것은 말이 안된다고 얘기하고 있습니다.

국정원이 국내 정치에 개입하고 대선에 불법적으로 공작을 벌여 지탄 받아오는 상황에서 이를 모면하기 위해 내세운 카드라는 것은 누구나 다 알고 있습니다.



그 회합에서 나온 일부 발언들은 일반 한국 국민으로서 상식적으로 납득할 수 없는 발언들이 있습니다.


저 공화당 타운홀미팅 처럼 그런 비상식적인 발언이라도 공개적으로 얘기할 수 있는 자유를 줘야 그런 비상식적인 주장과 논쟁하고 결국은 비상식적인 생각이 사그라드는 기회를 가질 수 있습니다.

그래야 사회가 건강해 질 수 있습니다.


군대보고 구테타를 일으켜 정권을 몰아내라는 비상식적인 주장이 주류 언론을 통해 소리칠 수 있는 자유를 줘야 그런 주장이 국민들의 지지를 얻지 못한다는 것을 깨닫게 해 잠잠해 지게 만들 수 있습니다.


지금 한국의 정치 상황은 민주주의 국가로서 건강하지 못한 모습을 보여주고 있습니다.

한 집단의 (정당의) 회합에서 나온 일부 구체적이지 않은 발언에 내란음모를 뒤집어 씌웁니다.

그 발언이 비 상식적인것은 맞습니다.

이 비 상식적인 주장이 한번도 공개적으로 논의할 기회를 갖지 못하고 기형적으로 성장한 것입니다.

공개적으로 주장할 기회를 그들에게도 주었다면 오바마를 테러리스트라고 주장하는 저 노파나 자기가 지지하지 않는 정당이 정권을 잡았다고 구테타를 일으키라고 하는 한국의 저 극우들의 주장처럼 그런 비 상식적인 주장은 이내 사그라 들었을 겁니다.


이렇게 건강하지 못한 민주주의가 된 이유는 바로 국가보안법 때문입니다.

저 노파같이 생각하는 사람들에게 발언의 기회조차 안준다면... 발언을 하면 국가원수모독죄니 이적행위니 뭐 이런걸로 처벌을 했다면 그런 비상식은 기형적으로 성장을 할 겁니다.


바로 국가보안법이 우리사회의 비상식을 기형적으로 성장하도록 조장한 근원입니다.





이번 국정원의 통진당 내란음모 모함을 통해 국가보안법의 불필요성이 다시 한번 부각될 것 같습니다.


이번 기회에 일제시대에 제정된 악법중의 악법인 국가보안법을 없애버리고 이 사회가 건강한 민주주의가 되도록 다같이 만들어 나갔으면 좋겠습니다.


그 회합에서 나온 일부 사람들의 발언은 분명 비 상식적입니다. 하지만 그런 비상식은 공개적인 공간에서, 햇볕이 비치는 양지에서 살균되고 정화될수 있는 수준입니다.

그런 비 상식을 음지로 몰아넣고 음지에서 활동하는 국정원이 악용하는 건강하지 못한 한국의 민주주의를 치료해야 합니다.


우리나라의 건강한 민주주의를 위해 국가보안법을 철폐합시다.


반응형


반응형

먹고 살기 바빠서 이런것도 시간들여서 한번 생각해 보는것도 부담됩니다....


기사를 보다 보니까 표창원 교수가 이런 말을 했다네요.


----------------------------------

표창원 전 경찰대 교수가 국가정보수사에 반발하고 있는 통합진보당에 대해 “통합진보당, 매우 아프겠지만, 이번 사건은 시민과 다른 야당 등에 도움 요청하는 것보다는 철저하게 법과 사실로 대응하시는 게 옳아 보입니다”라고 29일 밝혔다.

표 전 교수는 이날 트위터를 통해 이같이 표현한 후 “명확한 사실 알기 전에 ‘같은 편’ 되어 달라는 요구는 무리합니다. 모두 감시자가 되어 절차를 지켜볼 겁니다”라고 덧붙였다.

그는 이어 “이석기 의원, 옹호할 생각 추호도 없습니다. 법대로 원칙대로 수사, 입증하면 처벌해야. 무죄라도 발언내용 사실이면 의원직 박탈 필요”라며 “다만 정치적 목적으로 의혹 부풀리고 무리한 죄목 적용, 조직 위기 타개책으로 공안 여론몰이라면 엄중책임. 지켜봅니다”라고 전했다. 또 “국정원이 던진 마지막 승부수, 증거 없으면 역풍은 상상 이상이죠. 정권퇴진으로 이어질 겁니다. 지켜보시죠”라고 그는 덧붙였다.

------------------------------------


딱 내가 하고 싶은 말들이네요. ^^

그러고 보면 저는 아무래도 보수적인 성향이 많이 있나봐요.


진중권 교수가 올린 트위터 글도 눈에 들어 옵니다.


 

 

속은 시원하네요.

 

 

하나 덧 붙이자면..

 

국정원이 이 사건을 공개 수사한 시점이 뻔히 속이 보인다는 거죠.

 

국기 문란 사건을 저지른 국정원이 자기들에 대한 비난 여론을 잠재우려고 이 시점에 터뜨렸나본데...

어떻게 이 사건이 진행되던.. 또 어떻게 결론 나던 국정원 불법 정치 개입은 반드시 심판 받을 겁니다.

그리고 만약에 이번 사건이 조작이 심하다면 표창원 교수 말 대로 국정원 뿐만이 아니라 정권 퇴진이 이뤄질 일이죠...

 

현 정권이 어짜피 부정선거가 들어나면 물러날 것이 두려워서 이렇게 무리수를 두는 걸까요?

그냥 적당히 인정하고 국정원 개혁과 당정 쇄신으로 넘어갈 수도 있었던 것 같은데 괜히 자신들에게 많이 불리하게 돌아갈 수 있는 껀수를 하나 더 늘리네요.

 

이 껀 성공했다고 해서 국정원 불법선거 개입과 정치공작 그리고 부정선거가 그냥 잊혀지지는 않아요. 괜히 불리하게 진행될 수 있는 껀수만 하나 더 늘리신거예요 아주머니.....


반응형


반응형

Hannah Anderson Dismisses Critics, Explains Relationship with James DiMaggio

By Tim Nudd

08/22/2013 at 07:45 AM EDT 




Less than two weeks after her dramatic rescue, Hannah Anderson pushed back on Thursday at critics who have questioned her relationship with her abductor, James Lee DiMaggio – saying the letters and text messages she sent him were completely innocent.

극적으로 구출된지 2주일도 안되는 Hannah Anderson은 납치범 James Lee DiMaggio와의 관계에 의문을 가지는 의견들에 대해 응답했다. 그녀가 납치범에게 보낸 편지들과 문자메세지들은 범죄와는 상관 없는 일이라고 말했다.

On the very day she was abducted, Anderson, 16, reportedly sent as many as 13 texts to DiMaggio, who is suspected of killing Hannah's mother Christina, 44, and brother Ethan, 8, before being killed himself during an arrest attempt by the FBI.

그녀가 납치된 날 Anderson(16)은 그녀의 어머니인 Christina(44)와 남동생 Ethan(8)을 살해한 것으로 의심되는 DiMaggio에게 13통의 문자 메세지를 보냈다고 알려졌다. (DiMaggio는 납치 후 FBI에게 체포되는 과정에서 살해 당했다.)





But Hannah says the texts can be explained.

Hannah는 그 문자메세지에 대해서는 충분히 설명할 수 있다고 말했다.

"He was picking me up from cheer camp, and he didn't know the address or where I was," she said on the Today show. "So I had to tell him the address and tell him that I was going to be in the gym and not in front of the school, just so he knew where to come get me."

"그는 저를 cheer camp (치어리더들의 캠프)에서 pick up 했어요. 그는 그 주소도 몰랐고 제가 어디 있는지 조차 몰랐어요. 그래서 그에게 주소를 알려 줬죠. 그리고 학교 앞이 아니라 체육관에 갈거라고 얘기해 줬어요. 그래서 그가 저를 어디로 오면 만날 수 있는지 알았죠."라고 그녀는 Today show에서 말했다.

Anderson also wrote letters to DiMaggio, but says he was just helping her when she was having troubles.

Anderson은 또한 DiMaggio에게 편지를 썼었다. 그녀는 그 편지에 대해 DiMaggio 가 자신이 어려움에 처해 있을 때 도와줬었다고 말했다.

"The letters were from like a year ago, when me and my mom weren't getting along very well," she says. "Me and him would talk about how to deal with it. I'd tell him how I felt about it, and he'd help me through it. They weren't anything bad. They were just to help me through tough times."

"그 편지들은 한 1년 전 쯤에 썼던 거예요. 그때 제가 제 엄마와 별로 사이가 안 좋았었죠. DeMiggio는 제가 엄마와 사이가 안 좋은데 어떻게 해야 할 지에 대해 의논해 줬어요. 그에게 제 힘든 점을 얘기 했고 그는 저를 도와줬어요. 거기에 어떤 불순한 부분은 없었어요. 그 때 그냥 저를 도와 주려고 했었던 거예요." 




Though she finds herself on the defensive, Anderson says her critics just don't have the facts.

그녀는 그녀가 사실을 밝혔음에도 그녀를 향해 비판을 하는 내용들은 fact들이 없다고 말했다.

"They don't really know the story, so they kind of have their own opinion on what they hear," she says.

"그 사람들은 story를 제대로 알지 못해요. 그냥 그 사람들은 들은 얘기에 대해 자기 나름대로 생각하는 거예요."

She adds: "You are who you are, and you shouldn't let people change that. And you have your own opinion on yourself, and other people's opinions shouldn't matter."

그녀는 또 다음과 같이 덧 붙였다. "당신은 당신일 뿐이예요. 다른 사람들이 그것을 바꿀 수는 없어요. 당신은 당신에 대해 당신만의 견해를 가질 수 있어요. 그리고 다른 사람들은 그것에 대해 뭐라고 할 수 없어요."

Aside from defending herself, Anderson did find time to thank those who helped search for her, which eventually led to an FBI tactical agent killing DiMaggio while trying to arrest him on Aug. 10.

그녀는 자신의 의견을 밝히면서 납치된 그녀를 찾는데 협조한 사람들에 대해 감사의 뜻을 전하기도 했다. (FBI는 8월 10일 납치범 DiMaggio를 체포하는 작전 과정에서 그를 살해했다.)

"I would like to say thank you, because without them, I probably wouldn't be here right now," she says. "I want to thank the horsemen and the Amber Alert and the sheriff and the FBI, with everyone that put in time to find me, and my dad and my friends and my family and just all my supporters that helped spread the word."

"저는 협조한 모든 분들에 대해 감사를 드립니다. 그 분들이 없었으면 저는 여기 있을 수 없었을 거예요. 당시 말을 타고 있었던 분들이랑 Amber Alert 그리고 보안관들과 FBI에 그리고 저를 찾는데 협조해 주신 모든 분들께  감사의 뜻을 전하고 싶어요. 그리고 아빠와 친구들 그리고 제 가족들, 저를 찾는도 도움을 주기 위해 여기저기 납치 소식을 알려주신 모든 분들께도 감사드려요."


Visit NBCNews.com for breaking news, world news, and news about the economy


==========================================================


몇주전에 샌디에고에서 한 소녀가 납치되서 Amber Alert 이 발동됐었어요.

납치범이 그 소녀의 집에 불을 질러서 엄마와 남동생을 죽이고 그 소녀를 납치한건데요.


그 범인은 오하이오 주에서 FBI에 체포되는 과정에서 총에 맞아 죽고 그 소녀는 무사히 구출 됐어요.


그 사건이 일어나기 전서부터 그 소녀와 그 납치범은 편지와 문자 메세지를 주고 받을 정도로 친분이 있다는게 알려지면서 많은 이들이 이 사건에 대해 이런 저런 소문이 돌았어요.


저도 뭐가 있나? 하면서 궁금해 했는데 그 소녀가 그에 대해 인터뷰를 통해서 밝힌 기사가 있어서 한번 번역해 봤습니다.



Amber Alert : 정확한지는 모르지만 제가 아는 한에서는 미성년자가 납치됐을 경우 이 Amber Alert 이 발동 되요. 그러면 경찰은 그 지역 거주민의 핸드폰에 관련 내용에 대해 문자 메세지를 보내 협조를 부탁하고 고속도로에 있는 모든 전자 경고판에 사건 관련 안내 내용이 떠요.

제 핸드폰은 뉴저지 지역번호라서 이 문자 메세지를 받지는 못했는데요. (여긴 모바일 번호에만 사용되는 010 같은 게 따로 없고 그냥 일반 번호처럼 지역번호-국번-번호 이렇게 번호가 구성되요.)

이 지역번호로 시작하는 모바일을 가지고 있는 직장동료가 그러는데 그날 막 모바일이 삐삐 거리면서 사건 내용과 범인 자동차 색, 번호 뭐 이런게 문자 메세지로 왔대요. 그리고 출근 길에 고속도로에도 관련 내용이 display 되는 것을 봤다 그러구요. :)

반응형


반응형

ConstraintFixture



ConstraintFixtureCalculateFixtre의 변형 입니다. (see CalculateFixture) 이 ConstraintFixture는 각 calculation에 대한 true 값을 기대합니다.



Table Format



테이블의 첫번째 row는 fixture class 이름입니다. 그 다음 두번째 row에는 input parameter의 이름이 들어갑니다. 그 다음에 오는 모든 줄에는 input parameter의 값들을 넣구요.


!|ConstraintFixtureTest|
|firstPart|secondPart|
|1|2|
|2|3|





Fixture class

이 fixture class는 fitlibrary.ConstraintFixture를 extend 합니다. 여기에는 모든 파라미터 이름들로부터 나온 boolean method를 정의해야 합니다. (아래 예제의 경우에는 firstPartSecondPart이 됩니다.)



Java Source Code



package info.fitnesse.fixturegallery;

import fitlibrary.ConstraintFixture;

public class ConstraintFixtureTest extends ConstraintFixture{
    public boolean firstPartSecondPart(int firstPart,int secondPart){
        return firstPart<secondPart;
    }
}




.NET Source Code



using fitlibrary;
using System;

namespace info.fitnesse.fixturegallery
{
    public class ConstraintFixtureTest: ConstraintFixture
    {
        public bool FirstPartSecondPart(int  firstPart,int secondPart)
        {
            return firstPart<secondPart;
        }
    }
}




Python Source Code


# PYTHON: info.fitnesse.fixturegallery.CombinationFixtureTest
from fitLib.ConstraintFixture import ConstraintFixture

class ConstraintFixtureTest(ConstraintFixture):
    _typeDict = {}

    # PY3K: firstPartSecondPart(firstPart : int, secondPart : int) : bool
    _typeDict["firstPartSecondPart.types"] = [ "Boolean", "Int", "Int" ]
    def firstPartSecondPart(self, firstPart, secondPart):
        return firstPart < secondPart      


       


SetFixture




SetFixture는 한가지만 빼고는 ArrayFixture와 같습니다. (see ArrayFixture) 다른점은 row의 순서가 체크되지 않는다는 겁니다.



Notes



자바 flow mode 에서는 flow fixture method에서 return 된 set들이 자동적으로 SetFixture에 매핑됩니다.


Usage



자바에서는 JavaBean object를 사용할 때 RowFixture 대신에 SetFixture를 사용하세요. 왜냐하면 이 fixture가 JavaBeans getter에 대해 정확하게 기능을 제공하거든요. element들의 순서가 그렇게 중요하지 않을 때는 이 SetFixtureArrayFixture 대신에 사용하셔도 됩니다.



SubsetFixture



SubsetFixtureSetFixture의 변형입니다. (see SetFixture)  fixture table에 있는 row가 실제 row들의 subset이 될 수 있다는 부분 만 다릅니다.



Usage


잔여 element들을 무시하기를 원하신다면 RowFixtureSetFixture 대신에 이 SubsetFixture를 사용하세요. (예를 들어 같은 데이터베이스 테이블안에 있는 다른 row들은 상관하지 않고 데이터베이스의 어떤 row들의 존재를 체크하고 싶은 경우 등을 들 수 있습니다.)

반응형