res/ layout/ main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

</LinearLayout>


res/ layout/ splash.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/intro_black"
    android:gravity="center_vertical|center_horizontal"
    android:orientation="vertical" >

   <!--  
   <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="loading..."
        android:textSize="20sp"
        android:textStyle="bold" >
    </TextView>
    -->
</LinearLayout>


package kr.android.vichara;
//시작되는 & 로딩페이지(로딩페이지를 호출함)
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Window;

public class MainActivity extends Activity{
	@Override
	public void onCreate(Bundle savedInstanceState){
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		super.onCreate(savedInstanceState);
		setContentView(R.layout.splash);//로딩 이미지 있는곳

		initialize();
	}

	private void initialize(){
		Handler handler =    new Handler(){
			@Override
			public void handleMessage(Message msg){
				finish();    // 액티비티 종료
				startActivity(new Intent(MainActivity.this, SplashActivity.class));//이동될 클래스
			}
		};
		handler.sendEmptyMessageDelayed(0, 3000);    // ms, 3초후 종료시킴
	}
}


package kr.android.vichara;
//이동되는곳
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class SplashActivity extends Activity{
	@Override
	public void onCreate(Bundle savedInstanceState){
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);//로딩후 보여질페이지


		initialize();  // 시간이 걸리는 작업 처리
	}

	//스플래시 표시하는 것과 초기화를 동시에 진행시키기 위하여 쓰레드 처리
	private void initialize(){
		InitializationRunnable init = new InitializationRunnable();
		new Thread(init).start();
	}

	//초기화
	class InitializationRunnable implements Runnable{
		public void run(){
			// 여기서부터 초기화 작업 처리
			// do_something
		}
	}
}




'Android > 기본' 카테고리의 다른 글

Android 9 patch  (0) 2012.05.14
예비  (0) 2012.04.28
Android 카메라, 인증키(키스토어)  (0) 2012.04.28
Android surface(마우스에 이미지 따라다니기)  (0) 2012.04.28
Android Video View (동영상 재생)  (0) 2012.04.28

카메라 권한 , sd 쓰기 권한










인증키 만들기

:팩키지명 안겹치게.
:인증키 잃어버리지 말기.
:인증키 유효기간 넉넉하게 1000년







업데이트하기







스크린캡쳐









package net.npaka.cameraex;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class CameraEx extends Activity {
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(new CameraView(this));
	}
}


package net.npaka.cameraex;

import android.content.Context;
import android.hardware.Camera;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.FileOutputStream;

//카메라제어
public class CameraView extends SurfaceView implements 
                 SurfaceHolder.Callback,Camera.PictureCallback{
	private SurfaceHolder holder; //홀더
	private Camera camera;//카메라

	//생성자
	public CameraView(Context context){
		super(context);

		//표면 홀더 생성 
		holder=getHolder();
		holder.addCallback(this);
		//푸쉬 버퍼 지정(1)
		holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	}

	//표면생성 이벤트의 처리
	public void surfaceCreated(SurfaceHolder holder){
		//카메라 초기화 (2)
		try{
			camera=Camera.open();
			camera.setPreviewDisplay(holder);
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	//표면 변경 이벤트 처리
	public void surfaceChanged(SurfaceHolder holder, int format,int w, int h){
		//카메라 미리보기 시작(3)
		camera.startPreview();
	}

	//표면 파괴 이벤트 처리
	public void surfaceDestroyed(SurfaceHolder holder){
		//카메라 미리보기 정지(4)
		camera.setPreviewCallback(null);
		camera.stopPreview();
		camera.release();
		camera=null;
	}

	// 터치 이벤트 처리
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (event.getAction() ==MotionEvent.ACTION_DOWN) {
			// 카메라 스크린 샷 구하기 (5)
			camera.takePicture(null,null,this);
		}
		return true;
	}

	// 사진 촬영 완료 시 불린다.
	public void onPictureTaken(byte[] data,Camera camera) {
		// 파일 보존과 갤러리로의 등록
		try {
			data2sd(getContext(),data,"test.jpg");
		} catch (Exception e) {
			android.util.Log.e("",""+e.toString());
		}

		// 미리보기 재개
		camera.startPreview();
	}

	// 바이트 데이터→SD 카드
	private static void data2sd(Context context,
			byte[] w,String fileName) throws Exception {
		// SD 카드에 데이터 저장 (6)
		FileOutputStream fos=null;
		try {
			fos=new FileOutputStream("/sdcard/"+fileName);
			fos.write(w);
			fos.close();
		} catch (Exception e) {
			if (fos!=null) fos.close();
			throw e;
		}
	}
}





'Android > 기본' 카테고리의 다른 글

예비  (0) 2012.04.28
Android 메인로딩 페이지 만들기  (0) 2012.04.28
Android surface(마우스에 이미지 따라다니기)  (0) 2012.04.28
Android Video View (동영상 재생)  (0) 2012.04.28
Android Audio사용 (음악 재생)  (0) 2012.04.28
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

</LinearLayout>


MainAct
package aa.surface_ex1;

import android.app.Activity;
import android.os.Bundle;

public class MainAct extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MySurfaceView(this));
    }
}


MySurfaceView
package aa.surface_ex1;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Point;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.graphics.Canvas;
import android.view.SurfaceHolder.Callback;

/*
View 에 동영상 또는 카메라 프리뷰와 같이 빠른 화면 변화 또는
그러지는 양이 많을 경우 SurfaceView를 사용해 처리
Surface 는 그래픽 버퍼
Surfaceview 에서 화면 제어를 하기 위해 SurfaceHolder 생성


=-=-=-=--=-=-=-=-=-=-==-=-=-=
		Surface View
=-=-=-=--=-=-=-=-=-=-==-=-=-=
			Surface
=-=-=-=--=-=-=-=-=-=-==-=-=-=
		SurfaceHolder
		
SurfaceHolder를 이용해서 surface(버퍼)에 그림을 그리면 SurfaceView에 반영

*/

public class MySurfaceView extends SurfaceView{
	Bitmap imgMove;
	int moveX,moveY,imgW,imgH;
	Thread thread;
	Point pImage;
	boolean bMove = true;
	SurfaceHolder holder; //canvas의 주체

	public MySurfaceView(Context context) {
		super(context);
		/*SurfaceHolder 주요 메소드
		addCallBack(); 구현한 Callback 객체 등록
		lookccanvas() : Surface를 잠그고 그리기 위한
						Canvas를 반환
		unlockCanvasAndPost() : Canvas lock을 풀고 현재 이미지를 렌더링
		*/

		holder = getHolder(); //SurfaceHolder 객체 반환
		holder.addCallback(callback);
		setFocusable(true);
	}
	/*Surface에 변동사항을 전달할 객체
	Callback Interface는 SurfaceHolder를 통해 작성한
	Surface와 SurfaceView를 연결하기 위해서 Surfcae의 생성,변경 종료에 대한 이벤트 처리
	*/
	private SurfaceHolder.Callback callback = new Callback(){
		//Surface가 파괴되었을때
		public void surfaceDestroyed(SurfaceHolder holder){
			Log.i("MySurfaceView", "표면 파괴");
			bMove = false;
			thread = null;
		}
		public void surfaceCreated(SurfaceHolder holder){
			Log.i("MySurfaceView", "표면 생성");
			pImage = new Point(0,0);

			Resources resources = getResources();
			Bitmap temp_bitmap = BitmapFactory.decodeResource(resources, R.drawable.popeye);

			imgW = 150;
			imgH = 180;
			moveX = 200;
			moveY = 200;

			imgMove = Bitmap.createScaledBitmap(temp_bitmap,imgW,imgW,false);
			setClickable(true);
			thread = new Thread(runnable);
			thread.start();
		}
		//Surface가 변경되었을때
		public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){
			Log.i("MySurfaceView", "표면 변경");
		}
	};
	private Runnable runnable = new Runnable() {

		public void run() {
			while(bMove){
				Canvas c = null;
				try {
					c = holder.lockCanvas();
					synchronized (holder) {
						doDraw(c);
					}
				} catch (Exception e) {
					Log.i("disp", "err : " + e.getMessage());
				} finally{
					if(c != null) holder.unlockCanvasAndPost(c);
				}
			}
		}
	};

	private void doDraw(Canvas canvas){
		pImage.x = moveX;
		pImage.y = moveY;
		canvas.drawColor(Color.WHITE);
		canvas.drawBitmap(imgMove, pImage.x,pImage.y, null);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int action = event.getAction();

		//touch 지점의 좌표
		int x = (int)event.getX();
		int y = (int)event.getY();

		switch (action) {
		case MotionEvent.ACTION_MOVE:
			moveX = x;
			moveY = y;
			break;
		}
		return super.onTouchEvent(event);
	}
}


마우스에 이미지가 따라 다님



'Android > 기본' 카테고리의 다른 글

Android 메인로딩 페이지 만들기  (0) 2012.04.28
Android 카메라, 인증키(키스토어)  (0) 2012.04.28
Android Video View (동영상 재생)  (0) 2012.04.28
Android Audio사용 (음악 재생)  (0) 2012.04.28
Android Constants Provider  (0) 2012.04.28

파일위치



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <VideoView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/videoView" />

</LinearLayout>


package net.npaka.videoviewex;

import android.app.Activity;
import android.os.Bundle;
import android.content.Context;
import android.widget.VideoView;
import android.widget.MediaController;
import java.io.InputStream;
import java.io.OutputStream;

//동영상 재생
public class VideoViewEx extends Activity {
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		//비디오 뷰의 생성(1)
		VideoView videoView = (VideoView)this.findViewById(R.id.videoView);
		videoView.requestFocus();
		videoView.setMediaController(new MediaController(this));

		try{
			/*  case1  */
			//videoView.setVideoPath("/sdcard/be_my_baby5.mp4");

			/*  case2  */
			//videoView.setVideoURI(
			//		Uri.parse("http://192.168.200.105:8080/web/be_my_baby5.mp4"));

			/* case 3 */
			//Raw 자원의 파일 저장(2)
			raw2file(this,R.raw.be_my_baby5,"be_my_baby5.mp4");

			//동영ㅇ상의 재생 (3)
			String path = getFilesDir().getAbsolutePath()+"/be_my_baby5.mp4";
			videoView.setVideoPath(path);
			videoView.start();

		}catch(Exception e){
			android.util.Log.e("", e.toString());
		}
	}
	// Raw 자원의 파일 보존
	private void raw2file(Context context,
			int resID,String fileName) throws Exception {
		InputStream in=context.getResources().openRawResource(resID);
		in2file(context,in,fileName);
	}

	// 입력 스트림의 파일 보존
	private void in2file(Context context,
			InputStream in,String fileName)
					throws Exception {
		int size;
		byte[] w=new byte[1024];
		OutputStream out=null;
		try {
			out=context.openFileOutput(fileName,Context.MODE_WORLD_READABLE);
			while (true) {
				size=in.read(w);
				if (size<=0) break;
				out.write(w,0,size);
			};  
			out.close();
			in.close();
		} catch (Exception e) {
			try {
				if (in !=null) in.close();
				if (out!=null) out.close();
			} catch (Exception e2) {
			}
			throw e;
		}
	}  
}



실행화면 (에뮬레이터 에선 원활히 구동되지 않습니다)




음악파일 위치


<?xml version="1.0"  encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/startPlayerBtn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="오디오 재생 시작" />

    <Button
        android:id="@+id/restartPlayerBtn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="재생 재개" />

    <Button
        android:id="@+id/pausePlayerBtn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="재생 일시중지" />

</LinearLayout>


package com.proandroid;

import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;


public class SimpleAudio extends Activity {
	static final String AUDIO_PATH = "http://211.183.2.90/web/upload/the_boys.mp3";
	
	private MediaPlayer mediaPlayer;
	private int playbackPosition=0;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Button startPlayerBtn = (Button)findViewById(R.id.startPlayerBtn);
        Button pausePlayerBtn = (Button)findViewById(R.id.pausePlayerBtn);
        Button restartPlayerBtn = (Button)findViewById(R.id.restartPlayerBtn);
        
        startPlayerBtn.setOnClickListener(new OnClickListener(){
        	
        	public void onClick(View view){
        		try{
        			playLocalAudio();
        			//playAudio(AUDIO_PATH);
        			//playSdcardAudio();
        			//playLocalAudio_UsingDescriptor();
        		}catch(Exception e){
        			e.printStackTrace();
        		}
        	}
        });
       
        pausePlayerBtn.setOnClickListener(new OnClickListener(){
        	public void onClick(View view){
        		if(mediaPlayer!=null){
        			//음악을 일시 정지 시킬때 정지되기 직전의 position값 저장
        			playbackPosition = mediaPlayer.getCurrentPosition();
        			//일시정지
        			mediaPlayer.pause();
        		}
        	}
        });
        
        restartPlayerBtn.setOnClickListener(new OnClickListener(){
        	public void onClick(View view){
        		//MediaPlayer 객체가 존재하고 현재 실행중이 아닐때
        		if(mediaPlayer!=null && !mediaPlayer.isPlaying()){
        			//음악이 일시정지되기 직전의 position값으로 셋팅
        			mediaPlayer.seekTo(playbackPosition);
        			mediaPlayer.start();
        		}
        	}
        });
    } 
    
    private void playLocalAudio()throws Exception{
    	//어플리케이션에 내장되 있는 자원을 호출해서 MediaPlayer객체 생성
    	mediaPlayer=MediaPlayer.create(this, R.raw.the_boys);
    	//MediaPlayer 객체가 가지고 있는 음악 정보를 start
    	mediaPlayer.start();
    }
    private void  playAudio(String url)throws  Exception{
		killMediaPlayer();

		mediaPlayer = new MediaPlayer();
		mediaPlayer.setDataSource(url);
		mediaPlayer.prepare();
		mediaPlayer.start();
	}	
	private void playSdcardAudio()throws Exception{
		mediaPlayer = new MediaPlayer();
		mediaPlayer.setDataSource("/sdcard/twoneone.mp3");
		mediaPlayer.prepare();
		mediaPlayer.start();
	}
	private void playLocalAudio_UsingDescriptor() throws Exception {

		AssetFileDescriptor fileDesc = 
				getResources().openRawResourceFd(R.raw.twoneone);
		if(fileDesc!=null){
			mediaPlayer=new MediaPlayer();
			mediaPlayer.setDataSource(
					fileDesc.getFileDescriptor(), 
					fileDesc.getStartOffset(),
					fileDesc.getLength());
			mediaPlayer.prepare();
			mediaPlayer.start();
			fileDesc.close();
		}
	}
    
    @Override
    protected void onDestroy(){
    	super.onDestroy();
    	killMediaPlayer();
    }

	private void killMediaPlayer() {
		if(mediaPlayer!=null){
			try{
				//MediaPlayer 자원해제
				mediaPlayer.release();
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		
	}
}







Java File



Application -> ADD -> Provider

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="DB정보가 셋팅되었습니다." />

</LinearLayout>


main activity
package dr.android.contents;

import android.app.Activity;
import android.os.Bundle;

public class ConstantsOne extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}


Provider
package dr.android.contents;

import java.util.HashMap;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.hardware.SensorManager;
import android.net.Uri;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;

public class Provider extends ContentProvider{
	//DB명
	private static final String DATABASE_NAME ="constants.db";
	//테이블 명
	private static final String TABLE_NAME = "constants";
	//URI중 고유이름 지정
	private static final String AUTHORITY = "dr.android.contents.Provider";
	//집합데이터와 개별 데이터 구별을 위한 상수 지정
	private static final int CONSTANTS =1;
	private static final int CONSTANT_ID=2;
	//URI 정보를 갖는 객체 선언
	private static final UriMatcher MATCHER;
	//마임타입 지정 (집합데이터/개별데이터)
	private static final String COLLECTION_TYPE = 
			"vnd.android.cursor.dir/vnd.commonsware.constant";
	private static final String SINGLE_TYPE = 
			"vnd.android.cursor.item/vnd.commonsware.constant";
	//컬럼 명세 갖는 객체 선언
	private static HashMap<string,string> CONSTANTS_LIST_PROJECTION;

	//SQLite 연동을 위한 db선언
	private SQLiteDatabase db;

	public static final class Constants implements BaseColumns{
		public static final Uri CONTENT_URI =Uri.parse("content://"+AUTHORITY+"/constants");
		public static final String TITLE="title";
		public static final String VALUE="value";
	}
	static {
		//UriMatcher 객체 생성
		//전달되는 Uri가 집합데이터를 의미하는지 개별데이터를 의미하는지 여부 판결
		MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
		MATCHER.addURI(AUTHORITY, "constants", CONSTANTS);
		MATCHER.addURI(AUTHORITY, "constants/#", CONSTANT_ID);

		//컬럼 명세를 보관하는 객체
		CONSTANTS_LIST_PROJECTION = new HashMap<string,string>();
		CONSTANTS_LIST_PROJECTION.put(Provider.Constants._ID, Provider.Constants._ID);
		CONSTANTS_LIST_PROJECTION.put(Provider.Constants.TITLE, Provider.Constants.TITLE);
		CONSTANTS_LIST_PROJECTION.put(Provider.Constants.VALUE, Provider.Constants.VALUE);
	}
	
	@Override
	public boolean onCreate(){
		db=(new DatabaseHelper (getContext())).getWritableDatabase();
		return (db ==null)?false:true;
	}

	//전달된 URI를 통해서
	//집합데이터 / 개별데이터 요청 요부를 확인
	private boolean isCollectionUri(Uri url) {
		return(MATCHER.match(url)==CONSTANTS);
	}

	//기본 컬럼 명세를 갖고있는 객체 반환
	private HashMap<string, string=""> getDefaultProjection() {
		return(CONSTANTS_LIST_PROJECTION);
	}

	@Override
	public Cursor query(Uri url, String[] projection, String selection,
			String[] selectionArgs, String sort) {
		SQLiteQueryBuilder qb=new SQLiteQueryBuilder();

		qb.setTables(TABLE_NAME);

		if (isCollectionUri(url)) {
			//집합 데이터
			qb.setProjectionMap(getDefaultProjection());
		}
		else {
			//개별 데이터
			qb.appendWhere(Provider.Constants._ID+"="+url.getPathSegments().get(1));
		}

		String orderBy;

		if (TextUtils.isEmpty(sort)) {
			//전달되는 정렬 정보가 없을 경우
			orderBy=Provider.Constants.TITLE;
		} else {
			//전달되는 정렬 정보가 있을 경우
			orderBy=sort;
		}

		Cursor c=qb.query(db, projection, selection, selectionArgs,
				null, null, orderBy);
		//URI 원본자료가 변하면 그 사실을 Cursor 객체에 통보하는 역할
		//예)update후 query될 때 update시 변경된 자료 반영
		c.setNotificationUri(getContext().getContentResolver(), url);
		return c;
	}

	@Override
	public String getType(Uri url) {
		if (isCollectionUri(url)) {
			
			return(COLLECTION_TYPE);
		}
		
		return(SINGLE_TYPE);
	}

	@Override
	public Uri insert(Uri url, ContentValues initialValues) {
		long rowID;
		ContentValues values;

		if (initialValues!=null) {
			values=new ContentValues(initialValues);
		} else {
			values=new ContentValues();
		}

		if (!isCollectionUri(url)) {
			throw new IllegalArgumentException("Unknown URL " + url);
		}

		rowID=db.insert(TABLE_NAME, Provider.Constants.TITLE, values);
		if (rowID > 0) {
			Uri uri=ContentUris.withAppendedId(Provider.Constants.CONTENT_URI, rowID);
			getContext().getContentResolver().notifyChange(uri, null);
			return uri;
		}
		throw new SQLException("Failed to insert row into " + url);
	}

	@Override
	public int delete(Uri url, String where, String[] whereArgs) {
		int count;
		long rowId=0;

		if (isCollectionUri(url)) {
			count=db.delete(TABLE_NAME, where, whereArgs);
		}
		else {
			String segment=url.getPathSegments().get(1);
			rowId=Long.parseLong(segment);
			count=db
			.delete(TABLE_NAME, Provider.Constants._ID+"="
					+ segment
					+ (!TextUtils.isEmpty(where) ? " AND (" + where
							+ ')' : ""), whereArgs);
		}

		getContext().getContentResolver().notifyChange(url, null);
		return count;
	}

	@Override
	public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
		int count;

		if (isCollectionUri(url)) {
			count=db.update(TABLE_NAME, values, where, whereArgs);
		}
		else {
			String segment=url.getPathSegments().get(1);
			count=db
			.update(TABLE_NAME, values, Provider.Constants._ID+"="
					+ segment
					+ (!TextUtils.isEmpty(where) ? " AND (" + where
							+ ')' : ""), whereArgs);
		}

		getContext().getContentResolver().notifyChange(url, null);
		return count;
	}
	private class DatabaseHelper extends SQLiteOpenHelper {
		public DatabaseHelper(Context context) {
			super(context, DATABASE_NAME, null, 1);
		}

		
		
		@Override
		public void onCreate(SQLiteDatabase db) {

			try {
				db.execSQL(
				"CREATE TABLE constants (_id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, value REAL);");

				ContentValues cv=new ContentValues();
 
				cv.put(Constants.TITLE, "Gravity, Death Star I");
				cv.put(Constants.VALUE, SensorManager.GRAVITY_DEATH_STAR_I);
				db.insert("constants", Provider.Constants.TITLE, cv);

				cv.put(Constants.TITLE, "Gravity, Earth");
				cv.put(Constants.VALUE, SensorManager.GRAVITY_EARTH);
				db.insert("constants", Provider.Constants.TITLE, cv);

				cv.put(Constants.TITLE, "Gravity, Jupiter");
				cv.put(Constants.VALUE, SensorManager.GRAVITY_JUPITER);
				db.insert("constants", Provider.Constants.TITLE, cv);

				cv.put(Constants.TITLE, "Gravity, Mars");
				cv.put(Constants.VALUE, SensorManager.GRAVITY_MARS);
				db.insert("constants", Provider.Constants.TITLE, cv);
			}catch(SQLException e){
				Log.e("Provider",e.toString());
			}
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			Log.w("Constants", "Upgrading database, which will destroy all old data");
			db.execSQL("DROP TABLE IF EXISTS constants");
			onCreate(db);
		}
	}
}





res/ layout/ add_edit.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:text="이름:" />

        <EditText
            android:id="@+id/title"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:text="값:" />

        <EditText
            android:id="@+id/value"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true" />
    </LinearLayout>

</LinearLayout>


res/ layout/ main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Hello World, ConstantsBrowser" />

</LinearLayout>


res/ layout/ row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true" />

    <TextView
        android:id="@+id/value"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true" />

</RelativeLayout>


res/ values/ strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
        <string name="app_name">77ConstantsTwo</string>
        <string name="ok">확인</string>
        <string name="cancel">취소</string>
        <string name="add_title">상수 추가</string>
        <string name="delete_title">상수 데이터를 제거하시겠습니까?</string>
</resources>


src/ dr.android.contents2/ ConstantsTwo
package dr.android.contents2;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;

public class ConstantsTwo extends ListActivity {
	private static final String TITLE="title";
	private static final String VALUE="value";
	private static final String CONTENT_URI = 
			"content://dr.android.contents.Provider/constants";
	private static final String[] PROJECTION = new String[] {
		BaseColumns._ID, TITLE, VALUE};
	private Cursor constantsCursor;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//manageQuery()와 getContentResolver().query() 둘다 사용가능
		constantsCursor=managedQuery(
				Uri.parse(CONTENT_URI),PROJECTION, null, null, null);

		ListAdapter adapter=new SimpleCursorAdapter(this,
				R.layout.row, constantsCursor,
				new String[] {TITLE,VALUE},
				new int[] {R.id.title, R.id.value});

		setListAdapter(adapter);
		registerForContextMenu(getListView());
	}

	@Override
	public void onDestroy() {
		super.onDestroy();

		constantsCursor.close();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(Menu.NONE, 1, Menu.NONE, "추가")
		.setIcon(R.drawable.add)
		.setAlphabeticShortcut('a');
		menu.add(Menu.NONE, 2, Menu.NONE, "종료")
		.setIcon(R.drawable.eject)
		.setAlphabeticShortcut('c');

		return(super.onCreateOptionsMenu(menu));
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case 1:
			add();
			return(true);

		case 3:
			finish();
			return(true);
		}

		return(super.onOptionsItemSelected(item));
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenu.ContextMenuInfo menuInfo) {
		menu.add(Menu.NONE, 2, Menu.NONE, "삭제")
		.setIcon(R.drawable.delete)
		.setAlphabeticShortcut('d');
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case 2:
			AdapterView.AdapterContextMenuInfo info=
			(AdapterView.AdapterContextMenuInfo)item.getMenuInfo();

			delete(info.id);
			return(true);
		}

		return(super.onOptionsItemSelected(item));
	}

	private void add() {
		LayoutInflater inflater=LayoutInflater.from(this);
		View addView=inflater.inflate(R.layout.add_edit, null);
		final DialogWrapper wrapper=new DialogWrapper(addView);

		new AlertDialog.Builder(this)
		.setTitle(R.string.add_title)
		.setView(addView)
		.setPositiveButton(R.string.ok,
				new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog,
					int whichButton) {
				processAdd(wrapper);
			}
		})
		.setNegativeButton(R.string.cancel,
				new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog,
					int whichButton) {
				// ignore, just dismiss
			}
		})
		.show();
	}

	private void delete(final long rowId) {
		if (rowId>0) {
			new AlertDialog.Builder(this)
			.setTitle(R.string.delete_title)
			.setPositiveButton(R.string.ok,
					new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog,
						int whichButton) {
					processDelete(rowId);
				}
			})
			.setNegativeButton(R.string.cancel,
					new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog,
						int whichButton) {
					// ignore, just dismiss
				}
			})
			.show();
		}
	}

	private void processAdd(DialogWrapper wrapper) {
		ContentValues values=new ContentValues(2);

		values.put(TITLE, wrapper.getTitle());
		values.put(VALUE, wrapper.getValue());

		getContentResolver().insert(Uri.parse(CONTENT_URI),values);
		constantsCursor.requery();
	}

	private void processDelete(long rowId) {
		Uri uri=ContentUris.withAppendedId(Uri.parse(CONTENT_URI),rowId);
		getContentResolver().delete(uri, null, null);
		constantsCursor.requery();
	}

	class DialogWrapper {
		EditText titleField=null;
		EditText valueField=null;
		View base=null;

		DialogWrapper(View base) {
			this.base=base;
			valueField=(EditText)base.findViewById(R.id.value);
		}

		String getTitle() {
			return(getTitleField().getText().toString());
		}

		float getValue() {
			return(new Float(getValueField().getText().toString()).floatValue());
		}

		private EditText getTitleField() {
			if (titleField==null) {
				titleField=(EditText)base.findViewById(R.id.title);
			}

			return(titleField);
		}

		private EditText getValueField() {
			if (valueField==null) {
				valueField=(EditText)base.findViewById(R.id.value);
			}

			return(valueField);
		}
	}
}









'Android > 기본' 카테고리의 다른 글

Android Video View (동영상 재생)  (0) 2012.04.28
Android Audio사용 (음악 재생)  (0) 2012.04.28
Android FileSearch Gallery(사진선택)  (0) 2012.04.28
Android Animaiton 으로 효과 (2)  (0) 2012.04.28
Android Paint로 그림그리기  (0) 2012.04.28
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/photo"
        android:visibility="gone"
        android:layout_weight="1" />
    
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/text"
        android:visibility="gone"
        android:layout_weight="0"/>
    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/button01"
        android:text="사진 선택"
        android:layout_weight="0" />

</LinearLayout>


package dr.android.file.search;

import android.app.Activity;
import android.os.Bundle;
import java.io.File;
import java.io.IOException;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore.Images;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

public class FileSearchbyGallery extends Activity implements OnClickListener {
	ImageView photo;
	Button button01;
	TextView text;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		photo = (ImageView) findViewById(R.id.photo);
		text = (TextView) findViewById(R.id.text);
		button01 = (Button) findViewById(R.id.button01);

		button01.setOnClickListener(this);
	}

	public void onClick(View v) {
		// 갤러리를 호출해서 휴대폰에 저장된 이미지를 읽어들임
		Intent intent = new Intent();
		intent.setAction(Intent.ACTION_GET_CONTENT);
		intent.setType("image/*");// image/jpg, image/png
		startActivityForResult(intent, 0);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (data != null) {
			try {
				Uri uri = data.getData();
				// 이미지 정보 추출 및 표시
				text.setText("========이미지 정보===\n");
				text.append("URI : " + uri.toString() + "\n");
				text.append("Last Path Segment : " + uri.getLastPathSegment()
						+ "\n");
				//컨텐트 프로바이더로 구성된 정보를 DB로 부터 읽어옴
				Cursor c = getContentResolver().query(
						Images.Media.EXTERNAL_CONTENT_URI, null,
						Images.Media._ID + "=?",
						new String[] { uri.getLastPathSegment() }, null);

				if (c.moveToFirst()) {
					//getColumnIndexOrThrow : 컬럼의 인덱스 반환
					String imageFile = c.getString(c
							.getColumnIndexOrThrow(Images.Media.DATA));
					File f = new File(imageFile);
					text.append("원본 이미지 경로 : " + imageFile + "\n");
					text.append("이미지 용량 : " + f.length() + "\n");
				}
				text.setVisibility(View.VISIBLE);

				// ImageView 이미지 보여주기
				//컨텐트 프로바이더로 구성된 정보를 URI를 통해 읽어옴
				Bitmap image = Images.Media
						.getBitmap(getContentResolver(), uri);

				text.append("크기 : " + image.getWidth() + "*"
						+ image.getHeight() + "\n");

				photo.setImageBitmap(image);
				photo.setVisibility(View.VISIBLE);

			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}




'Android > 기본' 카테고리의 다른 글

Android Audio사용 (음악 재생)  (0) 2012.04.28
Android Constants Provider  (0) 2012.04.28
Android Animaiton 으로 효과 (2)  (0) 2012.04.28
Android Paint로 그림그리기  (0) 2012.04.28
Android Preferences 읽고 쓰기(환경설정)  (0) 2012.04.28

이미지가 서서히 변하는 효과(자연스럽게)

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:gravity="center" >

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/img"
        android:src="@drawable/jessica" />

</LinearLayout>


alpha.xml
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:fromAlpha="0.0"
    android:toAlpha="1.0"
    android:duration="2000"   />

<!--
    interpolator : 안드로이드에서 인터폴레이터는 애니메이션의 변화 정도를 정의
           이 값을 조정하여 애니메이션을 가속시킬 수도 있고, 감속시킬 수도 있으며 반복시킬수도 있음
    fromAlpha : 애니메이션 시작
    toAlpha : 애니메이션 끝
           알파값 : 0.0 (완전투명) ~ 1.0(완전 불투명)
    duration : 애니메이션이 진행되는데 "지연시간 (밀리세컨드)"
           참조 클래스 : android.viewanimation.AlphaAnimaiton

-->




main activity
package kr.android.animation;

import android.app.Activity;
import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;

public class AnimationDemo1 extends Activity {
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		ImageView image = (ImageView)findViewById(R.id.img);
		Animation alphaAnim = AnimationUtils.loadAnimation(this, R.anim.alpha);
		image.startAnimation(alphaAnim);
	}
}





이미지가 확대 되고 한바퀴 돌려지는 효과 (캡쳐는 일부분)

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:gravity="center" >

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/img"
        android:src="@drawable/jessica" />

</LinearLayout>




tween.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 
여러 가지 애니메이션 효과를 set로 묶어줌.
 -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
	android:interpolator="@android:anim/accelerate_decelerate_interpolator">
<!-- 
여러 가지 android:interpolator
1) 가속효과(accelerate,시작은 천천히, 갈수록 가속화) : accelerate_interpolator
2) 감속효과(decelarate, 시작은 빨리, 갈수록 감속화) : decelerate_interpolator
3) 가속/감속(시작과 끝은 천천히, 중간은 가속화) : accelerate_decelerate_interpolator
4) 튀는 효과(bounce, 공이 튀는 듯한 효과) : bounce_interpolator
5) 예측효과(anicipate,개구리가 움츠렸다 튀어나가는 듯한 효과) : anicipate_interpolator
6) 예측/넘침효과 : anicipate_overshoot_interpolator
7) 반복효과(cycle, 수학의 사인곡선을 이용하여 지정한 횟수만큼 반복):cycle_interpolator
8) 선형적인 변화지수(linear):linear_interpolator
9) 넘침효과(overshoot,원래 지정된 애니메이션 목표를 지나쳐버리는 효과):overshoot_interpolator
 --> 	
	<alpha 
       android:interpolator="@android:anim/accelerate_interpolator"
       android:fromAlpha="0.0" 
       android:toAlpha="1.0" 
       android:duration="1000" 
       />
	<scale 
		android:fromXScale="1.0" android:toXScale="2.0" 
		android:fromYScale="1.0" android:toYScale="2.0" 
		android:pivotX="50" android:pivotY="50%p"
		android:startOffset="2000"
		android:duration="1000" 
		/>
<!-- 
 pivotX, pivotY
 확대 변형을 하려면, 확대할 기준점이 필요. 이 값을 지정하지 않으면 객체의 중심점을 기준으로 변경
 "50"과 "50%"는 변형 대상 객체의 크기에 비율을 의미, "50%p"는 변형 대상 객체의 부모의 크기에 비례하여
 중심점을 정함.
 
 startOffset을 "2000"으로 하면 확대 효과를 2초 후에 작동하도록 설정
 -->	
	<translate 
		android:fromXDelta="0" 
		android:toXDelta="0" 
		android:fromYDelta="0" 
		android:toYDelta="50%" 
		android:startOffset="3000"
		android:duration="1000" 
		/>
	<rotate 
		android:fromDegrees="0" android:toDegrees="360"
		android:pivotX="0" android:pivotY="50%p"
		android:startOffset="4000"
		android:duration="1000" />
</set>	


package kr.android.animation2;

import android.app.Activity;
import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;

public class AnimationDemo2 extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        ImageView image = (ImageView)findViewById(R.id.img);
        Animation tween = AnimationUtils.loadAnimation(this, R.anim.tween);
        image.startAnimation(tween);
    }
}


012


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

</LinearLayout>


package com.hardrock.hellotest;

import android.app.Activity;
import android.os.Bundle;
import android.graphics.Canvas;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.view.View;

public class PaintDemo extends Activity {
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(new ViewWithDraw(this));
	}

	private static class ViewWithDraw extends View{

		public ViewWithDraw(Context context){
			super(context);
		}

		@Override
		protected void onDraw(Canvas canvas){
			//백그라운드 색깔지정
			canvas.drawColor(Color.BLACK);

			Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

			//draw Line
			mPaint.setColor(Color.RED); //도형의 색깔지정
			mPaint.setStrokeWidth(10);	//도형의 두께
			canvas.drawLine(50, 0, 50, 100, mPaint);
						//시작 x 시작 y 끝x 끝y   paint객체

			mPaint.setColor(Color.GREEN);
			mPaint.setStrokeWidth(5);
			//alpha : 0(투명) ~255 (완전 불투명)
			for(int y = 30,alpha =255; alpha>2 ; alpha -=50, y+=10){
				//alpha값 지정(투명도)를 지정
				mPaint.setAlpha(alpha);
				canvas.drawLine(0,y,100,y,mPaint);
			}
			
			// draw Rect
			mPaint.setColor(Color.WHITE);
			// 테두리만 그린다.
			mPaint.setStyle(Paint.Style.STROKE);
			mPaint.setStrokeWidth(1);
			canvas.drawRect(120, 10, 120 + 80, 10 + 80, mPaint);
						 //left top    right     bottom
			
			mPaint.setColor(Color.MAGENTA);
			// 내부를 채운다
			mPaint.setStyle(Paint.Style.FILL);
			canvas.drawRect(220, 10, 220 + 80, 10 + 80, mPaint);

			// draw Arc(원호 원의 일부분)
			mPaint.setColor(Color.YELLOW);
			canvas.drawArc(new RectF(150, 120, 150 + 100, 120 + 100), 0, 50,
					true, mPaint); // 시작각도(0) , 끝각도(50), 중심사용여부(true)

			// draw Oval(타원도 포함한 원)
			mPaint.setColor(Color.GREEN);
			canvas.drawOval(new RectF(20, 250, 20 + 100, 250 + 50), mPaint);

			// draw RoundRect
			mPaint.setColor(Color.RED);
			canvas.drawRoundRect(new RectF(150, 250, 150 + 100, 250 + 50), 10,
					10, mPaint);//라운드의 정도(10),(10) 포토샵Father효과임

			// draw Path
			mPaint.setColor(Color.YELLOW);
			// 테두리만 그린다.
			mPaint.setStyle(Paint.Style.STROKE);
			mPaint.setStrokeWidth(2);

			Path mPath = new Path();
			mPath.moveTo(0, 0);
			mPath.lineTo(30, 60);
			mPath.lineTo(-30, 60);
			mPath.close();

			//전체 Path 가 위치할 x,y 좌표
			mPath.offset(150, 360);
			canvas.drawPath(mPath, mPaint);
		}
	}
}



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
	<EditText  
	    android:id="@+id/edit"
	    android:layout_width="fill_parent" 
	    android:layout_height="wrap_content" 
	    />
	<Button  
	    android:id="@+id/write"
	    android:layout_width="fill_parent" 
	    android:layout_height="wrap_content" 
	    android:text="프리퍼런스 쓰기"
	    />
	<Button  
	    android:id="@+id/read"
	    android:layout_width="fill_parent" 
	    android:layout_height="wrap_content" 
	    android:text="프리퍼런스 읽기"
	    />
	<TextView  
	    android:id="@+id/view"
	    android:layout_width="fill_parent" 
	    android:layout_height="wrap_content"
	    />
</LinearLayout>


package net.npaka.preferencesex;

import android.app.Activity;
import android.os.Bundle;
import android.content.SharedPreferences;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class PreferencesEx extends Activity implements View.OnClickListener{
	private EditText editText;//텍스트 박스
	private Button btnWrite;//읽기 버튼
	private Button btnRead;//쓰기 버튼
	private TextView view;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		editText = (EditText)findViewById(R.id.edit);
		btnWrite = (Button)findViewById(R.id.write);
		btnRead= (Button)findViewById(R.id.read);
		view= (TextView)findViewById(R.id.view);

		btnWrite.setOnClickListener(this);
		btnRead.setOnClickListener(this);
	}

	public void onClick(View v) {
		if(v==btnWrite){
			//SharedPreferences 객체 구하기(1)
			SharedPreferences pref = getSharedPreferences("PreferencesEx",MODE_PRIVATE);

			//프리퍼런스의 쓰기(2)
			SharedPreferences.Editor editor =pref.edit();
			editor.putString("text", editText.getText().toString());
			//반드시 commit()메소드를 호출해야 저장됨
			editor.commit();
			editText.setText("");
		}else if(v==btnRead){
			//SharedPreferences 객체 구하기(1)
			SharedPreferences pref = getSharedPreferences("PreferencesEx",MODE_PRIVATE);

			//프리퍼런스로부터 읽기(3)
			view.setText(pref.getString("text",""));
		}
	}
}





res > 에 xml 폴더 생성후 -> preferences.xml을 생성




main.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <TableRow>
        <TextView
            android:paddingRight="5px"
            android:text="체크박스:" />

        <TextView android:id="@+id/checkbox" />
    </TableRow>

    <TableRow>
        <TextView
            android:paddingRight="5px"
            android:text="벨소리:" />

        <TextView android:id="@+id/ringtone" />
    </TableRow>

    <TableRow>
        <TextView
            android:paddingRight="5px"
            android:text="체크박스 #2:" />

        <TextView android:id="@+id/checkbox2" />
    </TableRow>

</TableLayout>
preferences.xml
<PreferenceScreen
	xmlns:android="http://schemas.android.com/apk/res/android">
	<PreferenceCategory android:title="Simple Preferences">
		<CheckBoxPreference
			android:key="@string/checkbox"
			android:title="체크박스 환경설정"
			android:summary="체크 상태를 변경합니다"
		/>
		<RingtonePreference
			android:key="@string/ringtone"
			android:title="벨소리 환경설정"
			android:showDefault="true"
			android:showSilent="true"
			android:summary="벨소리를 선택합니다"
		/>
	</PreferenceCategory>
	<PreferenceCategory android:title="상세 화면">
		<PreferenceScreen
			android:key="detail"
			android:title="상세 화면"
			android:summary="별도 페이지에 상세 설정이 있습니다">
			<CheckBoxPreference
				android:key="@string/checkbox2"
				android:title="상세 체크박스"
				android:summary="체크 상태를 변경합니다"
			/>
		</PreferenceScreen>
	</PreferenceCategory>
</PreferenceScreen>


main javafile
package com.commonsware.android.prefs;

import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class StructuredPrefsDemo extends Activity {
	private static final int EDIT_ID =1; 
	private static final int CLOSE_ID =2;

	private TextView checkbox = null;
	private TextView ringtone = null;
	private TextView checkbox2 = null;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		checkbox = (TextView)findViewById(R.id.checkbox);
		ringtone = (TextView)findViewById(R.id.ringtone);
		checkbox2 = (TextView)findViewById(R.id.checkbox2);
	}
	@Override
	public void onResume(){
		super.onResume();
		
		//환경설정시 생성된 default 환경설정 파일을 읽어들여 SharedPreference 객체 생성
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);

		//환경설정 파일에서 저장된 정보의 타입별로 메소드를 호출해 정보를 추출함
		//getBoolean(key,기본값)
		//				  기본값 : key를 통해서  value를 호출하게 되는데
		//					         설정된 값이 없을때 보여지는 값
		checkbox.setText(new Boolean(prefs.getBoolean("checkbox",false)).toString());
		ringtone.setText(prefs.getString("ringtone","<unset>"));
		checkbox2.setText(new Boolean(prefs.getBoolean("checkbox2",false)).toString());
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu){
		menu.add(Menu.NONE, EDIT_ID, Menu.NONE, "환경 설정")
		.setIcon(R.drawable.misc);
		menu.add(Menu.NONE, CLOSE_ID, Menu.NONE, "닫기")
		.setIcon(R.drawable.eject);

		return(super.onCreateOptionsMenu(menu));
	}
	@Override
	public boolean onOptionsItemSelected(MenuItem item){
		switch(item.getItemId()){
		case EDIT_ID:
			startActivity(new Intent(this,EditPreferences.class));
			return true;
		case CLOSE_ID:
			finish();
			return true;
		}
		return(super.onOptionsItemSelected(item));
	}
}
sub javafile
package com.commonsware.android.prefs;

import android.preference.PreferenceActivity;
import android.os.Bundle;

public class EditPreferences extends PreferenceActivity{
	@Override
	public void onCreate(Bundle savedIstanceState){
		super.onCreate(savedIstanceState);
		
		addPreferencesFromResource(R.xml.preferences);
	}
}

메인에는 환경설정값을 가져옵니다 (없을시에는 기본값 지정)

환경설정 진입화면



상세화면 진입화면



인터넷 권한 설정



main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#FFFFFF"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/mainTitle"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#CCCCCC"
        android:paddingBottom="5px"
        android:paddingTop="5px"
        android:textColor="#000000"
        android:textSize="13sp" />

    <TextView
        android:id="@+id/mainDescription"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#CCCCCC"
        android:paddingBottom="5px"
        android:textColor="#000000"
        android:textSize="12sp" />

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:cacheColorHint="#FFFFFF"/>

</LinearLayout>


news_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	>    
	<WebView
	    android:id="@+id/web"
	    android:layout_width="fill_parent"
	    android:layout_height="fill_parent"
	    /> 
</LinearLayout>


news_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent" 
	android:layout_height="50px"
	android:padding="5px"> 
	<TextView 
	    android:layout_width="wrap_content"
		android:layout_height="wrap_content" 
		android:id="@+id/text"
		android:textColor="#000000" 
		android:textSize="15sp"
	    /> 
</LinearLayout>


main javafile
  
 package kr.android.news;

import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class NewsRssDemo extends ListActivity {
	ArrayList<MyNews> myRss = new ArrayList<MyNews>();
	MyNews myRssProv = new MyNews();
	TextView mainTitle, mainDescription;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		parseXml();
		setListAdapter(new MyListAdapter(this, R.layout.news_list));

		mainTitle = (TextView)findViewById(R.id.mainTitle);
		mainDescription = (TextView)findViewById(R.id.mainDescription);

		mainTitle.setText(myRssProv.title);
		mainDescription.setText(myRssProv.description);
	}
	private void parseXml(){
		InputStream in = null;

		try{
			URL url = new URL("http://www.hani.co.kr/rss/");
			in = url.openStream();

			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

			//태크 사이의 공백무(JDK6.0이상부터 오류)
			factory.setIgnoringElementContentWhitespace(true);
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document doc = builder.parse(in);

			//신문사 정보 추출/저장
			Node provider = doc.getElementsByTagName("channel").item(0);

			NodeList prov = provider.getChildNodes();
			for(int j=0; j<prov.getLength();j++){
				Node n = prov.item(j);
				if(n.getNodeName().equals("title")){
					myRssProv.title =n.getFirstChild().getNodeValue();
				}
				if(n.getNodeName().equals("link")){
					myRssProv.link = n.getFirstChild().getNodeValue();
				}
				if(n.getNodeName().equals("description")){
					myRssProv.description = n.getFirstChild().getNodeValue();
					break;
				}
			}
			//기사 추출 & 저장
			NodeList articles = doc.getElementsByTagName("item");

			for(int i=0; i<articles.getLength(); i++){
				MyNews myNews = new MyNews();
				NodeList article = articles.item(i).getChildNodes();
				for(int j=0;j<article.getLength();j++){
					Node n = article.item(j);
					if(n.getNodeName().equals("title")){
						myNews.title = n.getFirstChild().getNodeValue();
					}
					if(n.getNodeName().equals("link")){
						myNews.link = n.getFirstChild().getNodeValue();
					}
					if(n.getNodeName().equals("description")){
						myNews.description = n.getFirstChild().getNodeValue();
					}
				}
				myRss.add(myNews);
			}
		}catch (Exception e){
			e.printStackTrace();
			Toast.makeText(this, "주소 읽기 실패"+e.getMessage(),
					Toast.LENGTH_SHORT).show();
		}finally{
			try{
				if(in != null) in.close();
			}catch(Exception e){

			}
		}
	}
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id){
		super.onListItemClick(l, v, position, id);
		Intent intent = new Intent(this, NewsRssDetail.class);
		
		intent.putExtra("title", myRss.get(position).title);
		intent.putExtra("link", myRss.get(position).link);
		intent.putExtra("description", myRss.get(position).description);
		
		startActivity(intent);
	}
	//어댑터 클래스
	class MyListAdapter extends BaseAdapter {
		Context context;
		LayoutInflater inflater;
		int layout;
		
		public MyListAdapter(Context context,int layout){
			this.context = context;
			this.layout = layout;
			
			//ListView에서 사용한 View를 정의한 xml를 읽어오기 위해
			//LayoutInflater 객체를 생성
			inflater = LayoutInflater.from(context);
		}
		public int getCount() {
			return myRss.size();
		}
		public Object getItem(int position) {
			return myRss.get(position).title;
		}
		public long getItemId(int position) {
			return position;
		}
		public View getView(int position, View convertView, ViewGroup parent) {
			if(convertView == null){
				convertView = inflater.inflate(layout,parent,false);
			}
			TextView txt = (TextView)convertView.findViewById(R.id.text);
			txt.setText(myRss.get(position).title);
			
			return convertView;
		}
	}

	class MyNews{
		String title;
		String link;
		String description;
	}
}


sub javafile
package kr.android.news.rss;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebSettings;

public class NewsRssdetail extends Activity  {
    
    String title ,link,description;
    WebView web;
    
    protected void onCreate(Bundle save){
        super.onCreate(save);
        setContentView(R.layout.news_detail);
        
        Intent intent = getIntent();
        
        title = intent.getExtras().getString("title");
        link = intent.getExtras().getString("link");
        description = intent.getExtras().getString("description");
        
        
        StringBuffer text =new StringBuffer();
        text.append("<html><body><font size=\"4\">");
        text.append(title);
        text.append("</font><hr size=\"2\" width=\"100%\" noshade>");
        text.append("<font size=\"2\">");
        text.append(description);
        text.append("</font><br/>");
        text.append("<div align=\"center\"><input type=\"button\" value=\"기사 전문 보기\" onclick=\"location.href='");
        text.append(link);
        text.append("'\"></div>");
        text.append("</body></html>");
        
        web= (WebView)findViewById(R.id.web);
        WebSettings set = web.getSettings();
        set.setJavaScriptEnabled(true);
        set.setBuiltInZoomControls(true);
        web.loadDataWithBaseURL(null, text.toString(), "text/html", "UTF-8", null);
    }
}



maifest.xml에서 권한설정을 해줍니다

(uses permission)



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <WebView
            android:id="@+id/web"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

        <ProgressBar
            android:id="@+id/web_progress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:visibility="gone" />
    </FrameLayout>

</LinearLayout>


package kr.android.web.progressbar;

import android.app.Activity;
import android.os.Bundle;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.Toast;

public class ProgressBarDemo1 extends Activity {
	private WebView web;
	private ProgressBar progress;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		ConnectivityManager cm = 
				(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

		NetworkInfo ni = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		boolean isWifiConn = ni.isConnected();

		ni = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

		boolean isMobileConn = ni.isConnected();

		if (!isWifiConn && !isMobileConn) {
			Toast.makeText(this, "인터넷에 접속되어 있지 않습니다!", Toast.LENGTH_SHORT)
			.show();
			finish();//액티비티 종료
		} else {
			setContentView(R.layout.main);

			progress = (ProgressBar) findViewById(R.id.web_progress);

			web = (WebView) findViewById(R.id.web);
			web.getSettings().setJavaScriptEnabled(true);
			web.getSettings().setBuiltInZoomControls(true);
			web.setHorizontalScrollbarOverlay(true);
			web.setVerticalScrollbarOverlay(true);

			web.loadUrl("http://raysoda.com");

			web.setWebViewClient(new WebViewClient() {
				// 링크 클릭에 대한 반응
				@Override
				public boolean shouldOverrideUrlLoading(WebView view, String url) {
					view.loadUrl(url);
					return true;
				}

				// 웹페이지 호출시 오류 발생에 대한 처리
				@Override
				public void onReceivedError(WebView view, int errorcode,
						String description, String fallingUrl) {
					Toast.makeText(ProgressBarDemo1.this,
							"오류 : " + description, Toast.LENGTH_SHORT).show();
				}
				// 페이지 로딩 시작시 호출
				@Override
				public void onPageStarted(WebView view,String url , Bitmap favicon){
					progress.setVisibility(View.VISIBLE);
				}
				//페이지 로딩 종료시 호출
				public void onPageFinished(WebView view,String Url){
					progress.setVisibility(View.GONE);
				}
			});
		}
	}
	public boolean onKeyDown(int keyCode, KeyEvent event){
		if(keyCode ==KeyEvent.KEYCODE_BACK && web.canGoBack()){
			web.goBack();
		}else if(keyCode ==KeyEvent.KEYCODE_BACK && !web.canGoBack()){
			Toast.makeText(this, "프로그램 종료!!", Toast.LENGTH_SHORT).show();
			finish();
		}
		return true;
	}
}
실행화면


무언가를 읽어들이는 것에는 무조건 Progress가 뜹니다






두번째 타이틀에 로딩바심기(ProgressBar)


인터넷 권한 설정 해주기




<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <WebView
        android:id="@+id/web"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</LinearLayout>


package kr.android.web.progressbar2;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Window;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

public class ProgressBarDemo2 extends Activity {
	private WebView web;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 타이틀바에 막대모양 프로세스 setContentView();
		// 호출 전에 호출 해야함
		getWindow().requestFeature(Window.FEATURE_PROGRESS);

		setContentView(R.layout.main);

		web = (WebView) findViewById(R.id.web);
		web.getSettings().setJavaScriptEnabled(true);
		web.getSettings().setBuiltInZoomControls(true);

		web.loadUrl("http://m.naver.com");

		final Activity activity = this;
		web.setWebChromeClient(new WebChromeClient() {
			public void onProgressChanged(WebView view, int progress) {
				// progress 구간 0~10000
				activity.setProgress(progress * 100);
				Log.i("progressBarDemo2", "Progress :" + progress);
			}
		});
		web.setWebViewClient(new WebViewClient() {
			@Override
			public void onReceivedError(WebView view, int errorCode,
					String description, String fallingUrl) {
				Toast.makeText(activity, "오류 : " + description,
						Toast.LENGTH_SHORT).show();
			}

			@Override
			public boolean shouldOverrideUrlLoading(WebView view, String url) {
				view.loadUrl(url);
				return true;
			}
		});
	}
	public boolean onKeyDown(int keyCode, KeyEvent event){
		if(keyCode ==KeyEvent.KEYCODE_BACK && web.canGoBack()){
			web.goBack();
		}else if(keyCode ==KeyEvent.KEYCODE_BACK && !web.canGoBack()){
			Toast.makeText(this, "프로그램 종료!!", Toast.LENGTH_SHORT).show();
			finish();
		}
		return true;
	}
}



private boolean isRunningService(){
		ActivityManager manager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
		List<ActivityManager.RunningServiceInfo> rsi = 
				manager.getRunningServices(100);
		for(int i=0; i<rsi.size();i++){
			ActivityManager.RunningServiceInfo rsInfo = rsi.get(i);
			if(rsInfo.service.getClassName().equals(
					"kr.android.news.service.NewsService")){
				Log.i("NewsDemo","~~~~~~실행중"+rsInfo.service.getClassName());
				return true;
			}
		}
		return false;
	}


'Android > 기본' 카테고리의 다른 글

RSS 가져오기(뉴스)  (0) 2012.04.28
Progressbar로 로딩표현 (인터넷로딩)  (1) 2012.04.28
안드로이드 프로세스 말끔히 죽이기  (0) 2012.04.28
Xml 가져오기 (날씨)  (0) 2012.04.28
SQLite 연동하기  (1) 2012.04.28

Android How to Kill Application Process 
관련글: 안드로이드 어플리케이션 종료하기 (이글을 참조하시기 바랍니다.)

<개발자의 부주의로 어플리케이션이 정리되지 않는 설겆이 거리를 만들어 낼 수 있습니다..>

  안드로이드 상에서 어플리케이션 개발을 진행하다 보면, 어플리케이션 Process 자체를 종료 시키고 싶은 경우가 있습니다. 특히 제 경우에는 여러가지 핸들러나 스레드를 사용하는 경우 Process 를 종료시키고 싶을 때가 많더군요. Activity 를 모두 종료하더라도, Process 가 살아 있으면 메인 UI 스레드에 연결되어 있는 Handler 와 Message 는 쌩쌩히 동작합니다. 더군다나 시간이 오래 걸리는 작업을 수행하기 위해 Thread 를 여럿 생성해 둔 상태에서 해당 Thread 들의 라이프 사이클을 잘 관리하지 않으면 Activity 가 종료 되더라도, 죽지 않고 계속 살아 남기 때문에, 원인을 알 수 없는 오류로 어플리케이션을 죽여 먹곤 했습니다. 

  그야말로 고생해서 밥 잘 해먹은 다음에, 설겆이 하면서 그릇을 다 깨먹는 형국입니다. 성능상에 약간의 손실을 감수하더라도, 기름때가 잔뜩 묻은 접시마냥 흉칙하게 남아있는 깔끔하게 정리해 버리고자, 몇 가지 방법을 사용해봤습니다. 하지만,종료 버튼 관련 포스트에서 한번 언급했듯이, 그런 시도들이 썩 성공적이지는 않았습니다.

 
<드라큘라에게도 약점이 있듯이, 안드로이드 Process 도 죽이는 방법이 있습니다.>

  궁하면 통하는 법인가요? 얼마전에 훌륭하게 Process 를 종료시킬 수 있는 방법을 구글링을 통해 발견해서 이야기해 봅니다. 특정 어플리케이션의 Process 를 확실히 죽이는 방법은 다음과 같습니다.
1.메니페스트 파일에 RESTART_PACKAGES 권한을 사용한다고 선언한다.
<uses-permission android:name="android.permission.RESTART_PACKAGES"/>

2.ActivityManager 의 restartPackage API 를 호출한다.
ActivityManager am 
             = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
am.restartPackage(getPackageName());
 이전에는 System.exit() 나 Process.killProcess() 를 이용해서 Process 를 종료하려고 했습니다. 두 가지 방법 모두, Process 를 정상적으로 종료 시키는 듯 보일 때도 있었지만, 대게의 경우 어플리케이션 Process 가 죽었나... 하는 순간에 벌떡 하고 무덤에서 살아 돌아와 저를 우울하게 만들고 했습니다.

 어떠한 차이때문에 이런 일이 벌어지는 걸 까요? 안드로이드 Process의 생명 주기에 대해 다시 한번 확인해 봤습니다.  안드로이드 Application Fundamentals 에 명시되어 있는 내용은 다음과 같습니다. 

Android may decide to shut down a process at some point, when memory is low and required by other processes that are more immediately serving the user. Application components running in the process are consequently destroyed. A process is restarted for those components when there's again work for them to do.

 System.exit() 이나 Process.killProcess() 를 호출 하면, Process 가 강제로 종료되고, 안드로이드 플랫폼 입장에서는, 예기치않은 이유로 해당 Process 가 종료되었다고 판단하는 것으로 보입니다. 이 때, 해당 Process 가 해야할 일이 남아 있은 경우, 안드로이드 플랫폼 입장에서 이미 무덤에 돌아간 Process 를 다시 불러 일으키게 됩니다. 제가 알고있는 경우는 두 가지 입니다.
  •  START_NOT_STICKY 모드가 아닌 Service 가 작동 중인 경우.
  •  Activity Task 상에 현재 화면에 보이는 Activity 바로 아래 위치한 Activity 가 종료하고자 하는 Process 의 구성 요소 일 때. (Task 는 Process 가 아니라 안드로이드 시스템에서 관리하고 있음으로, 갑자기 종료된 Activity 바로 아래에 위치한 Activity 를 시스템에서 다시 시작하려고 함으로...) 
 그럼, restartPackage() 의 경우에는 어째서 Process 가 다시 살아나지 않는 것일까요? 그 답은 API 문서에 잘 나와 있습니다. 

public void restartPackage (String packageName)

Since: API Level 3

Have the system perform a force stop of everything associated with the given application package. All processes that share its uid will be killed, all services it has running stopped, all activities removed, etc. In addition, a ACTION_PACKAGE_RESTARTED broadcast will be sent, so that any of its registered alarms can be stopped, notifications removed, etc.


 API 설명에 잘 나와 있듯이, restartPackage() 의 경우, 단지 Process 를 종료하는 것이 아니라, 안드로이드 플랫폼에게 특정 어플리케이션 패키지가 종료됨을 알리고, 따라서 이미 실행중인 Service 나 Activity 를 안드로이드 시스템상에서 모두 제거하게 됩니다. 

<편히 잠들기를...>


 안드로이드 플랫폼은 우리가 알게 모르게 많은 일들을 수행하고 있습니다. 그렇기 때문에, 안드로이드 플랫폼에게 Process 가 죽었다는 사실을 알려준 후에야, 묻어놓은 개발자들은 시체가 무덤에서 다시 돌아오지 않을 것임을 확신하고 마음 편히 잠들 수 있습니다...



출처:http://blog.naver.com/PostView.nhn?blogId=huewu&logNo=110082677696

+ Recent posts