※keystore 생성 / apk파일 생성 및 서명하기


- 마켓에 업로드 할 어플리케이션의 메니페스트 파일을 연 후, Manifest 탭의 하단을 보면 아래와 같이 Export 메뉴가 보입니다.



 두 가지 방법이 있는데, 하나는 APK파일 생성과 서명을 동시에 하는 것, 하나는 APK파일로만 생성하는 것입니다. 특별한 경우가 아니라면 동시에 해주는거 편하겠죠? Use the Export Wizard를 클릭합니다.




 Export  Android Application 창이 뜹니다. 여기에서는 apk파일로 내보내기를 수행할 프로젝트를 선택해주면 됩니다. Next를 눌러 다음 과정으로 넘어갑니다.





 어플리케이션 배포를 처음으로 하는 것이라면, 아직 keystore가 없을 겁니다. keystore가 있어야만 어플리케이션 서명도 할 수 있고, 구글맵 API Key도 받을 수 있습니다. (에뮬레이터에서 테스트할 때는 debug keystore로 API키를 받아서 구글맵을 사용할 수 있었지만, 실제 기기에 올릴 때는 debug keystore로 받은 API Key를 사용하면 로드가 제데로 되지 않습니다.)


Location 옆의 Browse...를 눌러 새로 만들 keystore가 저장될 위치를 선택합니다.






keystore의 경로 및 이름을 지정합니다.





keystore의 위치 및 이름을 지정했으면, keystore의 비밀번호를 입력한 후, Next 버튼을 눌러줍니다.





 Alias(이름) 및 비밀번호와 기본적인 정보들을 적어주면 되고, Validity(서명이 유효한 기간)은 50년으로 해줍니다. (안드로이드 마켓에 어플리케이션을 올리려면 적어도 안드로이드 마켓이 생긴 일자로부터 50년까지는 유효한 인증서로 서명이 되어야 합니다) 입력이 완료되었으면 Next버튼을 눌러 다음 과정으로 넘어갑니다.





어디에 apk파일을 생성할 지 모두 선택이 완료되었으면, Finish버튼을 눌러 apk파일을 생성합니다.





출처:http://www.androidpub.com/56913

'Android > 2012.04월 강좌' 카테고리의 다른 글

Toast 에 이미지 띄우기  (0) 2012.05.17
13일차 Font  (0) 2012.05.14
12일차 SocketServer 2 (Client,Server C->C)  (0) 2012.05.11
11일차 SocketServer (Client,Server C->S, S->C)  (0) 2012.05.10
11일차 Json  (0) 2012.05.10
package com.gusfree.toast;

import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class ToastActivity extends Activity{
	@Override
	protected void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		Button btn=new Button(this);
		btn.setText("버튼");
		setContentView(btn);

		btn.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View arg0) {
				Toast toast=
						Toast.makeText(getApplicationContext(), "ㅎㅎ", 0);

				ImageView imageView=new ImageView(getApplicationContext());
				imageView.setImageResource(R.drawable.ic_launcher);				

				/* 토스트에 뷰 셋팅하기 xml 통째로 넣어도 됨 */
				toast.setView(imageView);
				//위치 지정
				toast.setGravity(Gravity.CENTER,50,50);
				//여백 지정
				toast.setMargin(1000, 1000);
				toast.show();
			}
		});
	}
}



'Android > 2012.04월 강좌' 카테고리의 다른 글

안드로이드 어플 등록 과정  (0) 2012.05.18
13일차 Font  (0) 2012.05.14
12일차 SocketServer 2 (Client,Server C->C)  (0) 2012.05.11
11일차 SocketServer (Client,Server C->S, S->C)  (0) 2012.05.10
11일차 Json  (0) 2012.05.10
<?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" >

    <ToggleButton
        android:id="@+id/toggleButton01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/btn_default"
        android:textOff="Off Stage"
        android:textOn="On Stage" />

</LinearLayout>
package com.button;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ToggleButton;

public class ButtonActivity extends Activity {

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

		final ToggleButton tb = 
				(ToggleButton)this.findViewById(R.id.toggleButton01);

		tb.setOnClickListener(new View.OnClickListener() { 
			public void onClick(View v) { 
				if (tb.isChecked()) { 
					tb.setBackgroundDrawable(getResources().
							getDrawable(R.drawable.btn_press)); 
				} else { 
					tb.setBackgroundDrawable(getResources().
							getDrawable(R.drawable.btn_select)); 
				}
			} 
		});
	}
}




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

버튼클릭 제스쳐, 상태에 따른 버튼이미지 변경, xml 파일로 만들기  (0) 2012.05.15
Eclipse Phone test  (0) 2012.05.14
Android 9 patch  (0) 2012.05.14
예비  (0) 2012.04.28
Android 메인로딩 페이지 만들기  (0) 2012.04.28

버튼에 대한 상태를 생각해봅시다.
여러가지의 상태가 있는데 그 여러 상태에 대해서 버튼에 다른이미지를 보여줄 수 있습니다.

버튼의 상태
 default   아무것도 아닌 상태 
 pressed     누르고 있는 상태 
 focused   누르고 있진 않았지만 포커스가 주어진 상태 
 selected   선택된 상태  

이렇게 네가지의 상태가 있습니다.
이 네가지 상태에 대해서 각각 다른 이미지를 보여주기 위해서는 네가지의 이미지가 있어야 합니다.

저는 보통 3가지의 이미지를 두고, 
default, pressed, focused 또는 
default, pressed, selected 에 사용합니다.



이미지 파일을 준비합니다.
이미지들은 res 소스에 넣어 줍시다.

res/drawable/button_change.xml
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" 
        android:drawable="@drawable/btn_press" /> <!-- pressed -->
    
    <item android:state_selected="true" 
        android:drawable="@drawable/btn_select" /> <!-- selected -->
    
    <item android:drawable="@drawable/btn_default" /> <!-- default -->
</selector>

main.xml
<ImageButton
    android:id="@+id/main_btn_change"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/button_change"
/>


ButtonActivity.java
package com.button;
 
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
 
public class ButtonActivity extends Activity implements OnClickListener 
{
    ImageButton btn_change;
     
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
         
        btn_change = (ImageButton)findViewById(R.id.main_btn_change);
        btn_change.setOnClickListener(this);
    }
 
    @Override
    public void onClick(View v)
    {
        switch(v.getId())
        {
        case R.id.main_btn_change :
            btn_change.setSelected(true);
            break;
        }
    }
}


출처:http://croute.me/288

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

ToggleButton이 ON/OFF 될 때 버튼의 이미지를 변경하는 예제  (0) 2012.05.15
Eclipse Phone test  (0) 2012.05.14
Android 9 patch  (0) 2012.05.14
예비  (0) 2012.04.28
Android 메인로딩 페이지 만들기  (0) 2012.04.28

만들어진 앱은 AVD가 아닌 실제 휴대폰에서 잘 동작해야 합니다. 이번 포스트에서는 이클립스로 만든 앱을 실제 기기에 설치하고 실행하는 방법에 대해 안내 드립니다.

 

 

휴대폰 설정 

휴대폰으로 앱을 설치하기 위해서는 먼저 설정해야 하는 것이 있습니다. 아래와 같이 실행해 주세요. 

 

1. 안드로이드의 홈 스크린(바탕화면)에서 메뉴 버튼을 누르면, '설정'이라는 항목이 있습니다. 그것을 선택하세요.

 

2. 설정 메뉴에서 애플리케이션을 선택하세요.

 

3. 애플리케이션 설정에서 '개발'을 선택하세요.

 

4. 개발 메뉴에서 'USB 디버깅'을 체크하세요. USB 디버깅을 사용할지를 묻는 팝업이 뜹니다. '확인' 버튼을 클릭해 주세요.

 

 

휴대폰으로 앱을 실행하기 위한 과정

우리가 이클립스를 처음 사용했을 때에는 AVD가 작동할 수 있도록 AVD 매니저를 활용했었습니다. 그것이 아닌 실제 기기에 앱이 작동되려면, 우리는 별도의 설정을 추가로 해줘야 합니다.

 

1. 메뉴 Run - Run Configurations...를 선택하세요. 아래 그림을 참고하시기 바랍니다.




2. Run Configurations 창이 뜹니다. 여기에는 아래 그림과 같이 Android, Target, Common 탭들이 보입니다. 그 중 Target을 선택하세요. Deployment Target Selection Mode가 보일 것입니다. 그것을 Manual로 변경해 주세요. 이것은 이클립스가 앱을 실행시킬 때 AVD와 실제 기기(들) 중 어떤 것을 선택할지를 물어보겠다는 의미입니다. 변경 후 Apply 버튼을 클릭하시고, Run 버튼을 클릭하세요.



3. 여러분께서 가지고 있는 안드로이드 휴대폰을 PC에 연결하세요.



4. 이제 앱을 실행하는 메뉴 Run As - Android Application을 선택하세요. 그러면 이클립스는 아래 그림과 같이 Android Device Chooser 창을 띄웁니다. 여기에서 우리는 AVD와 실제 기기 중 하나를 선택할 수 있습니다. AVD의 시리얼 번호는 'emulator'로 시작합니다. 실제 기기에 앱을 실행하려면 다른 번호(아래 그림에서는 1234567890ABCDEF)를 선택해야겠지요? 실제 기기의 시리얼 번호를 선택하신 후 OK 버튼을 클릭하세요.



참고로 위 그림에서 실제 기기의 현재 OS 버전은 2.2.2입니다. 버전 왼쪽에 빨간 X표가 그려져 있네요. 그 이유는 제가 만든 프로젝트의 타겟 버전을 2.2.2보다 상위 버전(4.0을 선택했습니다. 아이스크림 샌드위치죠.)으로 선택했기 때문입니다. 빨간 X표는 앱이 실행될 타겟이 하위 버전이므로 그것이 실행되지 못할 수 있음을 의미합니다. 그러나 저는 이 프로젝트의 Min SDK version을 8로 지정했습니다. 이것은 바로 프로요의 API 레벨이죠. 따라서 이 프로젝트로부터 생성된 앱은 프로요 기기에서도 실행 가능합니다.
 
5. 잠시만 기다려 주시면 여러분의 폰에서 앱이 실행됩니다. 확인해 보세요.




요번 포스트는 안드로이드를 

좀 더 아이폰 스타일의 텍스트뷰(에디터뷰)를 만들어보겠습니다.

위에서는 아이폰의 "X" 버튼을 만들어보았는데, 

나인패치를 이용하여 전 포스트를 아이폰과 비슷한 아래의 모양 처럼 만들어보겠습니다. 



나인패치란 쉽게 말해서 기존의 이미지 PNG 파일에 1px의 테두리를 두고, 

늘어나는 곳와 내용이 출력되도록 하는 것입니다. 

즉, 뷰의 크기에 따라 이미지의 크기가 자동으로 조절 되는 것을 말합니다.. 

파일 이름은 반드시 *.9.png 로 해야. 나인패치를 적용할 수 있습니다. 

나인패치를 하기 위해

두개의 이미지를 준비를 했습니다. 



ic_btn_serach_selected.png
  
 

ic_btn_serach_selected.png
  
 



나인패치프로그램은 안드로이드sdk 설치된 곳에 

tools폴더에 보면 draw9patch.bat를 실행 시키면 검은 cmd창이 뜨는데, 종료를 하시면 프로그램이 꺼져버리니 그냥둡니다. 


cmd창이 자동으로 종료가 될 경우 아래의 파일을 안드로이드sdk폴더 안에 tools 폴더에 있는 lib 폴더에 넣어줍니다. 

tools/lib


이제 위에서 받은 이미지를 드래그해서 창위에 올려 놓아 이미지를 불러옵니다. 



이미지를 불러오면 위에와 같이 원본 파일 테두리에 1px의 여백이 나타나는데, 이곳에 표시를 하여, 

늘어나는 곳을 정해주면됩니다. 

왼쪽과 상단은 stretchable area를, 오른쪽과 하단은 padding box의 위치를 정해줍니다. 






다음과 같이 검은색으로 표시된 곳이 나인패치를 정해준 곳입니다. 

상하의 모양을 유지하기 위해서 왼쪽 여백은 다 칠했고, 

좌우는 view의 모양에 따라 크기가 자동으로 변하게 하기 위하여 늘어나는 공간을 표시했습니다. 

하단과 우측의 경우 view의 크기에 따른 글씨의 크기 텍스트가 표시될 위치(?)를 나타냅니다. 

이렇게 ic_btn_serach_selected.png와 ic_btn_serach_unselected.png 파일을 동일하게 편집하고 9.png파일로 저장을 합니다. 

저장한 파일을 drawable 폴더에 넣고, xml파일을 수정하면 됩니다. 


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

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="horizontal"
        android:paddingTop="0px" >

        <EditText
            android:id="@+id/address"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/ic_btn_serach_unselected"
            android:hint="Search"
            android:inputType="textUri"
            android:maxLength="14"
            android:singleLine="true" />

        <ImageButton
            android:id="@+id/clear_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dip"
            android:layout_marginTop="10dip"
            android:background="@drawable/ic_btn_serach_selected"
            android:visibility="invisible" />
    </RelativeLayout>

</LinearLayout>



NinePatchActivity.java
package com.gusfree.nine;

import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.EditText;
import android.widget.ImageButton;

public class NinePatchActivity extends Activity {

	EditText et;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		et=(EditText) findViewById(R.id.address);
		
		
		et.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				
				if(event.getAction()== MotionEvent.ACTION_DOWN){
				et.setBackgroundDrawable(getResources().
						getDrawable(R.drawable.ic_btn_serach_selected));

			}
			else if(event.getAction() == MotionEvent.ACTION_UP){
				et.setBackgroundDrawable(getResources().
						getDrawable(R.drawable.ic_btn_serach_unselected));

			}
			return false;
			}

		});
	}
}


폰트 하나를 assets/fonts에 복사한다.

(윈도우 제어판에 가면 쉽게 폰트를 사용할 수있다.단 용량이 큰것은 오래걸리니 되도록 용량이 작은 폰트를 사용하자)



             나인패치 ...다운 받아서 res 소스 3개중에 한곳에 복사해주자~~

              


<?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:id="@+id/layout"
    android:background="@drawable/bg_dialog">

    <TextView
        android:background="@drawable/ic_btn_background"
        android:id="@+id/textView1"
        android:textSize="40px"
        android:typeface="serif"
        android:textStyle="bold"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <Button
        android:background="@drawable/ic_btn_background"
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

</LinearLayout>


package com.gusfree.font;

import android.app.Activity;
import android.graphics.Typeface;
import android.os.Bundle;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class FontActivity extends Activity {

	TextView tv;
	LinearLayout lt;
	Button btn;
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        tv=(TextView)findViewById(R.id.textView1);
        
        //글꼴을 불러오자.
        Typeface font1 = Typeface.createFromAsset(getAssets(), "fonts/H2GTRE.TTF");
        
        //뷰에 글꼴을 적용하자.
        tv.setTypeface(font1);
        
        //SharedPreferance에 저장하길 권장
        
        lt=(LinearLayout) findViewById(R.id.layout);
        btn=(Button) findViewById(R.id.button1);
        
        //나인 패치 디자인을 사용하자 파일이름 9.jpg
	}
}






Java Project 
ChatServer.class
package chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
  
public class ChatServer {

	int PORT = 5000;
	ArrayList<ClientThread> clientList = new ArrayList<ClientThread>();
	String who;

	public ChatServer() { // default Constructor
		System.out.println("시작");
		try {
			// 1. 서버소켓을 생성한다. port
			ServerSocket server = new ServerSocket(PORT);
			System.out.println("서버생성 및 레디상태");

			while (true) {
				// 2. 서버소켓이 클라이언트가 접속할수 있도록 ready
				Socket socket = server.accept(); // accept에 block
				String who=socket.getInetAddress().getHostAddress();
				System.out.println("접속 IP :"+ who);
				ClientThread thread=new ClientThread(socket);

				thread.start();

			}
		} catch (IOException e) {
		}
	}

	// 클라이언트와 데이터를 주고 받는 기능을 담당
	class ClientThread extends Thread{
		Socket socket;
		BufferedReader br;  // 데이터 받을 때 사용
		PrintWriter pw;       //  데이터 보낼 때 사용

		public ClientThread (Socket socket){
			this.socket=socket;
			try {
				InputStream is=socket.getInputStream();
				InputStreamReader isr=
						new InputStreamReader(is);				
				br = new BufferedReader(isr);
				pw = new PrintWriter(socket.getOutputStream());

				// Line 단위로 보냈으니 Line단위로 읽자
				String firstMessage = br.readLine();
				who=socket.getInetAddress().getHostAddress();
				sendAll(who+" connected");

				//나는 내가 접속했습니다라는 메세지를 받지 않음
				clientList.add(this);  

				System.out.println(firstMessage);

			} catch (Exception e) {
			}
		}

		@Override
		public void run() {			
			super.run();
			try{
				String line="";
				while(  ( line=br.readLine()) !=null ) {
					System.out.println(line);
					if(line.equals("/exit")){
						clientList.remove(this);
						sendAll(who+" leaved ");
					}
					sendAll(line);
				}
			}catch(Exception e){				
			}
		}

		// 데이터 보내는 메서드
		public void send(String line){
			pw.println(line);
			pw.flush();
		}

		@Override
		public void destroy() {
			pw.println("/exit");
			pw.flush();
			pw.close();
			try{
				socket.close();
			}catch (Exception e) {
			}
		}
	}

	// 서버에 연결된 모든 클라이언트에게 메세지를 보내기
	public void sendAll(String line){

		// ArrayList안에 들은 모든 쓰레드에게
		for(ClientThread oneThread : clientList ){
			oneThread.send(line);
		}
	}

	public static void main(String[] args) {
		new ChatServer();
	}
}



'Android > 2012.04월 강좌' 카테고리의 다른 글

Toast 에 이미지 띄우기  (0) 2012.05.17
13일차 Font  (0) 2012.05.14
11일차 SocketServer (Client,Server C->S, S->C)  (0) 2012.05.10
11일차 Json  (0) 2012.05.10
11일차 NavarOpenAPI 이용한 Dom Parser  (0) 2012.05.10
이건 JAVA project 
 ChatServer.class
package chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class ChatServer {


	int PORT=5000;

	public ChatServer(){//default Construtor
		System.out.println("시작");
		try {

			//1.서버소켓을 생성한다. port
			ServerSocket server = new ServerSocket(PORT);
			System.out.println("서버생성 및 레디 상태");

			while(true){
				//2.서버소켓이 클라이언트가 접속할 수 있도록 ready
				Socket socket = server.accept();//accept에 block
				String who = socket.getInetAddress().getHostAddress();
				System.out.println("접속 IP: "+who);
				ClientThread thread= new ClientThread(socket);
				thread.start();
			}
		} catch (IOException e) {


			e.printStackTrace();
		}
	}
	  
	//클라이언트와 데이터를 주고 받는 기능을 담당
	class ClientThread extends Thread{
		Socket socket;
		BufferedReader br; //데이터 받을 때 사용
		PrintWriter pw;    //데이터 보낼 때 사용
		
		public ClientThread(Socket socket) {
			this.socket=socket;
			try {
				InputStream is = socket.getInputStream();
				InputStreamReader isr = new InputStreamReader(is);
				
				br = new BufferedReader(isr);
				pw = new PrintWriter(socket.getOutputStream());
				
				//Line 단위로 보냈으니 Line 단위로 읽자
				String firstMessage = br.readLine();
				System.out.println(firstMessage);
				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		 
		@Override
		public void run() {
			super.run();
			try {
				String line="";
				while( (line = br.readLine()) !=null){
					System.out.println(line);
					send(line);
				}
			} catch (Exception e) {
			}
		}
		//데이터 보내는 메서드
		public void send(String line){
			pw.println(line);
			pw.flush();
		}
	}
	public static void main(String[] args) {
		new ChatServer();
	}
}



여기부터는 AndroidProject 

manifast.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.gusfree.chatclient"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".ChatClientActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>
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" >

    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10" >

        <requestFocus />

    </EditText>

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

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

</LinearLayout>
ChatClientActivity.java
package com.gusfree.chatclient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.TextView;

public class ChatClientActivity extends Activity implements OnClickListener{

	TextView textView;
	EditText editText;
	private final int PORT=5000;
	private final String IP="ip를 적어주삼~";//cmd창에,ipconfig명령어 
	Socket socket;
	PrintWriter pw;    //데이터를 보낼 때 사용할 객체
	BufferedReader br; //데이터를 받을 때 사용할 객체

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

		textView=(TextView) findViewById(R.id.textView1);
		editText=(EditText) findViewById(R.id.editText1);
		findViewById(R.id.button1).setOnClickListener(this);

		//서버와 Socket으로 연결하기
		try { 
			socket = new Socket(IP,PORT);//서버연결
			OutputStream os = socket.getOutputStream();
			pw = new PrintWriter(os);
			InputStream is = socket.getInputStream();
			br = new BufferedReader(new InputStreamReader(is));
			
			/* 바이트 단위 전송
			 * pw.write("안녕? I'm Cityboy");
			 * pw.flush();    */
			
			//Line 단위 전송
			pw.println("hi? I'am kj");
			pw.flush();
			
			//서버로부터 오는 데이터를 받는 스레드 생성 + 실행
			new ReceiveThread().start();
			
		} catch (UnknownHostException e) {

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

			e.printStackTrace();
		}
	}
	//서버로 부터 오는 데이터를 받는 역활을 맡는다.
	class ReceiveThread extends Thread{
		String line;
		
		@Override
		public void run() {
			super.run();
			try {
				while( (line=br.readLine()) != null){
					/*주의: 스레드에서는 뷰에 접근할 수없다.*/
					
					//대안1:post 메서드 사용, 대안2:핸들러 사용
					textView.post(new Runnable() {
						@Override
						public void run() {
							String before = (String) textView.getText();
							textView.setText(line+"\n"+before);
						}
					});
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void onClick(View v) {
		String msg = editText.getText().toString().trim();
		pw.println(msg);
		pw.flush();
	}
}







'Android > 2012.04월 강좌' 카테고리의 다른 글

13일차 Font  (0) 2012.05.14
12일차 SocketServer 2 (Client,Server C->C)  (0) 2012.05.11
11일차 Json  (0) 2012.05.10
11일차 NavarOpenAPI 이용한 Dom Parser  (0) 2012.05.10
11일차 DOM과 SAX의 기술적 특징  (0) 2012.05.10
JsonActivity.java
package com.gusfree.json;

import org.json.JSONException;
import org.json.JSONObject;

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

public class JsonActivity extends Activity {

	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        TextView textView= new TextView(this);
        //Object : {string:value,string:value,string:value...}
        String test1="{title:음식점,price:2000,location:강남}";
        String content="";
        try {
        	JSONObject jsonObject = new JSONObject(test1);
        	String title =jsonObject.getString("title");
        	String price =jsonObject.getString("price");
        	String location =jsonObject.getString("location");
        	content="title: "+title+" price: "+price+" locaction: "+location;
        
        } catch (JSONException e) {
			e.printStackTrace();
		}
        textView.setText(content);
        setContentView(textView);
        
	}
}
/* <Data>
 * 	  <title>음식점 </title>
 * 	  <price>2000 </price>
 * 	  <location>강남 </location>
 * </Data>
 * 
 * 
 * {"음식점",2000,강남} //Json 방식 Mobile
 * */
 








package com.gusfree.json;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

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

public class JsonActivity extends Activity {
 
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        TextView textView= new TextView(this);
        //Object : {string:value,string:value,string:value...}
        String test1="{title:음식점,price:2000,location:강남}";
        String content="";
        try {
        	JSONObject jsonObject = new JSONObject(test1);
        	String title =jsonObject.getString("title");
        	String price =jsonObject.getString("price");
        	String location =jsonObject.getString("location");
        	content="title: "+title+" price: "+price+" locaction: "+location;
        
        	//JSONArray 따옴표 안에 따옴표를 표현하고 싶을 때
        	//\n
        	
        	String test2="[ \"목요일 \",\"금요일 \" ]";
        	JSONArray jasonArray =new JSONArray(test2);
        	Object first = jasonArray.get(0);
        	Object second = jasonArray.get(1);
        	content += "\n" +first.toString() + "\n" +second.toString();
        	
        } catch (JSONException e) {
			e.printStackTrace();
		}
        textView.setText(content);
        setContentView(textView);
        
	}
}
/* <Data>
 * 	  <title>음식점 </title>
 * 	  <price>2000 </price>
 * 	  <location>강남 </location>
 * </Data>
 * 
 * 
 * {"음식점",2000,강남} //Json 방식 Mobile
 * */
 



manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.gusfree.naver"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".NaverOpenAPIActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>
NaverOpenAPIActivity.java
package com.gusfree.naver;

import java.io.InputStream;
import java.net.URL;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;



public class NaverOpenAPIActivity extends Activity {
	ListView listView;

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

		listView=(ListView) findViewById(R.id.listView1);

		String sample =
"http://openapi.naver.com/search?key=자신의 키값&query=starwars&display=10&start=1&target=movie";

		try {
			URL url = new URL(sample);
			InputStream is = url.openStream();
			//Dom Parser, Document Object

			DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();

			DocumentBuilder builder=factory.newDocumentBuilder();

			//데이터를 읽어서 다큐먼트를 만드느다.
			Document document = builder.parse(is);

			//<total>태그의 value 값 (total태그는 1개 뿐이다)
			String total=document.getElementsByTagName("total").item(0).
					getFirstChild().getNodeValue();

			Log.i("검색결과 갯수","검색결과 갯수"+total);

			for(int i=0;i<Integer.parseInt(total);i++){
				//!title은 최초에
				//<title>Naver Open API - movie ::'starwars'</title>
				//에 나오기 대문에 i+1번째로 보기로 하자
				String title=document.getElementsByTagName("title").item(0).
						getFirstChild().getNodeValue();
				/*<actor> 태그 value를 전부 Log찍기*/
				String actor=document.getElementsByTagName("actor").item(0).
						getFirstChild().getNodeValue();

				Log.i("for문","title= "+title);
				Log.i("for문","actor= "+actor);
			}

			/*모든 태그가 열고 닫힘이 100%일치해야 사용가능*/
		
			/*//item 10개가 들어있다
			NodeList itemList = document.getElementsByTagName("item");

			for(int i=0;i<itemList.getLength();i++){
				Node itemNode = itemList.item(i);
				NodeList itemChildList = itemNode.getChildNodes();
				for(int j=0;j<itemChildList.getLength();j++){
					//tite,link,image,subtitle.....
					String text= itemChildList.item(j).getFirstChild().getNodeValue();

					Log.i("텍스트","텍스트: "+text);
				}
				Log.w("다음 item","다음 item");

			}*/
		} catch (Exception e) {
		}
	}
}



'Android > 2012.04월 강좌' 카테고리의 다른 글

11일차 SocketServer (Client,Server C->S, S->C)  (0) 2012.05.10
11일차 Json  (0) 2012.05.10
11일차 DOM과 SAX의 기술적 특징  (0) 2012.05.10
11일차 오픈 API 사용법  (0) 2012.05.10
11일차 Weather (SAX parser)  (0) 2012.05.10



PULLparser - 내가 직접 파싱을 처리

DOM Parser - 한번 받은 데이터를 재사용해야 할때

JSOMPaser

'Android > 2012.04월 강좌' 카테고리의 다른 글

11일차 Json  (0) 2012.05.10
11일차 NavarOpenAPI 이용한 Dom Parser  (0) 2012.05.10
11일차 오픈 API 사용법  (0) 2012.05.10
11일차 Weather (SAX parser)  (0) 2012.05.10
11일차 Samples for SDK 사용하기  (0) 2012.05.10

로그인 하고 더보기 클릭 도구에 개발자 센터 들어가자


개발자센터 오픈API


검색API 키추가




우리는 안드로이드 쓰니 안드로이드클릭



발급키를 사용합니다.



검색하고 싶은 목록 클릭 우선 나는 영화



샘플 URL으로 검색해보자



test에 자기가 발급받은 키값을 주자


그럼 정보가 뜬다~~


'Android > 2012.04월 강좌' 카테고리의 다른 글

11일차 NavarOpenAPI 이용한 Dom Parser  (0) 2012.05.10
11일차 DOM과 SAX의 기술적 특징  (0) 2012.05.10
11일차 Weather (SAX parser)  (0) 2012.05.10
11일차 Samples for SDK 사용하기  (0) 2012.05.10
10일차 TouchEvent  (0) 2012.05.09

가상청 사이트에가서 RSS 주소를 알아오자..

http://www.kma.go.kr/








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" >
  
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

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

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>


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

</LinearLayout>
mainfast.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.gusfree.weatherparse"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".WeatherParseActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>
data.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="34dp"
        android:layout_toRightOf="@+id/textView1"
        android:text="TextView" />

    <TextView
        android:id="@+id/textView4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="20dp"
        android:layout_toRightOf="@+id/textView1"
        android:text="TextView" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/textView4"
        android:layout_marginLeft="24dp"
        android:layout_toRightOf="@+id/textView2"
        android:text="TextView" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:src="@drawable/ic_launcher" />
    
</RelativeLayout>

WeatherParseActivity.java
package com.gusfree.weatherparse;

import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class WeatherParseActivity extends Activity implements OnClickListener{

	TextView textView;
	ListView listView;
	InputStream is;
	//Date를 넣을 Collections
	ArrayList<Data> list =new ArrayList<Data>();

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

		findViewById(R.id.button1).setOnClickListener(this);
		findViewById(R.id.button2).setOnClickListener(this);
		textView=(TextView) findViewById(R.id.textView1);
		listView=(ListView) findViewById(R.id.listView1);

		findViewById(R.id.button1).performClick();//test용
		findViewById(R.id.button2).performClick();//test용
	}

	@Override
	public void onClick(View v) {
		switch(v.getId()){

		case R.id.button1 : //날씨 정보 요청하고 응답받기
			String addr ="http://www.kma.go.kr/weather/forecast/mid-term-xml.jsp?stnId=108";
			try{
				URL url =new URL(addr); //String -> URL
				//InputStream is = url.openStream(); 가장 간단한 방법

				//내가 요청할 내용
				HttpGet httpGet = new HttpGet(addr);

				//내가 고객
				HttpClient client= new DefaultHttpClient();

				//고객이 요청 사항을 전달하기 ->결과가 돌아옴
				HttpResponse response = client.execute(httpGet);

				if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){//응답과 요청이 성공했다.

					is=response.getEntity().getContent();

					/*int k=0;
				ByteArrayBuffer bab =new ByteArrayBuffer(64);
				while( (k=is.read())!=-1 ){//아스키코드 0~255
					bab.append(k);

				}
				//ByteArrayBuffer -> byteArray -> String
				textView.setText(new String(bab.toByteArray()));*/

				}else{
					Toast.makeText(this,"요청중 예외발생", 0).show();
				}
			}catch(Exception e){
			}
			break;

		case R.id.button2 : //받은 데이터를 파싱해서 화면 출력
			//SaxPaser로 InputStream의 데이터를 파싱하자
			try {
				SAXParserFactory factory = SAXParserFactory.newInstance();
				SAXParser saxParser =factory.newSAXParser();
				XMLReader reader = saxParser.getXMLReader();

				//InputStream -> InputSource로 형변환 하자
				InputSource source = new InputSource(is);

				reader.setContentHandler(new ReaderWork());
				reader.parse(source);//return void;		

				/*MyThread thread =new MyThread();
				thread.start();*/

			} catch (Exception e) {
			}
			break;
		}
	}

	//리더가 할 일을 명시해둔 클래스
	class ReaderWork extends DefaultHandler{

		String city;         
		String numEf;		 //2일후 예보
		String tmEf;         //날짜 태그
		String wf;           //날씨예보 태그
		String tmn;          //최저온도 태그
		String tmx;          //최고 온도 태그
		String reliability;  //신뢰도 태그
		String tag;
		String text;

		@Override //xml 파싱을 시작할때 1번 호출
		public void startDocument() throws SAXException {
			Log.w("startDocument","startDocument");
			super.startDocument();
		}

		@Override  //여는 태그를 만날때 호출
		public void startElement(String uri, String localName, String qName,
				Attributes attributes) throws SAXException {
			Log.i("startElement","startElement"+localName);
			super.startElement(uri, localName, qName, attributes);
		}


		@Override //태그와 태그 사이의 값을 만날 때 호출
		public void characters(char[] ch, int start, int length)
				throws SAXException {
			//ch ={'a','b','c','d','e','f'} => "abcde"
			text=new String(ch,start,length);
			Log.i("characters","characters"+text);
			super.characters(ch, start, length);
		}


		@Override //닫는 태그를 만날때 호출
		public void endElement(String uri, String localName, String qName)
				throws SAXException {
			Log.w("endElement","endElement");
			if(localName.equalsIgnoreCase("city")){
				Log.e("city 닫는 태그","city 닫는태그 " +text);
				city=text;
			}else if(localName.equalsIgnoreCase("numEf")){
				numEf=text;
			}else if(localName.equalsIgnoreCase("tmEf")){
				tmEf=text;
			}else if(localName.equalsIgnoreCase("wf")){
				wf=text;
			}else if(localName.equalsIgnoreCase("tmn")){
				tmn=text;
			}else if(localName.equalsIgnoreCase("tmx")){
				tmx=text;
			}else if(localName.equalsIgnoreCase("reliability")){
				reliability=text;

				//변수 7개에 값이 들어값으므로 객체 생성
				Data data = new Data(city,numEf,tmEf,wf,tmn,tmx,reliability);
				list.add(data);
				Log.e("객체생성","-----------------------------------------");
			}
			super.endElement(uri, localName, qName);
		}
		@Override //문서 마지막에 호출
		public void endDocument() throws SAXException {
			Log.w("endDocument","endDocument");
			super.endDocument();

			listView.setAdapter(new MyAdapter());
		}
	}

	class MyAdapter extends BaseAdapter{

		@Override
		public int getCount() {
			return list.size();
		}

		@Override
		public Object getItem(int arg0) {
			return null;
		}

		@Override
		public long getItemId(int arg0) {
			return 0;
		}

		@Override
		public View getView(int position, View arg1, ViewGroup arg2) {
			//list안에 들은 Data객체의 필득값을
			//data.xml안의 뷰에 셋팅해서 return하기

			Data oneData = list.get(position);
			RelativeLayout layout =
					(RelativeLayout)View.inflate(getApplicationContext(), R.layout.data, null);
			TextView tv1=(TextView) layout.findViewById(R.id.textView1);//도시 이름 city
			TextView tv2=(TextView) layout.findViewById(R.id.textView2);//날짜 tmEf
			TextView tv3=(TextView) layout.findViewById(R.id.textView3);//tmn~tmx
			TextView tv4=(TextView) layout.findViewById(R.id.textView4);//날씨 wf
			ImageView imgView=(ImageView) layout.findViewById(R.id.imageView1);//

			tv1.setText(oneData.city);
			tv2.setText(oneData.tmEf);
			tv3.setText(oneData.tmn+" ~ "+oneData.tmx);
			tv4.setText(oneData.wf);

			if(oneData.wf.contains("비")){
				imgView.setImageResource(R.drawable.rainy);
			}else if(oneData.wf.contains("구름")){
				imgView.setImageResource(R.drawable.cloudy);
			}else if(oneData.wf.contains("조금")){
				imgView.setImageResource(R.drawable.mcloudy);
			}
			return layout;
		}
	}

	class MyThread extends Thread{
		@Override
		public void run() {
			//할일
			super.run();
		}
	}
}
Data.java
package com.gusfree.weatherparse;

public class Data {
	String city;         
	String numEf;		 //2일후 예보
	String tmEf;         //날짜 태그
	String wf;           //날씨예보 태그
	String tmn;          //최저온도 태그
	String tmx;          //최고 온도 태그
	String reliability;  //신뢰도 태그
	
	
	public Data(String city, String numEf, String tmEf, String wf, String tmn,
			String tmx, String reliability) {
		super();
		this.city = city;
		this.numEf = numEf;
		this.tmEf = tmEf;
		this.wf = wf;
		this.tmn = tmn;
		this.tmx = tmx;
		this.reliability = reliability;
	}
}



'Android > 2012.04월 강좌' 카테고리의 다른 글

11일차 DOM과 SAX의 기술적 특징  (0) 2012.05.10
11일차 오픈 API 사용법  (0) 2012.05.10
11일차 Samples for SDK 사용하기  (0) 2012.05.10
10일차 TouchEvent  (0) 2012.05.09
10일차 Login  (0) 2012.05.09

밑에 이게 자신의 API 버전에 맞게 설치하거나 되어저야한다.



그리고 새로운 프로젝트를 만들 때 Create project from existing sample로 설치한다~



APIDemos를 쓰고 싶으니까 이걸 선택하고 설치~


'Android > 2012.04월 강좌' 카테고리의 다른 글

11일차 오픈 API 사용법  (0) 2012.05.10
11일차 Weather (SAX parser)  (0) 2012.05.10
10일차 TouchEvent  (0) 2012.05.09
10일차 Login  (0) 2012.05.09
10일차 TabView  (0) 2012.05.09

+ Recent posts