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

최근에 받은 트랙백

글 보관함



Lesson 3의 나머지 부분에서는 Intent에 대한 설명이 나옵니다.
Intent 는 다른 Activity를 실행시키는 명령어로 같은 앱 내의 Activity 이외에 다른 앱의 액티비티를 실행 시킬 수 있습니다.
그러니까 내 앱을 사용하다가 전화거는 서비스를 제공해야 하면 Intent를 사용해서 다른 전화거는 앱 즉 안드로이드 자체에 실려있는 전화거는 앱을 이 Intent를 사용해서 실행하면 됩니다
문자메세지, 바코드 스캐닝, 카메라 등등의 기능도 그냥 다른 앱을 불러서 사용하도록 하면 됩니다.

이 때 Intent를 사용하면 Activity의 정확한 이름 즉 클래스 이름을 제공하는데 다른 앱의 액티비티 클래스 이름을 알 수는 없습니다.
이럴 때 Implicit Intents를 사용할 수 있습니다.

안드로이드는 이 Implicit Intents에서 사용한 이름의 액티비티가 여러개 있을 때 그 중 하나를 선택할 수 있는 메뉴를 보여 줍니다.

실습을 해 보겠습니다.

지금까지 만든 일기예보 앱에 Map을 보여주는 기능을 추가 할 겁니다.
지도는 구글맵을 불러와서 해당 지역을 그 구글 맵에 표시하도록 할 겁니다.

우선 menu option을 추가해서 지도에 사용자가 정한 지역을 표시하도록 할 겁니다.


res-menu-main.xml 파일에 위와 같이 지도를 위한 메뉴 아이템을 추가 합니다.



그리고 MainActivity에 아래와 같이 openPreferredLocationInMap()을 추가 합니다.

    private void openPreferredLocationInMap() {
        SharedPreferences sharedPrefs =
                PreferenceManager.getDefaultSharedPreferences(this);
        String location = sharedPrefs.getString(
                getString(R.string.pref_location_key),
                getString(R.string.pref_location_default));

        // Using the URI scheme for showing a location found on a map.  This super-handy
        // intent can is detailed in the "Common Intents" page of Android's developer site:
        // http://developer.android.com/guide/components/intents-common.html#Maps
        Uri geoLocation = Uri.parse("geo:0,0?").buildUpon()
                .appendQueryParameter("q", location)
                .build();

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(geoLocation);

        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivity(intent);
        } else {
            Log.d(LOG_TAG, "Couldn't call " + location + ", no receiving apps installed!");
        }
    }


내용을 보면 SharedPreference를 불러오고 location 값을 get합니다.

그리고 URI에 이 location값을 넣어 줍니다.
우편번호로 지도상의 위도와 경도를 가져와서 URI에 넣어 줍니다.
이 부분을 자세히 보시려면 이곳에 가시면 됩니다.
http://developer.android.com/guide/components/intents-common.html#Maps

그리고 Intent에서 Intent.ACTION_VIEW 라는 Implicit Intent를 사용합니다.

그리고 이 intent에 Uri (위도와 경도가 있는)를 setting 합니다.
그러면 이 위도와 경도 정보를 Intent.ACTION_VIEW라는 액티비티로 넘겨 줄 준비가 돼어 있는 겁니다.

그리고 if 문에서 resolveActivity를 사용해서 이 Implicit Intent에 해당하는 액티비티가 있는 지 확인합니다.
있으면 startActivity를 하고 없으면 로그를 뿌려 줍니다.


그리고 나서  onOptionsItemSelected()에 아래와 같이 map 관련 부분을 추가 합니다.
 
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            startActivity(new Intent(this, SettingsActivity.class));
            return true;
        }

        if (id == R.id.action_map) {
            openPreferredLocationInMap();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

이제 Setting에서 Map Location을 누르면 해당 지역의 위도 경도가 구글맵 애플리케이션에 전달되서 구글맵 앱에 해당 지역 위치가 보일 겁니다.



참고로 Share Intent 에 대해 자세히 보려면 이곳으로 가면 됩니다.
https://developer.android.com/training/sharing/shareaction.html

Lesson 3의 다음 부분을 보면 Detail 화면에서 날씨를 Share 하거나 문자 메세지로 보내는 기능이 추가 됩니다.

이 때 Intent Share의 Share Provider를 사용합니다.


이 기능을 구현하는 순서는 우선 res-menu 에 detailfragment.xml을 아래와 같이 만듭니다.
여기서 ShareActionProvider를 사용했습니다.

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/action_share"
        android:title="@string/action_share"
        app:showAsAction="always"
        app:actionProviderClass="android.support.v7.widget.ShareActionProvider" />
</menu>

그 다음 DetailActivity 클래스로 갑니다.

그리고 나서 DetailFragment 클래스를 아래와 같이 업데이트 합니다.

   /**
     * A placeholder fragment containing a simple view.
     */
    public static class DetailFragment extends Fragment {

        private static final String LOG_TAG = DetailFragment.class.getSimpleName();

        private static final String FORECAST_SHARE_HASHTAG = " #SunshineApp";
        private String mForecastStr;

        public DetailFragment() {
            setHasOptionsMenu(true);
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {

            View rootView = inflater.inflate(R.layout.fragment_detail, container, false);

            // The detail Activity called via intent.  Inspect the intent for forecast data.
            Intent intent = getActivity().getIntent();
            if (intent != null && intent.hasExtra(Intent.EXTRA_TEXT)) {
                mForecastStr = intent.getStringExtra(Intent.EXTRA_TEXT);
                ((TextView) rootView.findViewById(R.id.detail_text))
                        .setText(mForecastStr);
            }

            return rootView;
        }

        @Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
            // Inflate the menu; this adds items to the action bar if it is present.
            inflater.inflate(R.menu.detailfragment, menu);

            // Retrieve the share menu item
            MenuItem menuItem = menu.findItem(R.id.action_share);

            // Get the provider and hold onto it to set/change the share intent.
            ShareActionProvider mShareActionProvider =
                    (ShareActionProvider) MenuItemCompat.getActionProvider(menuItem);

            // Attach an intent to this ShareActionProvider.  You can update this at any time,
            // like when the user selects a new piece of data they might like to share.
            if (mShareActionProvider != null ) {
                mShareActionProvider.setShareIntent(createShareForecastIntent());
            } else {
                Log.d(LOG_TAG, "Share Action Provider is null?");
            }
        }

        private Intent createShareForecastIntent() {
            Intent shareIntent = new Intent(Intent.ACTION_SEND);
            shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
            shareIntent.setType("text/plain");
            shareIntent.putExtra(Intent.EXTRA_TEXT,
                    mForecastStr + FORECAST_SHARE_HASHTAG);
            return shareIntent;
        }
    }
   
일단 onCreateView 에서 mForecastStr 라는 member variable 을 사용해서 text를 세팅했습니다.

그리고 createShareForecastIntent()를 만듭니다.
여기서는 문자메세지를 보내기 위해 필요한 세팅들을 합니다.
putExtra를 사용해서 내용을 추가하는데 그 내용은 해당 detail 페이지에 있는 날씨 정보 입니다.
그리고 이 shareIntent를 return 합니다.

이 클래스는 onCreateOptionsMenu에서 해당 아이콘이 클릭되면 호출 됩니다.

이제 Detail 화면에서 메세지 아이콘을 누르면 아래와 같이 문자메세지 앱이 실행됩니다.



그 이외에 Broadcast Intent 가 있습니다.

예를 들어 핸드폰이 충전되고 있는지를 Broadcast해 주는데요.  이 Broadcast되는 정보를 받아서 앱에서 활용할 수 있습니다.

ACTION_POWER_CONEECTED 이벤트를 사용하고 리시버는 Manifest Receiver를 사용해서 구현합니다.

자세한 내용은 이곳을 참고 하세요.

https://developer.android.com/reference/android/content/BroadcastReceiver.html



반응형

Comment

이전 1 2 3 4 5 6 7 8 9 ··· 46 다음