반응형



Context Menu : 특정 뷰(View)를 오래 누르고 있으면 나타나는 메뉴(일반 PC에서 마우스 오른쪽버튼의 역할)


버튼(Button) 뷰를 하나 만들고 이 버튼에 컨텍스트 메뉴를 만들겁니다.


 짧게 클릭하면 'Normal Cliking'이라는 글씨가 보입니다.


이 버튼을 길게 누르고 있으면 Context Menu가 나타납니다.

특정 메뉴 아이템을 선택하면 해당하는 Toast가 표시되는 예제소스입니다.



먼저 실행 화면입니다.


             메인화면                    일반적인 버튼클릭             길게눌러서 Context Menu 발생

    


  

 컨텍스트 메뉴(Context Menu)의 각 menuItem 선택시의 Toast



소스코드

 MainActivity.java

 public class MainActivity extends Activity {

Button btn_Contextmenu;


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//Button View 객체 참조

btn_Contextmenu= (Button)findViewById(R.id.btn_contextmenu);

//btn_Contextmenu 버튼 뷰를 Context Menu로 등록

//어떠한 View 객체도 Context Menu로 등록 가능

registerForContextMenu(btn_Contextmenu);

}

//컨텍스트 메뉴(Context Menu)로 등록된 View(btn_contextmenu)가 길게 눌러질때 호출되는 메소드

@Override

public void onCreateContextMenu(ContextMenu menu, View v,

ContextMenuInfo menuInfo) {

// TODO Auto-generated method stub

//res폴더의 menu플더안에 xml로 MenuItem추가하기.

//mainmenu.xml 파일을 java 객체로 인플레이트(inflate)해서 menu객체에 추가

getMenuInflater().inflate(R.menu.mainmenu, menu);

super.onCreateContextMenu(menu, v, menuInfo);

}

//컨텍스트 메뉴(Context Menu)의 MenuItem을 선택했을 때 자동으로 호출되는 메소드

@Override

public boolean onContextItemSelected(MenuItem item) {

// TODO Auto-generated method stub

switch( item.getItemId() ){//눌러진 MenuItem의 Item Id를 얻어와 식별

case R.id.save:

Toast.makeText(this, "SAVE", Toast.LENGTH_SHORT).show();

break;

case R.id.search:

Toast.makeText(this, "SEARCH", Toast.LENGTH_SHORT).show();

break;

case R.id.setting:

Toast.makeText(this, "SETTING", Toast.LENGTH_SHORT).show();

break;

}

return super.onContextItemSelected(item);

}

    //Button 클릭시에 자동으로 호출되는 callback Method...

    public void mOnClick(View v){

    

     switch( v.getId() ){

    

     case R.id.btn_contextmenu: //일반적인 버튼의 짧은 클릭시 토스트 (Toast) 발생

    

     Toast.makeText(this, "Normal Clicking", Toast.LENGTH_SHORT).show();    

    

     break;

     }

    

    }

}




메뉴아이템을 설계하는 XML 리소스를 만듭니다.

(이전 옵션메뉴 포스트의 xml파일을 가져와도 됨)

res폴더 안에 'menu'라는 이름으로 폴더를 만드세요(절대 이름 틀리면 안됨)

만들어진 menu폴더안에 mainmenu.xml 파일을 하나 추가하세요.


메뉴 XML 리소스 파일

 mainmenu.xml

 <menu xmlns:android="http://schemas.android.com/apk/res/android" >

    

    <item

        android:id="@+id/save" 

        android:title="SAVE"

        android:icon="@android:drawable/ic_menu_save" />

    

    <item

        android:id="@+id/search" 

        android:title="LOAD"

        android:icon="@android:drawable/ic_menu_search" />

    

    <item

        android:id="@+id/setting" 

        android:title="SETTING"

        android:icon="@android:drawable/ic_menu_edit" />


</menu>

  

반응형
반응형

안드로이드는 기본적으로 세가지 메뉴를 가지고 있습니다.


1. Option Menu : 디바이스의 하드웨어 menu키(일부 기기에서는 소프트키로 되어 있습니다.)를 눌렀을 때 아래에서 쑥 올라오는 메뉴

2. Context Menu : 특정 뷰(View)를 오래 누르고 있으면 나타나는 메뉴(일반 PC에서 마우스 오른쪽버튼의 역할)-다음 포스트에서 소개

3. Popup Menu : 특정 명령에 따라 특정 위치에 팝업(Popup)되어 서브 메뉴용도로 사용할 수 있는 메뉴-다다음 포스트에서 소개


이번 포스트는 옵션 메뉴를 만드는 예제소스입니다.

참고로 허니콤(api 10)버전 이후부터 액션바(ActionBar)의 개념이 생기면서 Option 메뉴의 위치가 변경되었습니다.


옵션메뉴(Option Menu)를 액션바 메뉴(Action Bar)메뉴로 사용하게 하였습니다.

안드로이드 폰 중에서 하드웨어 키로 Menu나 Home버튼이 있는 경우는 여전히 아래에서 옵션메뉴가 나타납니다.

반면에 소프트키로 menu나 Home 버튼이 있는 일부 기기(LG g3 등)에서는 액션바(Action Bar)에서 옵션메뉴가 아래로 펼쳐집니다.


아. 물론 하드웨어 키가 있는 기기에서도 옵션메뉴를 눌렀을 때 액션바(Action Bar)에서 나타나게 할 수 있습니다.


먼저 실행 화면입니다.


      하드웨어 메뉴키(GenyMotion)            아래쪽에서 나타나는 옵션메뉴(Option Menu)

     


    

각각의 아이템을 눌렀을 때 Toast 발생



먼저 Java 코드만으로 옵션메뉴를 보여주도록 했습니다.


Menu의 아이템들을 XML의 리소스로 제작하는 방식은 아래 코드에서 주석처리 되어있습니다.

xml 리소스로 메뉴를 제작하실 때는

menu.add() 메소드를 주석처리하시고

getMenuInflater().inflate(R.menu.mainmenu, menu); 부분의 주석을 해제하세요.

그리고 아래 onOptionsItemSelected() 메소드의

2개의 switch문의 주석을 서로 바꾸세요.


소스코드

 MainActivity.java

 public class MainActivity extends Activity {

public static final int DATA_SAVE=1;

public static final int DATA_SEARCH=2;

public static final int DATA_SETTING=3;


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

//디바이스의 Menu 버튼이 처음 눌러졋을 때 한번 호출되는 메소드

//Menu의 MenuItem을 설정하는 메소드

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// TODO Auto-generated method stub

//java언어에서 바로 MenuItem 추가하기..

//add( Group Id, Item Id, 배치순서, 메튜타이틀);

//Group Id : 메튜아이템을 그룹으로 관리할 때 그룹의 식별값

//Item Id : 각각의 MenuItem을 구별하기 위한 고유 식별값: 위에 final 살수로 선언

//배치순서(order) : add한 순서와 상관없이 배치순서를 정할 대 사용

menu.add(0, DATA_SAVE, 0, "SAVE");

menu.add(0, DATA_SEARCH, 0, "SEARCH");

menu.add(0, DATA_SETTING, 0, "SETTING");

/* res폴더의 menu플더안에 xml로 MenuItem추가하기.(icon 추가)

//mainmenu.xml 파일을 java 객체로 인플레이트(inflate)해서 menu객체에 추가

getMenuInflater().inflate(R.menu.mainmenu, menu);

*/

return super.onCreateOptionsMenu(menu);

}

//디바이스의 Menu 버튼이 눌러질때 마다 매번 호출되는 메소드

//처음 create 할때의 메뉴의 내용을 변경하고 싶을 대 사용하는 메소드

@Override

public boolean onPrepareOptionsMenu(Menu menu) {

// TODO Auto-generated method stub

return super.onPrepareOptionsMenu(menu);

}

//OptionMenu의 MenuItem 중 하나를 눌렀을 때 자동으로 호출되는 메소드

@Override

public boolean onOptionsItemSelected(MenuItem item) {

// TODO Auto-generated method stub

switch( item.getItemId() ){//눌러진 MenuItem의 Item Id를 얻어와 식별

case DATA_SAVE:

Toast.makeText(this, "SAVE", Toast.LENGTH_SHORT).show();

break;

case DATA_SEARCH:

Toast.makeText(this, "SEARCH", Toast.LENGTH_SHORT).show();

break;

case DATA_SETTING:

Toast.makeText(this, "SETTING", Toast.LENGTH_SHORT).show();

break;

}

/* mainmenu.xml을 사용했을때의 switch 문

switch( item.getItemId() ){//눌러진 MenuItem의 Item Id를 얻어와 식별

case R.id.save:

Toast.makeText(this, "SAVE", Toast.LENGTH_SHORT).show();

break;

case R.id.search:

Toast.makeText(this, "SEARCH", Toast.LENGTH_SHORT).show();

break;

case R.id.setting:

Toast.makeText(this, "SETTING", Toast.LENGTH_SHORT).show();

break;

}

*/

return super.onOptionsItemSelected(item);

}

}




만약 메뉴아이템의 설계를 XML 리소스로 하신다면

res폴더 안에 'menu'라는 이름으로 폴더를 만드세요(절대 이름 틀리면 안됨)

만들어진 menu폴더안에 mainmenu.xml 파일을 하나 추가하세요.


메뉴 XML 리소스 파일

 mainmenu.xml

 <menu xmlns:android="http://schemas.android.com/apk/res/android" >

    

    <item

        android:id="@+id/save" 

        android:title="SAVE"

        android:icon="@android:drawable/ic_menu_save" />

    

    <item

        android:id="@+id/search" 

        android:title="LOAD"

        android:icon="@android:drawable/ic_menu_search" />

    

    <item

        android:id="@+id/setting" 

        android:title="SETTING"

        android:icon="@android:drawable/ic_menu_edit" />


</menu>

 


이 메뉴아이템들에는 추가적으로 아이콘(icon)를 설정해 주었습니다.

참고로 위의 자바파일에서는 setIcon()메소드로 아이콘을 추가할 수도 있습니다.

다만 최신 버전의 기기에서는 아래에서 나오는 옵션메뉴를 지양는 추세여서 아이콘이 보이지 않습니다.


아이콘이 보이려면 액션바(Action Bar) 메뉴로 나타나도록 해야 합니다.

방법은 간단합니다.

XML 리소르 아이템(item)를 작성할 때 showAsAction:속성만 추가해주면 됩니다.

제어하는 방식은 위의 소스코드와 동일합니다.


Action Bar 메뉴 XML 리소스 파일

 mainmenu.xml

 <menu xmlns:android="http://schemas.android.com/apk/res/android" >

    

    <item

        android:id="@+id/save" 

        android:title="SAVE"

        android:icon="@android:drawable/ic_menu_save"

        android:showAsAction="ifRoom" />

    

    <item

        android:id="@+id/search" 

        android:title="LOAD"

        android:icon="@android:drawable/ic_menu_search"        

        android:showAsAction="ifRoom" />

    

    <item

        android:id="@+id/setting" 

        android:title="SETTING"

        android:icon="@android:drawable/ic_menu_edit"

        android:showAsAction="ifRoom" />


</menu>

 


ShowAsAction : 주요속성값

 ifRoom

 액션바에 공간이 있다면 보이도록 함(아이콘만 보임)-가장많이 사용

 never 

 액션바의 공간과 상관없이 무조건 숨겨져 있도록 함(메뉴키 또는 Overflow를 눌렀을 때 보임)-Default 값

 always 

 무조건 보이도록 함( 공간이 없다면 겹침. 비추)

 withText

 텍스트와 아이콘을 같이 보이도록 함



액션바 메뉴(Action Bar Menu)로 사용하는 옵션메뉴




반응형
반응형

인텐트(Intent)를 이용하여 안드로이드 시스템 액티비티들(스마트폰 개발회사가 미리 설치해 놓은 어플들)을 호출하는 예제입니다.


많은 시스템액티비티들 중에서 주로 많이 이용되고 있는 sms 문자보내기전화걸기이메일보내기 등의 어플들을 실행시켜보는 예제 소스입니다. 




메인화면                                        Dial Activity(전화번호 입력 액티비티)          Call Activity(전화걸기 액티비티)

    





SMS Activity(sms문자보내기 액티비티)      Web Page Activity(웹브라우져 액티비티)

   


 

Layout 파일

 activity_main.xml

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical" >

    

    <Button android:id="@+id/btn_dial"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="Start Dial Activity"

        android:onClick="mOnClick"/>

    

    <Button android:id="@+id/btn_call"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="Start Call Activity"

        android:onClick="mOnClick"/>

    

    <Button android:id="@+id/btn_sms"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="Start SMS Activity"

        android:onClick="mOnClick"/>

    

    <Button android:id="@+id/btn_webpage"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="Start Web Page Activity"

        android:onClick="mOnClick"/>

    

    <Button android:id="@+id/btn_email"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="Start E-Mail Activity"

        android:onClick="mOnClick"/>   


</LinearLayout>




소스파일

 

 MainActivity.java

 public class MainActivity extends Activity {


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

    //Button 클릭시에 자동으로 호출되는 callback Method...

    public void mOnClick(View v){

    

     Intent i; //시스템액티비티를 부를 Intent 참조변수

     Uri uri;  //시스템 액티비티의 세부 종류를 구분하는 Data는 Uri객체로 제공. 이를 위한 참조변수

    

     switch( v.getId() ){

    

     case R.id.btn_dial://전화번호 Dial 입력 액티비티 

    

     uri= Uri.parse("tel:01012345678"); //전화와 관련된 Data는 'Tel:'으로 시작. 이후는 전화번호

     i= new Intent(Intent.ACTION_DIAL,uri); //시스템 액티비티인 Dial Activity의 action값

     startActivity(i);//액티비티 실행   

    

     break;

    

     case R.id.btn_call://전화걸기 화면 액티비티

    

     uri= Uri.parse("tel:01012345678"); //전화와 관련된 Data는 'Tel:'으로 시작. 이후는 전화번호

     i= new Intent(Intent.ACTION_CALL,uri); //시스템 액티비티인 Dial Activity의 action값

     startActivity(i);//액티비티 실행  

     //전화걸기 액티비티는 전화요금과 관련된 것이기에 반드시 퍼미션(permission)을 받아야 합니다.

     //메니페스트 파일에 <uses-permission android:name="android.permission.CALL_PHONE"/> 추가.

    

     break;

     case R.id.btn_sms://문자보내기 액티비티

    

     uri= Uri.parse("smsto:01012345678"); //sms 문자와 관련된 Data는 'smsto:'로 시작. 이후는 문자를 받는 사람의 전화번호

     i= new Intent(Intent.ACTION_SENDTO,uri); //시스템 액티비티인 SMS문자보내기 Activity의 action값

     i.putExtra("sms_body", "Hello...");  //보낼 문자내용을 추가로 전송, key값은 반드시 'sms_body'

     startActivity(i);//액티비티 실행   

    

     break;

    

     case R.id.btn_webpage://웹브라우저 실행

    

     uri= Uri.parse("http://www.naver.com"); //웹페이지와 관련된 Data는 'http:'으로 시작. 이후는 사이트의 URL

     i= new Intent(Intent.ACTION_VIEW, uri); //시스템 액티비티인 Dial Activity의 action값

     startActivity(i);//액티비티 실행  

     //웹페이지 액티비티는 데이터요금과 관련된 것이기에 퍼미션(permission)을 받도록 합니다.

     //메니페스트 파일에 <uses-permission android:name="android.permission.INTERNET"/> 추가.

    

     break;


     case R.id.btn_email://이메일 보내기

    

     uri= Uri.parse("mailto:abcd@naver.com"); //이메일과 관련된 Data는 'mailto:'으로 시작. 이후는 이메일 주소

     i= new Intent(Intent.ACTION_SENDTO, uri); //시스템 액티비티인 Dial Activity의 action값

     startActivity(i);//액티비티 실행  

     //GenyMotion 무료버전에서는 실행오류. 실제 디바이스에서는 동작됩니다.

    

     break;   

    

     }

    

    }

}

 



 전화걸기와 네트워크를 사용하기 위해서는 사용 권한(uses-permission)이 필요합니다.

여러분 프로젝트의 메니페스트 파일에 퍼미션을 추가합니다.


 AndroidManifest.xml

 <manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.kitesoft.systemintent"

    android:versionCode="1"

    android:versionName="1.0" >


    <uses-sdk

        android:minSdkVersion="14"

        android:targetSdkVersion="16" />

    

    <!-- 전화걸기 Call 액티비티 실행 퍼미션 -->

    <uses-permission android:name="android.permission.CALL_PHONE"/>

    

    <!-- 네트워크 사용 액티비티들에 대한 퍼미션 -->

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


    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <activity

            android:name=".MainActivity"

            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>


 



기타 시스템 액티비티들


// 구글맵 띄우기

Uri uri = Uri.parse("geo:38.899533,-77.036476");

Intent it = new Intent(Intent.Action_VIEW,uri);

startActivity(it);

 

 

// 구글 길찾기 띄우기

Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=출발지주소&daddr=도착지주소&hl=ko");

Intent it = new Intent(Intent.ACTION_VIEW,URI);

startActivity(it);  

 

// SMS/MMS 발송

Intent it = new Intent(Intent.ACTION_VIEW);   

it.putExtra("sms_body", "The SMS text");   

it.setType("vnd.android-dir/mms-sms");   

startActivity(it); 

 

// MMS 발송

Uri uri = Uri.parse("content://media/external/images/media/23");   

Intent it = new Intent(Intent.ACTION_SEND);   

it.putExtra("sms_body", "some text");   

it.putExtra(Intent.EXTRA_STREAM, uri);   

it.setType("image/png");   

startActivity(it);

 

 

// 이메일 발송 

Intent it = new Intent(Intent.ACTION_SEND);   

it.putExtra(Intent.EXTRA_EMAIL, "me@abc.com");   

it.putExtra(Intent.EXTRA_TEXT, "The email body text");   

it.setType("text/plain");   

startActivity(Intent.createChooser(it, "Choose Email Client")); 

 

 

Intent it = new Intent(Intent.ACTION_SEND);     

String[] tos = {"me@abc.com"};     

String[] ccs = {"you@abc.com"};     

it.putExtra(Intent.EXTRA_EMAIL, tos);     

it.putExtra(Intent.EXTRA_CC, ccs);     

it.putExtra(Intent.EXTRA_TEXT, "The email body text");     

it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");     

it.setType("message/rfc822");     

startActivity(Intent.createChooser(it, "Choose Email Client"));  

 

 

// extra 추가하기

Intent it = new Intent(Intent.ACTION_SEND);   

it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");   

it.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/mysong.mp3");   

sendIntent.setType("audio/mp3");   

startActivity(Intent.createChooser(it, "Choose Email Client"));

 

 

// 미디어파일 플레이 하기

Intent it = new Intent(Intent.ACTION_VIEW);

Uri uri = Uri.parse("file:///sdcard/song.mp3");

it.setDataAndType(uri, "audio/mp3");

startActivity(it);

 

 

Uri uri = Uri.withAppendedPath(

  MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1");   

Intent it = new Intent(Intent.ACTION_VIEW, uri);   

startActivity(it); 

 

 

// 설치 어플 제거

Uri uri = Uri.fromParts("package", strPackageName, null);   

Intent it = new Intent(Intent.ACTION_DELETE, uri);   

startActivity(it);

 

 

// APK파일을 통해 제거하기

Uri uninstallUri = Uri.fromParts("package", "xxx", null);

returnIt = new Intent(Intent.ACTION_DELETE, uninstallUri);

 

 

// APK파일 설치

Uri installUri = Uri.fromParts("package", "xxx", null);

returnIt = new Intent(Intent.ACTION_PACKAGE_ADDED, installUri);

 

 

// 음악 파일 재생

Uri playUri = Uri.parse("file:///sdcard/download/everything.mp3");

returnIt = new Intent(Intent.ACTION_VIEW, playUri);

 

 

// 첨부파일을 추가하여 메일 보내기

Intent it = new Intent(Intent.ACTION_SEND);  

it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");  

it.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/eoe.mp3");  

sendIntent.setType("audio/mp3");  

startActivity(Intent.createChooser(it, "Choose Email Client"));

 

 

// 마켓에서 어플리케이션 검색

Uri uri = Uri.parse("market://search?q=pname:pkg_name");  

Intent it = new Intent(Intent.ACTION_VIEW, uri);  

startActivity(it);  

// 패키지명은 어플리케이션의 전체 패키지명을 입력해야 합니다.

 

 

// 마켓 어플리케이션 상세 화면

Uri uri = Uri.parse("market://details?id=어플리케이션아이디");  

Intent it = new Intent(Intent.ACTION_VIEW, uri);  

startActivity(it);

// 아이디의 경우 마켓 퍼블리싱사이트의 어플을 선택후에 URL을 확인해보면 알 수 있습니다.

 

 

// 구글 검색

Intent intent = new Intent();

intent.setAction(Intent.ACTION_WEB_SEARCH);

intent.putExtra(SearchManager.QUERY,"searchString")

startActivity(intent);



[출처. 인터넷 검색(어딘지 기억이 안나네요. 문제되면 댓글달아 주세요~)]


반응형
반응형

이미지를 로딩하거나 외부데이터베이스의 데이터를 로딩하는 등의 오래걸리는 작업을 수행할 때 사용자가 앱이 멈춘것이 아니라는 것을 인지시키기 위해 ProgressDialog를 사용하게 됩니다. 이 ProgressDialog에는 두가지 모양의 Progress가 가능합니다.


1. 로딩할 데이터의 양이 얼마인지 몰라 현재 얼마만큼 작업이 수행된건지 측정할 수 없을 때 사용하는 둥근 형태의 SPINNER 스타일.

2. 로딩할 데이터의 양이 얼마인지 알고있어서 현재 작업수행정도를 표시할 수 있을 때 사용하는 막대바 형태의 HORIZONTAL 스타일.


이 중 막대바형태의 ProgressDialog 를 진행시키기 위해서는 별도의 Thread를 사용해야만 합니다. 이때 별도의 Thread에서 Progress를 진행하는 것은 어렵지 않지만 주의할 점은 화면(UI)은 오로지 main(UI) Thread 만 변경이 가능하다는 것입니다. 그렇기에 별도의 작업스레드에서 진행상황을 변경하는 명령을 수행할 수 없어서 runOnUiThread() 메소드를 호출하거나 Handler를 이용하여 UI를 변경하는 작업을 수행해야 합니다. 이는 다소 불편하게 느껴질수 있습니다. 그래서 별도의 Thread 작업과 UI 작업을 한번에 할 수 있는 AsyncTask 클래스를 이용해서 막대바 형태의 ProgressDialog를 실행시키는 앱을 소개합니다.



버튼을 누르면 0.1초(100ms) 간격으로 ProgressDialog가 진행되고 끝마치면 Toast를 표시하는 예제 앱 소스입니다.


메인화면                                       버튼클릭시 나타나는 ProgressDialog         Progress 종료후 Toast 완료 메세지























Layout 파일

 activity_main.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="${relativePackage}.${activityClass}" >


    <Button android:id="@+id/button"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="Progress Dialog by AsyncTask"

        android:onClick="mOnClick"/>


</RelativeLayout>


소스파일 

 MainActivity.java

 public class MainActivity extends Activity {

ProgressDialog dialog;   //ProgressDialog 참조변수

int pos_dilaog=0;         //ProgressDialog의 진행 위치


    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

    }

    

    //Button 클릭시에 자동으로 호출되는 callback Method...

    public void mOnClick(View v){

    

     switch( v.getId() ){

    

     case R.id.button:

    

     if(dialog!=null) return;  //ProgressDialog가 현재 보여지고 있다면 아무작업도 하지 않음.

    

     new AsyncProgressDialog().execute(100); // 다이얼로그의 max 값으로 100 전달

    

    

     break;

     }

    

    }

    

    

    //AsyncTask를 상속한 클래스선언

    //AsyncTask 클래스의 콜백 메소드들 중 doInBackground를 제외하고는 기본적으로 main(UI) Thread에서 실행됨.

    //doInBackground를 제외한 다른 메소드에서는 어디서든 UI 작업 가능 

    

    //AsyncTask< 작업스레드가 처리할 데이터 타입 , 다이얼로그의 설정 데이터 타입, 작업의 결과로 리턴할 데이터 타입 >

    //쉽게 소개하면

    //첫번재 데이터 타입은 doInBackground() 메소드의 파라미터 타입을 지정

    //두번재 파라미터의 타입은 onProgressUpdate() 메소드의 파라미터 타입을 지정

    //세번째 파라미터의 타입은 onPostExecute() 메소드의 파라미터 타입을 지정

    class AsyncProgressDialog extends AsyncTask<Integer, Integer, String>{

    

    

     //작업이 시작되기 전에 호출되는 메소드로서 일반적으로 이곳에서 ProgressDialog 객체를 생성.    

     @Override

     protected void onPreExecute() {

     // TODO Auto-generated method stub

     super.onPreExecute();

    

     dialog= new ProgressDialog(MainActivity.this); //ProgressDialog 객체 생성

     dialog.setTitle("Progress");                   //ProgressDialog 제목

     dialog.setMessage("Loading.....");             //ProgressDialog 메세지

     dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); //막대형태의 ProgressDialog 스타일 설정

     dialog.setCanceledOnTouchOutside(false); //ProgressDialog가 진행되는 동안 dialog의 바깥쪽을 눌러 종료하는 것을 금지

    

     dialog.show(); //ProgressDialog 보여주기    

     }    

    

     //excute() 메소드에 의해 실행되는 작업 스레드의 메소드  ( excute()호출 시에 전달한 값 params에서 받음 )

@Override

protected String doInBackground(Integer... params) { 

     // TODO Auto-generated method stub

while( pos_dilaog < params[0]){ //현재 ProgessDialog의 위치가 100보다 작은가? 작으면 계속 Progress

pos_dilaog++;

//ProgressDialog에 변경된 위치 적용 ..

publishProgress(pos_dilaog);  //onProgressUpdate()메소드 호출.

try {

Thread.sleep(100); //0.1초간 스레드 대기 ..예외처리 필수

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}//while

//while을 끝마치고 여기까지 오면 Progress가 종료되었다는 것을 의미함.

pos_dilaog=0; //다음 프로세스를 위해 위치 초기화

return "Complete Load"; // AsyncTask 의 작덥종료 후 "Complete Load" String 결과 리턴

}

//publishProgress()에 의해 호출되는 메소드

@Override

protected void onProgressUpdate(Integer... values) {

// TODO Auto-generated method stub

super.onProgressUpdate(values);

dialog.setProgress(values[0]); //전달받은 pos_dialog값으로 ProgressDialog에 변경된 위치 적용

}

//doInBackground() 메소드 종료 후 자동으로 호출되는 콜백 메소드

//doInBackground() 메소드로부터 리턴된 결과를 파라미터로 받음

@Override

protected void onPostExecute(String result) {

// TODO Auto-generated method stub

super.onPostExecute(result);

dialog.dismiss(); //ProgressDialog 보이지 않게 하기

dialog=null;      //참조변수 초기화

//doInBackground() 메소드로부터 리턴된 결과 "Complete Load" string Toast로 화면에 표시

Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();

}

    

    }//AsyncProgressDailog class..


}//MainActivity class..


반응형
반응형

 이전의 두 포스트는 여러분의 앱에서 다른 앱의 액티비티를 시작하는 방법에 대한 측면에 초첨이 맞추어져 있었습니다. 하지만 만약 여러분의 앱이 다른 앱에게 유용한 action 을 수행할 수 있다면, 여러분의 앱은 다른 앱으로부터 요청된 action에 응답할 수 있도록 미리 준비가 되어 있어야 합니다. 실예로, 만약 여러분이 사용자의 친구들과 메세지나 사진들을 공유할 수 있는 소셜(social) 앱을 만든다면,ACTION_SEND 인텐트를 지원하도록 하는 것이 가장 좋습니다. 그렇게 하면 사용자는 다른 앱으로부터 "공유(share)" action 을 시작되게 할 수 있으며 그 action을 수행할 수 있도록 여러분의 액티비티를 실행할 수 있습니다.


 다른 앱이 여러분의 액티비티를 시작하도록 하기 위해서는 앱의 메니페스트(manifest) 파일안에 해당하는 <activity> 요소에 대해<intent-filter> 요소를 추가할 필요가 있습니다.


 여러분의 앱이 디바이스에 설치되어있을 때, 시스템은 여러분의 인텐트 필터를 식별하며 모든 설치된 앱들에 의해 지원되는 인텐트들의 내부 카테고리에 정보를 추가합니다. 하나의 앱이 묵시적(implicit) 인텐트(Intent)로 startActivity() 또는 startActivityForResult() 메소드를 호출할 때, 시스템은 어떤 액티비티가 이 인텐트(Intent)에 응답할 수 있는지 찾게 됩니다.



인텐트 필터 추가하기(Add an Intent Filter)

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

여러분의 액티비티가 처리할 수 있는 인텐트(Intent)들을 적절하게 정의하기 위해서는, 여러분이 추가한 인텐트 필터는 액티비티가 허용하는 action 과 data 의 타입 측면에서 가능한 명확하게 해야 합니다.


시스템은 액티비티가 가지고 있는 인텐트 필터가 아래에 있는 Intent 객체의 기준에 충족하면 주어진 Intent 를 액티비티에 전달 합니다.


Action

  수행하는 action 의 이름을 지정하는 문자열(String). 일반적으로 ACTION_SEND 또는 ACTION_VIEW 와 같은 값을 정의한 플랫폼 중 하나입니다.


 액티비티의 인텐트 필터안에 <action> 요소를 통해 지정합니다. 이 요소안에 지정하는 값은 API 상수을 대시하여 action에 대한 전체 문자열 이름으로 되어 있어야 합니다.(아래 예를 볼 수 있습니다.) 



Data

  인텐트와 함께 조합된 데이터의 세부사항


  액티비티의 인텐트 필터안에 <data> 요소를 통해 지정합니다. 이 요소안에 하나 또는 그 이상의 속성을 사용합니다. 여러분은 단지MIME타입만 저장하거나, URI 스키마 하나만 지정할 수도 있고, 또는 이것들과 허용되는 data 타입을 나타내는 다른 것들과 조합하여 지정할 수 있습니다.


Note : 만약 여러분이 Uri 데이터에 대해 세부사항을 선언할 필요가 없다면( 여러분의 액티비티가 URI를 대신해서 다른 종류의 "extra" 데이터를 처리할 때와 같이), 여러분은 text/plain 또는 image/jpeg 과 같이 여러분의 액티비티가 처리할 data의 타입을 선언하기 위해 오직android:mimeType 속성만을 지정하셔야만 합니다.



Category

   보통 사용자 제스쳐 또는 시작된 것으로 부터의 위치에 관련된 Intent 를 처리하는 액티비티를 특정하기 위해 추가적인 방법을 제공합니다. 시스템에 의해 지원되어지는 서로 다른 다양한 카테고리가 있습니다. 하지만 대부분은 드물게 사용되어 집니다. 어쨋든, 모든 묵시적(implicit) 인텐트(Intent)들은 디폴트로 CAREGORY_DEFAULT로 정의되어 집니다.


 액티비티의 인텐트 필터안에 <category> 요소를 통해 지정합니다.



인텐트 필터안에서, 여러분은 <intent-filter>요소에 자리한 해당 XML 요소와 그들 각각을 선언하여 액티비티가 허용하는 기준을 선언할 수 있습니다. 


예를들어 보겠습니다. 아래는 text 또는 image의 data 타입일 때 ACTION_SEND 인텐트를 처리하는 인텐트 필터를 가진 액티비티의 예가 있습니다.

 <activity android:name="ShareActivity">

    <intent-filter>

        <action android:name="android.intent.action.SEND"/>

        <category android:name="android.intent.category.DEFAULT"/>

        <data android:mimeType="text/plain"/>

        <data android:mimeType="image/*"/>

    </intent-filter>

</activity>


각각의 들어오는 인텐트는 오직 하나의 action 과 하나의 data 타입을 지정합니다. 하지만 각각의 <intent-filter>요소안에는 <action>,<category>, 그리고 <data> 요소의 인스턴스를 여러개 선언해도 OK 입니다.


만약 action과 data로 된 2개의 쌍이 상호 배타적으로 동작한다면, 여러분은 data 타입에 부합되는 action 을 받아들일 수 있도록 지정하기 위해 별도로 구분된 인텐트 필터를 만들어야만 합니다.


예를 들어, 여러분의 액티비티가 ACTION_SEND 와 ACTION_SENDTO 인텐트 모두에서 text 와 image 를 모두 처리하도록 처리할 수 있도록 지원할 수 있습니다. 이런 경우, 여러분은 반드시 2개의 action 에 대해 별개의 구분된 인텐트 필터(Intent filter)를 정의해야만 합니다. 왜냐하면, ACTION_SENDTO 인텐트는 send 와 sendto URI 스키마(scheme)의 수신자 주소를 지정하는데 반드시 Uri data 를 사용해야만 하기 때문입니다. 예:

 <activity android:name="ShareActivity">

    <!-- filter for sending text; accepts SENDTO action with sms URI schemes -->

    <intent-filter>

        <action android:name="android.intent.action.SENDTO"/>

        <category android:name="android.intent.category.DEFAULT"/>

        <data android:scheme="sms" />

        <data android:scheme="smsto" />

    </intent-filter>


    <!-- filter for sending text or images; accepts SEND action and text or image data -->

    <intent-filter>

        <action android:name="android.intent.action.SEND"/>

        <category android:name="android.intent.category.DEFAULT"/>

        <data android:mimeType="image/*"/>

        <data android:mimeType="text/plain"/>

    </intent-filter>

</activity>

Note : 묵시적(implicit) 인텐트를 수신하기 위해서는, 반드시 인텐트 필터(Intent filter)안에 category 로 CATEGORY_DEFAULT 를 포함해야만 합니다. 카테고리에 CATEGORY_DEFAULT 로 선언함으로서 startActivity()  startActivityForResult() 메소드들은 선언된 인텐트들을 처리합니다. 만약 여러분이 인텐트필터안에 이 것을 선언하지 않는다면 묵시적 인텐트는 여러분의 액티비티를 처리하지 않을 겁니다.


소셜(social) 공유를 작업을 수행하기 위한 ACTION_SEND 인텐트를 전송하고 수신받는 것에 대한 추가 정보를 알고싶다면 개발자 사이트의 Receiving Simple Data from Other Apps 를 참조하시기 바랍니다.




액티비티에서 Intent 처리하기 (Handle the Intent in Your Activity)

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

여러분의 액티비티가 가지고 있는 action 이 무엇인지 결정하기 위해서 여러분은 액티비티를 시작하는데 사용한 Intent 객체를 읽을 수 있습니다.


여러분의 액티비티가 시작됨으로서, 액티비트를 실행시킨 Intent 객체를 복구하기 위해 getIntent() 메소드를 호출합니다. 여러분은 액티비티의 라이프사이클(lifecycle) 동안 어떤 순간에서든 이 작업을 할 수 있습니다. 하지만 일반적으로는 onCreate() 또는 onStart() 와 같이 콜백메소드 중에 가장 빨리 호출되는 메소드안에서 이 작업을 하는 것이 좋습니다.


예:

 @Override

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);


    setContentView(R.layout.main);


    // Get the intent that started this activity

    Intent intent = getIntent();

    Uri data = intent.getData();


    // Figure out what to do based on the intent type

    if (intent.getType().indexOf("image/") != -1) {

        // Handle intents with image data ...

    } else if (intent.getType().equals("text/plain")) {

        // Handle intents with text ...

    }

}



결과 리턴하기(Return a Result)

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

만약 여러분의 액티비티를 발동시킨 액티비티로 결과(result)를 리턴하길 원한다면, 간단하게 setResult() 메소드를 호출하여 결과코드(result code) 와 결과 인텐트(result Intent) 를 지정할 수 있습니다. 액티비티가 여러분의 명령을 끝마쳤거나 사용자가 원래의 액티비티로 되돌아가길 원할 때, finish() 메소들를 호출하여 여러분의 액티비티를 정지(그리고 파괴Destroy) 시킵니다. 예:

 // Create intent to deliver some kind of result data

 Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");

 setResult(Activity.RESULT_OK, result);

 finish();


여러분은 항상 결과(result)와 함께 결과코드(result code)를 지정해야만 합니다. 일반적으로 RESULT_OK 이거나 RESULT_CANCEL 을 사용합니다. 여러분은 필요하다면 Intent 안에 data를 추가적으로 제공할 수 있습니다.


Note : 결과(result)는 기본적으로 RESULT_CANCEL로 설정되어 있습니다. 그래서 action 을 완료하기 전에 사용자가 'Back' 버튼을 눌러서 결과(result)를 설정하기 전이라면 원래의 오리지널 액티비티는 "canceled" 결과를 받게 됩니다.


만약 다양한 결과(result) 옵션중 하나을 나타내는 정수형(integer) 결과를 리턴할 필요가 있다면, 여러분은 0 보다 큰 값으로 결과코드(result code)를 설정할 수 있습니다. 만약 여러분이 하나의 정수형(integer)를 전달하기 위해 result code 를 사용한다면 여러분은 Intent를 포함할 필요가 없습니다. 여러분은 setResult() 메소드를 호출하며 오직 result code 만 전달할 수 잇습니다. 예:


 setResult(RESULT_COLOR_RED);

 finish();


Note : 여러분은 여러분의 액티비티가 startActivity() 로 실행된건지 startActivityForResult()로 실행된건지 체크할 필요가 없습니다. 인텐트에 의해 시작된 여러분의 액티비티가 결과(result)를 기대한다면 간단하게 setResult()를 호출합니다. 만약 원래의 액티비티가startActivityforResult()를 호출햇다면, 시스템은 setResult()로 제공한 결과(result)를 전달할겁니다. 만약 그렇지 않다면 그 result는 무시될 겁니다.

반응형
반응형

 다른 액티비티를 실행하는 것은 한가지 방법만 있는 것은 아닙니다. 여러분은 다른 액티비티를 실행하고 그 액티비티로부터 결과를 되돌려 받을 수도 있습니다. 결과를 받기 위해서는 startActivity() 를 대신해서 startActivityForResult() 메소드로 다른 액티비티를 실행해야 합니다.


 예를 들어보면, 여러분의 앱이 카메라 앱을 실행해서 촬영된 사진을 결과로 받을 수 있습니다. 또는 사용자가 연락처를 선택하기 위해People App( 예전 버전에서의 연락처 앱)을 실행하고 그 결과로 연락처의 상세내역을 받도록 할 수도 있습니다.


 물론, 응답하도록 되어 있는 액티비티는 반드시 결과(Result)를 리턴하도록 디자인 되어 있어야 합니다. 그렇게 되어 있을 때, 그 앱은 또다른 Intent 객체를 이용해서 결과를 보내줍니다. 여러분의 액티비티는 리턴된 결과를 onActivityResult() 콜백(callback) 메소드를 통해 받을 수 있습니다.


Note : 여러분은 startActivityForResult() 메소드를 호출할 때 명시적(explicit) 인텐트 또는 묵시적(implicit) 인텐트를 사용할 수 있습니다. 결과를 받기 위해 여러분의 앱안에 있는 액티비티들 중 하나를 실행할 경우에는 여러분이 기대하는 결과를 받을 수 있도록 보장하기 위해 명시적(explicit) 인텐트(intent)를 사용하는 것이 좋습니다.




액티비티 시작 (Start the Activity)

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

 결과(result)를 받기 위해 액티비티를 실행할 때 사용하는 Intent 객체는 특별할 것이 없습니다. 다만 startActivityForResult() 메소들 호출할 때 정수형(integer) 매개변수를 추가적으로 전달할 필요가 있습니다.


이 정수형(integer) 인자는 "요청코드(request code)"로서 여러분의 요청을 식별하는 용도입니다. 여러분이 결과(result) 인텐트(Intent)를 받을 때, onActivityResult() 콜백(callback) 메소드는 여러분이 결과 액티비티를 호출할 때 전달했던 것과 같은 요청코드(request code)를 제공합니다. 이로 인해서 여러분의 앱은 그 결과가 적절한 것인지 확인할 수 있고 그 것을 어떻게 처리할 것인지 결정할 수 있습니다.


아래는 사용자가 연락처를 선택하고 얻어오도록 하는 액티비티를 실행하는 방법의 예제입니다.

 static final int PICK_CONTACT_REQUEST = 1;  // The request code

 ...

 private void pickContact() {

     Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));

     pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers

     startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);

 }

 



결과 받기 (Receive the Result)

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

 사용자가 다음 액티비티을 수행하고 다시 현재 액티비티로 되돌아 왔을 때, 시스템은 여러분의 액티비티의 onActivityResult() 메소드를 자동으로 호출합니다. 이 메소드는 3개의 인자(argument)를 포함하고 있습니다.


° startActivityForResult() 메소드를 호출할 때 전달했던 요청코드(request code)

° 두번째 액티비티에 의해 지정되어지는 결과코드(result code). 이 코드는 명령이 성공했을 때의 RESULT_OK 와 어떤 이유에 의해 명령이 실패하거나 사용자가 뒤로가기(back)을 통해 되돌아 올때의 RESULT_CANCELED 가 있을 수 있습니다.

° 결과(result) 데이터를 가지고 있는 Intent 객체


아래는 "연락처 얻기" 인텐트(Intent)에 대한 결과를 처리할 수 있는 방법에 대한 예제입니다.

 @Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    // Check which request we're responding to

    if (requestCode == PICK_CONTACT_REQUEST) {

        // Make sure the request was successful

        if (resultCode == RESULT_OK) {

            // The user picked a contact.

            // The Intent's data Uri identifies which contact was selected.


            // Do something with the contact here (bigger example below)

        }

    }

}

이 예제에서, Android의 연락처 앱(Contract 또는 People)에 의해 리턴된 결과(resultIntent 는 사용자가 선택한 연락처를 식별하는Content  Uri 객체를 제공합니다.


 이 결과(Result)를 성공적으로 처리하기 위해서는, 여러분은 반드시 결과가 될 Intent 의 형식이 무엇인지 이해하고 있어야 합니다. 여러분의 앱이 가지고 있는 액티비티들 중 하나로부터 결과를 되돌려 받을 때는 그 결과를 이해하는 것이 쉽습니다. 앱들은 Android 플랫폼이 특정 결과 데이터를 기대할 수있는 그들의 API 들을 포함하고 있습니다. 예를 들어, 연락처 앱(People) 앱은 항상 선택된 연락처를 식별할 수 있는 Content  Uri 를 결과로 돌려줍니다. 그리고 카메라 앱 같은 경우에는 Intent의 extra "data" 안에 Bitmap 객체를 리턴합니다(개발자 사이트의 Capturing Photos 에 대한 클래스를 참고하세요).



추가설명 : 연락처 데이터 읽기 ( Bonus : Read the contact data )

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

 People 앱으로부터 결과를 받기 위한 방법을 보여주는 위의 코드는 결과(result)로부터 실제 데이터를 읽어들이는 방법에 대해서는 세부적으로서 소개하고 있지는 않습니다. 왜냐하면, 이 작업을 하려면 Content Provider 에대한 좀더 향샹된 설명이 요구되기 때문입니다. 어쨋든, 만약 여러분이 이에 대해 관심이 있다면, 아래의 코드를 보시기 바랍니다. 아래의 몇가지 추가된 코드는 선택된 연락처로부터 전화번호를 얻기위해 결과 데이터(result data)를 요청하는 방법을 보여주고 있습니다.

 @Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    // Check which request it is that we're responding to

    if (requestCode == PICK_CONTACT_REQUEST) {

        // Make sure the request was successful

        if (resultCode == RESULT_OK) {

            // Get the URI that points to the selected contact

            Uri contactUri = data.getData();

            // We only need the NUMBER column, because there will be only one row in the result

            String[] projection = {Phone.NUMBER};


            // Perform the query on the contact to get the NUMBER column

            // We don't need a selection or sort order (there's only one result for the given URI)

            // CAUTION: The query() method should be called from a separate thread to avoid blocking

            // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)

            // Consider using CursorLoader to perform the query.

            Cursor cursor = getContentResolver()

                    .query(contactUri, projection, null, null, null);

            cursor.moveToFirst();


            // Retrieve the phone number from the NUMBER column

            int column = cursor.getColumnIndex(Phone.NUMBER);

            String number = cursor.getString(column);


            // Do something with the phone number...

        }

    }

}


Note : Android 2.3( API level 9) 이전에는 Contacts Provider 의 요청을 수행하기위해(위에 보여젔던 것과 같이) 여러분의 앱에READ_CONTACTS 퍼미션(permission) 을 선언하도록 요구했었습니다. 어쨋든, Android 2.3 부터는 Contacts/People 에 대해 여러분이 하나의 결과를 리턴할 때 Contacts Provider 로부터 읽어들일 수 있는 임시 퍼미션을 여러분의 앱에 허가합니다. 임시 퍼미션은 오직 요청된 특정 연락처(contact) 만을 제공합니다. 그래서 여러분은 READ_CONTACTS 퍼미션 선언 없이 intent 의 Uri에 의해 지정된 하나 이상의 연락처를 요청할 수 없습니다.

반응형
반응형

이 앱은 자바언어를 학습하실 때 해봤던 소켓통신을 안드로이드에 적용한 예제입니다. 

소켓통신으로 단말기 끼리 1:1 채팅을 하는 예제로 서로 간단한 메세지를 주고받는 정도만 가능합니다.

정식 채팅 앱은 나중에 따로 포스트 할 예정입니다.


 한 대는 서버로 동작하고 한 대는 클라이언트가 되는 앱입니다. 서로 역할을 바꿀 수도 있습니다.


우선 단말기 간 테스트를 할 수 있도록 Genymotion의 에뮬레이터를 2대 준비합니다. 



프로그램을 Run 시킬때 아래처럼 연결되어 있는 디바이스가 2개 보이셔야 합니다.(각 단말기의 IP번호도 확인가능합니다.)




아래 소개될 소스코드를 2번 Run 해서 각각의 에뮬레이터에 동일한 앱을 설치합니다.


서버 (ip주소 : 192.168.0.101)

 

























클라이언트(ip주소 : 192.168.0.102)

 

























동일한 앱을 설치한 2대의 에뮬레이터를 각 각 서버와 클라이언트로 접속합니다.

그러면 서버 액티비티 화면과 클라이언트 액티비티 화면으로 전환합니다.


  서버

















 클라이언트




 서버와 클라이언트가 준비되면 먼저 서버쪽 부터 START 버튼을 클릭해서 서버를 구축합니다. 에러가 발생하지 않으면 잘 만들어진 겁니다. 서버에 에러가 없었다면 클라이언트쪽의 CONNECT SERVER 버튼을 클릭해서 서버에 접속합니다. 아래의 EditText 의 IP주소를 변경해서 서버의 역할을 바꿀 수도 있습니다.


서버 구축                                                서버에 접속

       






 에러가 없다면 접속이 잘 된 것입니다. 이제 각 각의 EditText View에 원하는 메세지를 작성하고 SEND 버튼을 클릭하면 서로에게 메세지가 전달되는 것을 확인할 수 있습니다.


 



 


















            








































Main 화면 Layout 파일

 activity_main.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="${relativePackage}.${activityClass}" >


    <Button

        android:id="@+id/btn_server"

        android:layout_width="200dp"

        android:layout_height="50dp"

        android:layout_centerHorizontal="true"

        android:layout_marginTop="200dp"

        android:gravity="center"

        android:text="Server"

        android:textSize="25sp"

        android:onClick="mOnClick"/>

    

    <Button

        android:id="@+id/btn_client"

        android:layout_width="200dp"

        android:layout_height="50dp"

        android:layout_centerHorizontal="true"

        android:layout_alignParentBottom="true"

        android:layout_marginBottom="200dp"

        android:gravity="center"

        android:text="Client"

        android:textSize="25sp"

        android:onClick="mOnClick"/>


</RelativeLayout>



Main 화면 소스파일

 

 MainActivity.java

public class MainActivity extends Activity {


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

//Button을 클릭했을 때 호출되는 callback 메소드

public void mOnClick(View v){

Intent i;

switch(v.getId()){

case R.id.btn_server: //서버 화면

i= new Intent(this, ServerActivity.class);

startActivity(i);

break;

case R.id.btn_client: //클라이언트 화면

i= new Intent(this, ClientActivity.class);

startActivity(i);

break;

}

}

}






Server 화면 Layout 파일

 activity_server.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:gravity="start"

    tools:context="${relativePackage}.${activityClass}" >


    <Button android:id="@+id/btn_start_server"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerHorizontal="true"

        android:layout_marginTop="20dp"

        android:text="START"

        android:textStyle="bold"

        android:onClick="mOnClick"/>

    

    <TextView android:id="@+id/label_message_from_client" 

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_below="@id/btn_start_server"

        android:gravity="center"

        android:text="The Message from the client"

        android:textSize="20sp"

        android:textStyle="bold"

        android:textColor="#000000"

        android:layout_marginTop="50dp"/>

    

    <TextView android:id="@+id/text_massage_from_client"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_below="@id/label_message_from_client"

        android:text="text"

        android:gravity="center"

        android:layout_marginTop="20dp"/>

    

    <TextView android:id="@+id/label_message_to_client" 

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_below="@id/text_massage_from_client"

        android:gravity="center"

        android:text="The Message to the client"

        android:textSize="20sp"

        android:textStyle="bold"

        android:textColor="#000000"

        android:layout_marginTop="50dp"/>

    

    <EditText android:id="@+id/edit_message_to_client"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerHorizontal="true"

        android:layout_below="@id/label_message_to_client"

        android:layout_marginTop="20sp"

        android:gravity="center"

        android:hint="Enter the message"/>

    

    <Button android:id="@+id/btn_send_server"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerHorizontal="true"

        android:layout_below="@id/edit_message_to_client"

        android:layout_marginTop="50dp"

        android:text="SEND"

        android:onClick="mOnClick"/>


</RelativeLayout>



Server 화면 소스파일

 

 ServerActivity.java

public class ServerActivity extends Activity {

static final int PORT=10001;

ServerSocket serversocket;

Socket socket;

DataInputStream is;

DataOutputStream os;

TextView text_msg; //클라이언트로부터 받을 메세지를 표시하는 TextView

EditText edit_msg; //클라이언트로 전송할 메세지를 작성하는 EditText

String msg="";

boolean isConnected=true;


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_server);

text_msg= (TextView)findViewById(R.id.text_massage_from_client);

edit_msg= (EditText)findViewById(R.id.edit_message_to_client);

}

//Button 클릭시 자동으로 호출되는 callback 메소드

public void mOnClick(View v){

switch(v.getId()){

case R.id.btn_start_server: //채팅 서버 구축 및 클라이언트로 부터 메세지 받기

//Android API14버전이상 부터 네트워크 작업은 무조건 별도의 Thread에서 실행 해야함.

new Thread(new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

try {

//서버소켓 생성.

serversocket=new ServerSocket(PORT);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

try {

      //서버에 접속하는 클라이언트 소켓 얻어오기(클라이언트가 접속하면 클라이언트 소켓 리턴)

socket= serversocket.accept(); //서버는 클라이언트가 접속할 때까지 여기서 대기...

//여기 까지 왔다는 것은 클라이언트가 접속했다는 것을 의미하므로

//클라이언트와 데이터를 주고 받기 위한 통로구축..

is= new DataInputStream(socket.getInputStream()); //클라이언트로 부터 메세지를 받기 위한 통로

os= new DataOutputStream(socket.getOutputStream()); //클라이언트로 메세지를 보내기 위한 통로

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

//클라이언트가 접속을 끊을 때까지 무한반복하면서 클라이언트의 메세지 수신

while(isConnected){

try {

​                                     //클라이언트로 부터 메세지가 전송되면 이를 UTF형식으로 읽어서 String 으로 리턴​

msg=is.readUTF(); 

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

//클라이언트로부터 읽어들인 메시지msg를 TextView에 출력..

//안드로이드는 오직 main Thread 만이 UI를 변경할 수 있기에

//네트워크 작업을 하는 이 Thread에서는 TextView의 글씨를 직접 변경할 수 없음.

//runOnUiThread()는 별도의 Thread가 main Thread에게 UI 작업을 요청하는 메소드임.

runOnUiThread(new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

text_msg.setText(msg);

}

});

/////////////////////////////////////////////////////////////////////////////

}//while..

}//run method...

}).start(); //Thread 실행..

break;

case R.id.btn_send_server: // 클라이언트로 메세지 전송하기.

if(os==null) return; //클라이언트와 연결되어 있지 않다면 전송불가..

//네트워크 작업이므로 Thread 생성

new Thread(new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

//클라이언트로 보낼 메세지 EditText로 부터 얻어오기

String msg= edit_msg.getText().toString();

try {

os.writeUTF(msg); //클라이언트로 메세지 보내기.UTF 방식으로(한글 전송가능...)

os.flush();   //다음 메세지 전송을 위해 연결통로의 버퍼를 지워주는 메소드..    

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}).start(); //Thread 실행..

break;

}

}

}

   



 

Client 화면 Layout 파일

 activity_client.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="${relativePackage}.${activityClass}" >


    <Button android:id="@+id/btn_connectserver"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerHorizontal="true"

        android:layout_marginTop="20dp"

        android:text="CONNECT SERVER"

        android:textStyle="bold"

        android:onClick="mOnClick"/>

    

    <TextView android:id="@+id/label_message_from_server" 

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_below="@id/btn_connectserver"

        android:gravity="center"

        android:text="The Message from the server"

        android:textSize="20sp"

        android:textStyle="bold"

        android:textColor="#000000"

        android:layout_marginTop="50dp"/>

    

    <TextView android:id="@+id/text_massage_from_server"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_below="@id/label_message_from_server"

        android:text="text"

        android:gravity="center"

        android:layout_marginTop="20dp"/>

    

    <TextView android:id="@+id/label_message_to_server" 

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_below="@id/text_massage_from_server"

        android:gravity="center"

        android:text="The Message to the server"

        android:textSize="20sp"

        android:textStyle="bold"

        android:textColor="#000000"

        android:layout_marginTop="50dp"/>

    

    <EditText android:id="@+id/edit_message_to_server"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerHorizontal="true"

        android:layout_below="@id/label_message_to_server"

        android:layout_marginTop="20sp"

        android:gravity="center"

        android:hint="Enter the message"/>

    

    <Button android:id="@+id/btn_send_client"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerHorizontal="true"

        android:layout_below="@id/edit_message_to_server"

        android:layout_marginTop="50dp"

        android:text="SEND"

        android:onClick="mOnClick"/>

    

    <EditText android:id="@+id/edit_addressofserver"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:hint="Enter the address of server"

        android:layout_alignParentBottom="true"

        android:layout_marginBottom="20dp"

        android:gravity="center"/>


</RelativeLayout>



Client 화면 소스파일

 

 ClientActivity.java

public class ClientActivity extends Activity {

private static final int PORT = 10001; //서버에서 설정한 PORT 번호

String ip="192.168.56.101"; //서버 단말기의 IP주소..

//본 예제는 Genymotion 에뮬레이터 2대로 테스한 예제입니다.

//Genymotion을 실행하면 각 에뮬레이터의 IP를 확인할 수 있습니다.

Socket socket;     //클라이언트의 소켓

DataInputStream is;

DataOutputStream os;

TextView text_msg;  //서버로 부터 받은 메세지를 보여주는 TextView

EditText edit_msg;  //서버로 전송할 메세지를 작성하는 EditText

EditText edit_ip;   //서버의 IP를 작성할 수 있는 EditText

String msg="";

boolean isConnected=true;


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_client);

text_msg=(TextView)findViewById(R.id.text_massage_from_server);

edit_msg=(EditText)findViewById(R.id.edit_message_to_server);

edit_ip=(EditText)findViewById(R.id.edit_addressofserver);

edit_ip.setText(ip);

}

//Button 클릭시 자동으로 호출되는 callback 메소드

public void mOnClick(View v){

switch(v.getId()){

case R.id.btn_connectserver://서버에 접속하고 서버로 부터 메세지 수신하기

//Android API14버전이상 부터 네트워크 작업은 무조건 별도의 Thread에서 실행 해야함.

new Thread(new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

try {

ip= edit_ip.getText().toString();//IP 주소가 작성되어 있는 EditText에서 서버 IP 얻어오기

//서버와 연결하는 소켓 생성..

socket= new Socket(InetAddress.getByName(ip), PORT );

//여기까지 왔다는 것을 예외가 발생하지 않았다는 것이므로 소켓 연결 성공..

//서버와 메세지를 주고받을 통로 구축

is=new DataInputStream(socket.getInputStream());

os=new DataOutputStream(socket.getOutputStream());

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

//서버와 접속이 끊길 때까지 무한반복하면서 서버의 메세지 수신

while(true){

try {

msg= is.readUTF(); //서버 부터 메세지가 전송되면 이를 UTF형식으로 읽어서 String 으로 리

//서버로부터 읽어들인 메시지msg를 TextView에 출력..

//안드로이드는 오직 main Thread 만이 UI를 변경할 수 있기에

//네트워크 작업을 하는 이 Thread에서는 TextView의 글씨를 직접 변경할 수 없음.

//runOnUiThread()는 별도의 Thread가 main Thread에게 UI 작업을 요청하는 메소드임.

runOnUiThread(new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

text_msg.setText(msg);

}

});

//////////////////////////////////////////////////////////////////////////

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}//while

}//run method...

}).start();//Thread 실행..

break;

case R.id.btn_send_client: //서버로 메세지 전송하기...

if(os==null) return;   //서버와 연결되어 있지 않다면 전송불가..

//네트워크 작업이므로 Thread 생성

new Thread(new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

//서버로 보낼 메세지 EditText로 부터 얻어오기

String msg= edit_msg.getText().toString();

try {

os.writeUTF(msg);  //서버로 메세지 보내기.UTF 방식으로(한글 전송가능...)

os.flush();        //다음 메세지 전송을 위해 연결통로의 버퍼를 지워주는 메소드..

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}//run method..

}).start(); //Thread 실행..

break;

}

}

}

   



네트워크 사용하기 위해서는 사용 권한(uses-permission)이 필요합니다.

여러분 프로젝트의 메니페스트 파일에 퍼미션을 추가합니다.


 AndroidManifest.xml

 <manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.kitesoft.socket"

    android:versionCode="1"

    android:versionName="1.0" >


    <uses-sdk

        android:minSdkVersion="8"

        android:targetSdkVersion="16" />

    

    <!-- 네트워크 작업을 위한 permission -->

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


    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <activity

            android:name=".MainActivity"

            android:label="@string/app_name" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />


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

            </intent-filter>

        </activity>

        

        <activity

            android:name=".ServerActivity"

            android:label="@string/title_activity_server" >

        </activity>

        

        <activity

            android:name=".ClientActivity"

            android:label="@string/title_activity_client" >

        </activity>

        

    </application>


</manifest>

 

반응형
반응형

인텐트를 받을 앱이 있는지 확인하기(Verify There is an App to Receive the Intent)

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

비록 안드로이드 플랫폼이 여러분의 인텐트에 대해 내장된 앱(전화걸기, 이메일, 또는 달력 앱 등)중에서 하나가 확실하게 사용할 수 있다는 것을 보증하더라도, 여러분은 항상 인텐트를 발동하기 전에 인텐트에 대응하는 앱이 있는지 확인 단계를 포함하시는 것이 좋습니다.


Caution : 만약 인텐트가 발동 되었는데 디바이스(device)에 인텐트를 처리할 수 있는 앱이 없다면 여러분의 앱은 충돌을 일으킵니다.


 인텐트에 반응할 수 있는 액티비티가 있는지 확인하기 위해서 여러분은 queryIntentActivities() 메소드를 호출하여 그 Intent 를 처리하는 능력을 가진 액티비티들의 리스트(list)를 얻을 수 있습니다. 만약 이 메소드로부터 리턴된 List 인스턴스가 비어있지 않다면, 여러분은 안전하게 인텐트를 사용할 수 있습니다. 예:

 PackageManager packageManager = getPackageManager();

 List activities = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);

 boolean isIntentSafe = activities.size() > 0;


 만약 isIntentSafe 변수의 값이 true 면, 인텐트에 응답할 앱이 최소한 1개 이상이라는 것입니다. 만약 이 값이 false 라면, 그 인텐트를 처리할 어떤 앱도 없다는 것입니다.


Note :  사용자가 인텐트를 사용려고 하기 전에 이를 사용하는 기능을 해제 해야할 필요가 있는 경우에는 여러분의 액티비티가 처음 시작될 때 이 체크를 수행 해야 합니다. 만약 여러분이 인텐트를 처리할 특정 앱을 알고 있다면, 여러분은 또한 앱을 다운로드 하기 위한 사용자에 대해 링크(link)를 제공할 수 있습니다.( 개발자 사이트의 "link to your product on Google Play" 의 방법을 참고하세요)




Intent 로 Activity 실행하기 (Start an Activity with the Intent)

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

 여러분이 Intent 를 만들고 extra 정보를 설정했다면, startActivity() 메소들 호출해서 시스템에게 인텐트를 전송합니다. 만약 시스템이 그 인텐트를 처리 할 수 있는 액티비티들이 하나 이상으로 식별한다면, 그림 1에 보여진 것 처럼 사용자에게 어떤 앱을 사용할 것이지 선택하도록 하기위한 다이얼로그(dialog)를 표시합니다. 만약 인텐트를 처리할 수 있는 액티비티가 오직 하나라면 시스템은 즉시 그 앱을 실행합니다.

  startActivity(intent);



그림 1. 인텐트를 처리할 수 있는 앱이 하나 이상일때 나타나는 선택 다이얼로그의 예.



 아래는 지도보기를 위한 인텐트를 만드는 방법과 그 인텐트를 처리할 수 있는 앱이 존재하는지 확인하고 난후에 그 앱을 실행하는 완성된 예제입니다.

 // Build the intent

 Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");

 Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);


 // Verify it resolves

 PackageManager packageManager = getPackageManager();

 List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);

 boolean isIntentSafe = activities.size() > 0;


 // Start an activity if it's safe

 if (isIntentSafe) {

     startActivity(mapIntent);

 }




Chooser 앱 보여주기 (Show an App Chooser)

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

  위에서 설명했듯이 여러분이 startActivity()에 Intent를 전달해서 하나의 액티비티를 시작할 때 그 인텐트에 응답하는 앱이 하나 이상이면 어떤 앱을 사용할 지 선택하도록 하는데 이 때 여러분은 기본으로 실행될 앱을 선택할 수 있습니다.( 그림 1의 다이얼로그에서 아래 바닥에 있는 체크박스(checkbox)를 선택함으로서). 이 것은 웹 페이지(web page)를 열 때(사용자가 가능한 하나의 웹브라우져(web browser)를 사용한다고 가정하고) 또는 사진 촬영(사용자가 하나의 카메라를 선호한다고 가정하고)과 같이 , 하나의 액션을 수행할 때 사용자가 일반적으로 매 순간 같은 앱을 사용하도록 한다면 매우 좋은 방법입니다.


어쨋든, 만약 수행되어지는 action이 여러 앱들에서 처리되어지고 사용자가 매 순간 다른 앱을 선호할 수 도 있다면( 사용자가 하나의 아이템을 여러 앱들을 통해 공유할 수도 있는 "공유(share)" action 같은) 여러분은 그림 2에서 보여진 Chooser 다이얼로그(Chooser Dialog)를 명시적(explicit)으로 보이도록 하는 것이 좋습니다. Chooser Dialog는 사용자가 매 순간 action에 대해 어떤 앱을 사용할 지 선택할 수 있도록 합니다. (이 다이얼로그는 사용자가 action에 대한 기본 앱을 선택할 수 없습니다.)



 















그림 2. A Chooser Dialog



 Chooser를 보기 위해서는 createChooser() 메소드를 사용하여 Intent 만들고 startActivity()에 이 인텐트를 전달해야 합니다.

예:

 Intent intent = new Intent(Intent.ACTION_SEND);

 ...


 // Always use string resources for UI text.

 // This says something like "Share this photo with"

 String title = getResources().getString(R.string.chooser_title);

 // Create intent to show chooser

 Intent chooser = Intent.createChooser(intent, title);


 // Verify the intent will resolve to at least one activity

 if (intent.resolveActivity(getPackageManager()) != null) {

     startActivity(chooser);

 }


 Chooser는 createChooser() 메소드에 전달된 인텐트에 응답하는 앱의 목록을 다이얼로그에 표시합니다. 그리고 Dialog의 제목에는 제공되어진 Text 를 사용합니다.

반응형
반응형

 안드로이드의 가장 중요한 기능중 하나는 실행하기를 원하는 "action" 을 기반으로 다른 앱으로 사용자를 보내는 능력(다른 앱을 실행하는 능력)입니다. 예를 들어, 만약 여러분 앱이 지도에 보여주고 싶은 업체 주소를 가지고있는데, 여러분의 앱안에는 지도를 보여주는 액티비티가 없다면 이를 대신하여 여러분은 Intent를 사용하여 맵에 주소를 보여주도록 요청할 수 있습니다. 그렇게 하면 안드로이드 시스템은 맵 위에 해당 주소를 보여줄 수 있는 앱을 시작합니다.


 이 게시판의 첫번째 포스트 "첫번째 앱 만들기(Building Your First App)"에서 설명했듯이, 여러분은 여러분의 앱이 가지고 있는 액티비티들 사이를 이동하기 위해서는 Intent 를 사용해야만 합니다. 여러분은 일반적으로 여러분이 시작하기를 원하는 확실한 컴포넌트의 클래스 이름을 정의한 명시적(explicit) 인텐트를 통해 이 작업을 합니다. 어쨋든, 여러분이 "지도보기"와 같이 하나의 action을 수행하는 별도의 다른 앱을 실행하고자 한다면 여러분은 반드시 암시적(implicit) 인텐트를 사용해야만 합니다.


 이번 시간에는 여러분에게 특정 action 에 대한 암시적 인텐트를 만드는 방법과 다른 앱안에서 이 액션을 수행하는 액티비티를 실행하도록 이 인텐트를 사용하는 방법을 소개하도록 하겠습니다. 



암시적 인텐트 만들기 (Build an Implicit Intent)

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

암시적 인텐트는 시작될 컴포넌트의 클래스 이름을 선언하지 않습니다. 대신 실행 할 action을 선언합니다. action 은 무엇인가를 보여주고, 만들고, 전송하고, 얻어오는 등의 여러분이 동작하길 원하는 것을 지정합니다. Intent는 또한 여러분이 지도에 보여주길 원하는 주소, 또는 전송하고 싶은 이메일(email) 같은 action 과 조합된 데이터를 포함하고 있습니다. 이 데이터는 여러분이 만들기를 원하는 Intent에 따라, Uri 객체가 될수도 있고, 또 다른 다양한 데이터 타입 중 하나일 수도 있으며 또는 어떤 데이터도 필요하지 않을 수도있습니다.


만약 여러분의 데이터가 Uri 타입이라면, action 과 data 를 정의하는데 사용할 수 있는 간단한 Intent() 생성자(constructor)가 있습니다.


예들 들어보겠습니다. 아래는 전화 번호를 지정한 Uri 데이터를 사용하여 전화 걸기를 초기화하는 Intent를 만드는 방법을 보여주고 있습니다.

 Uri number = Uri.parse("tel:5551234");

 Intent callIntent = new Intent(Intent.ACTION_DIAL, number);

여러분의 앱이 startActivity() 메소드를 호출해서 이 인텐트를 발동시기면, 전화 앱이 시작되고 이 앱은 주어진 전화번호로 초기화합니다.


아래는 action 과 Uri data 쌍의 다른 인텐트들의 예입니다.


지도보기:

 // Map point based on address

 Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");

 // Or map point based on latitude/longitude

 // Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level

 Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);



웹뷰(WebView) 보기:

 Uri webpage = Uri.parse("http://www.android.com");

 Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);



 암시적(implicit) 인텐트의 다른 종류들은 String과 같이 다른 데이터 타입을 제공하는 "extra"데이터를 요구합니다. 여러분은 다양한putExtra() 메소드를 사용해서 하나 또는 그 이상의 extra 데이터 추가할 수 있습니다.



기본적으로 시스템은 포함된 Uri 를 기반으로 Intent에 의해 요구되는 적절한 MIME(Multipurpose Internet Mail Extensions) 타입을 결정합니다. 만약 여러분이 Intent 안에 Uri 을 포함시키지 않았다면, 일반적으로 인텐트와 조합된 데이터의 타입을 지정하기 위한setType() 메소드을 사용해야 합니다. MIME 타입을 설정하는 것은 나중에 인텐트를 받아야 하는 액티비티들의 종류를 지정하는 것입니다.



아래는 여러분이 원하는 action을 지정하기 위한 extra 데이터를 추가한 Intent 들의 몇가지 예시입니다.


첨부파일과 함께 이메일 보내기

 Intent emailIntent = new Intent(Intent.ACTION_SEND);

 // The intent does not have a URI, so declare the "text/plain" MIME type

 emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);

 emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients

 emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");

 emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");

 emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));

 // You can also attach multiple items by passing an ArrayList of Uris


달력(Calendar) 이벤트 생성하기

 Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);

 Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);

 Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);

 calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());

 calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());

 calendarIntent.putExtra(Events.TITLE, "Ninja class");

 calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");

Note : Calendar 이벤트에 대한 이 인텐트(intent)는 API 14 버전 이상에서만 제공되어집니다. 


Note : 가능한 명확하게 여러분의 Intent 를 정의하는 것을 중요합니다. 예를 들어, 만약 여러분이 ACTION_VIEW 인텐트를 사용하여 이미지를 보여주기를 원함다면 여러분은 image/* 로 MIME 타입을 지정하셔야만 합니다. 이것은 인텐트에 의해 앱이 시작될 때"view" 할 수 있는 다른 데이터 타입( 지도보기 처럼)의 앱이 실행되는 것을 방지합니다.

반응형
반응형

 안드로이드 앱은 일반적으로 다양한 액티비티들을 가지고 있습니다. 각각의 액티비티는 사용자가 특정 작업( 지도보기 또는 사진촬영 같은)을 수행시킬 수 있는 사용자 인터페이스(user Interface : UI )를 보여줍니다. 사용자가 하나의 액티비티에서 다른 액티비티로 전환하기 위해서는, 여러분은 반드시 무엇인가를 하려는 앱의 "의도(intent)" 를 정의하기 위해 Intent 클래스를 사용해야만 합니다.startActivity() 메소드를 통해 시스템에게 Intent를 전달할 때, 시스템은 적절한 앱 컴포넌트(component)를 식별하고 이를 시작하기 위해 Intent 인스턴스를 사용합니다. Intent를 사용하는 것은 심지어 별도의 다른 앱안에 포함되어 있는 액티비티도 시작하게 할 수 있습니다.


Intent 는 특정 컴포넌트를 지정하여 실행하도록 하는 명시적(explicit) 인텐트와 컴포넌트를 지정하지 않고 의도된 동작(마치 사진캡쳐와 같은)을 처리할 수 있는 어떤 컴포넌트를 적절히 실행하기 위한 암시적(implicit) 인텐트가 있습니다.


 이번 장에서는 여러분에게 다른 앱 실행하기, 앱으로부터 결과 받기, 여러분의 앱을 다른 앱으로부터의 Intent에 응답할 수 있도록 하는 등, 몇가지 다른앱과의 기본적인 상호작용을 수행하기 위해 Intent 를 사용하는 방법을 소개하도록 하겠습니다.


 

Lessons

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

다른 앱으로 사용자 보내기- 다른 앱 실행하기

(Sending the User to Another App)

  액션(action)을 수행할 수 있는 다른 앱을 시작하기 위한 암시적(implicit) 인텐트를 만드는 방법을 소개합니다. 


액티비티로부터 결과 얻어오기 (Getting a Result from an Activity)

  다른 앱을 실행하고 그 액티비티로 부터 결과(result)를 받는 방법을 소개합니다.


다른 앱들이 여러분의 앱을 실행하도록 하기 

(Allowing Other Apps to Start Your Activity)

  여러분의 앱이 암시적 인텐트를 받을 수 있도록 선언된 인텐트 필터(filter)를 정의함으로서 다른 앱에 의해 여러분의 앱안에 있는 액티비티를 열 수 있도록 만드는 방법을 소개합니다.

반응형

+ Recent posts