레이블이 Android인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Android인 게시물을 표시합니다. 모든 게시물 표시

2019년 5월 21일 화요일

[IONIC] 아이오닉으로 실행할때 필요했던 커맨드 명령어 모음.


  • 일단 개발 환경이 중요함.
    • MAC OS 10.14
    • XCODE 10.0
    • Android Studio 3.4.1

  • node.js 설치
    • $ brew install node

  • IONIC 설치
    • $ npm install -g cordova ionic

  • IONIC 샘플 앱 생성
    • $ ionic start myApp tabs

  • IONIC 아이폰 앱 빌드
    • 플랫폼 추가
      • $ ionic cordova platform add ios
    • 빌드
      • $ ionic build ios
    • 시뮬레이터 설치
      • $ npm install -g ios-sim
    • 앱 실행
      • $ ionic cordova  emulate ios
          

  • IONIC 안드로이드 앱 빌드
    • 플랫폼 추가
      • $ ionic cordova platform add android
    • 빌드
      • $ ionic build android
    • 앱 실행
      • $ ionic cordova emulate android
          
  • 아이폰 빌드 예외 해결용
    • xcode-select 설치
      • $ xcode-select --install
    • 10.14 버전 (Mojave) xcode-select 설정
      • $ sudo xcode-select -s /Applications/Xcode.app/Contents/Developer

  • 안드로이드 빌드 예외 해결용
    • 자바 1.8 설치 (1.8만 된다 -ㅁ-;;)
    • 자바 버전 확인
      • javac -version
    • 현재 자바 홈 확인
      • $ /usr/libexec/java_home -V
    • 자바가 여러개 깔렸을때 1.8을 홈으로 지정
      • $ export JAVA_HOME=`/usr/libexec/java_home -v 1.8`
    • Gradle 설치
      • $ brew install gradle
    • 빌드중에 라이선스 오류가 난다면...
      • Android Studio에서 해당 항목 업데이트
           
          
          
             
          

2018년 7월 24일 화요일

[Android] 안드로이드 tools:text에 샘플 텍스트 넣기

안드로이드 레이아웃을 잡을때 샘플 텍스트를 지정 할때가 있는데, 아래와 같은 녀석을 쓰면 편리 하다.

tools:text = "이런것 대신에..."

"@tools:sample/lorem/random" , "@tools:sample/full_names" , "@tools:sample/full_names" ,"@tools:sample/cities"

2012년 5월 8일 화요일

[안드로이드] 부팅시간? 켜진시간??


public static final String ACTION_BOOT_COMPLETED

안드로이드가 껐다 켜지면 위와 같은 액션을 브로드케스트 리시버를 달아 받을 수 있다.
하지만 피치 못할 사정으로 브로드케스트 리시버를 사용 할 수 없다면?

SystemClock에 다음과 같은 두 메쏘드가 있다.

static long elapsedRealtime()
딥슬립 시간을 포함한 부팅 후 경과한 시간을 밀리초 단위로 리턴함.

static long uptimeMillis()
딥슬립 시간을 제외한 부팅 후 경과한 시간을 밀리초 단위로 리턴함.

uptimeMillis()의 경우는 딥슬립 시간을 제외 하니 다른 용도로 써야겠고..
elapsedRealtime()을 쓰면 될듯 하다. System.currentTimeMillis() - elapsedRealtime()하면 부팅 시간이니 말이다.

가령 shared_prefernce 등에 시간을 저장해 두고
OnCreate()에서 그값을 읽어와 부팅시간과 비교해
값이 적다면 새로 부팅한거니 그에 따른 처리를 한뒤 shared_prefernce에 다시 값을 넣어 주고,
값이 더 크다면 아무 것도 하지 않으면 된다.

물론 BOOT_COMPLETED를 받아야만 하는 경우도 있겠지만, 단순히 우리 어플리케이션이 안드로이드가 부팅되고 처음 실행 되는 건지 아닌지 정도는 구분할수 있다.

2012년 4월 17일 화요일

[안드로이드] SD 마운트-탈착에 관한 인텐트



SD 카드에 관련한 작업을 하다보면 예외적인 상황을 고려하지 않을 수 없다. 작업중에 강제로 SD카드가 뽑히거나, USB 연결등으로 마운트 해제가 될수도 있기 때문이다. 그러한 경우 다행히 Broadcast가 날라 오므로 필요에 맞게 받아 처리 할 수 있다.
  • Intent.ACTION_MEDIA_MOUNTED
SD 카드가 마운트 되면 날라옴
  • Intent.ACTION_MEDIA_EJECT
SD 카드가 강제로 뽑히거나 유저가 마운트 해제 하였을때 날라옴
  • Intent.ACTION_MEDIA_UNMOUNTED
유저가 마운트 해제 하였을때 날라옴
  • Intent.ACTION_MEDIA_REMOVED
SD 카드가 장치에서 제거 되었을때 날라옴
  • Intent.ACTION_MEDIA_BAD_REMOVAL
유저가 마운트 해제 하지 않은체 SD 카드가 강제로 뽑혔을때 날라옴

실제로 SD카드를 강제로 뽑아 보면 다음 순으로 발생 함
Intent.ACTION_MEDIA_BAD_REMOVAL -> Intent.ACTION_MEDIA_EJECT

마운트 해제 하면 다음 순으로 발생함
Intent.ACTION_MEDIA_EJECT -> Intent.ACTION_MEDIA_UNMOUNTED

SD 카드를 새로 꼽으면 다음 순으로 발생함
Intent.ACTION_MEDIA_UNMOUNTED -> Intent.ACTION_MEDIA_MOUNTED
희안하게도 언마운트가 먼저 호출되니 처리시 주의가 필요함

참고로 위 인텐트들을 등록 할 때는 아래와 같이 Data scheme을 지정해 줘야 한다.
<receiver android:name=".TestBroadcastReceiver">
    <intent-filter>
        <action android:name="android.intent.action.MEDIA_EJECT" />
        <action android:name="android.intent.action.MEDIA_BAD_REMOVAL" />
        <action android:name="android.intent.action.MEDIA_MOUNTED" />
        <action android:name="android.intent.action.MEDIA_REMOVED" />
        <action android:name="android.intent.action.MEDIA_UNMOUNTED" />
        <data android:scheme="file"></data>
    </intent-filter>
</receiver> 

[안드로이드] 브로드케스트리시버 동적으로 등록/해지 하기

브로드케스트 인텐트를 받기 위해
보통 AndroidManifest.xml 파일에 리시버를 등록 하곤 한다.
이렇게 하면 해당 브로드케스트가 발생하면 항상 실행되게 되는데, 기능에 따라 On/Off 를 하고 싶을 경우가 있다.
뭐 그런 경우 브로드케스트 리시버에서 처리를 안해도 되지만 아예 꺼버린다면 여러모로 효율이 좋게된다.

* 먼저 브로드케스트 리시버를 등록 하는 법
// 인텐트 필터 생성
IntentFilter filter = new IntentFilter();
filter.addAction("com.hermina.broadcast.TEST");
// 브로드케스트 리시버 등록
registerReceiver(reciever, filter);
물론 reciever는 등록할 BroadcastReciever 이며
다룰 인텐트에 따라 필터를 좀더 명확 하게 설정할 수 있다.
filter.addCategory
filter.addDataType
filter.addDataScheme
* 해지 하는법
unregisterReceiver(reciever);

2012년 4월 3일 화요일

[안드로이드] 테마 적용 + 배경이 투명한 액티비티 만들기

안드로이드 ICS가 출시 되면서 Holo.Light 테마가 생겨 났다.
그러한 테마를 적용 하면서 투명 액티비티를 띄우면 투명 액티비티만 테마가 후리다;;;

인터넷에서 찾아 보면 투명 액티비티를 만드는 테마는 다음과 같다.
<activity android:name="Test" android:theme="@android:style/Theme.Translucent">
물론 잘 동작 한다.
하지만 위에서 적었듯이 투명 액티비티에서 보여지는 위젯들은 테마가 적용이 않된 후린 기본 스타일로 보여지게 된다.

내 경우 다이얼로그를 띄워야 하는데 다른 다이얼로그는 테마가 적용 됬는데 투명액티비티에서 띄우는 녀석만 미운오리새끼 같다.

그럼 어떻게 해야 하는가!!

일단 테마를 만듭니다.
project/res/values/themes.xml 을 추가 하면 된다.
다음과 같이 themes.xml파일의 내용을 체운다.
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="Translucent_Dialog" parent="@android:style/Theme.Holo.Light.Dialog.NoActionBar">
        <item name="android:windowBackground">@android:color/transparent</item>        
    </style>

</resources>
이미 themes.xml 파일이 있다면 style 항목만 추가 하면 되겠죠?

style 에서 "parent" 부분이 상속받을 스타일이고 "item" 으로 배경을 투명하게 지정 한것이다.
사실 "@android:style/Theme.Holo.Light.Dialog.NoActionBar" 테마는 투명액티비티에 필요한 "NoActionBar"라던가 "Dialog"라던가 하는 스타일이 거의 지정 되어 있다.
현재 사용하는 테마 스타일이 다른것이라면 아래와 같은 속성을 추가해 타이틀과 액션바를 없애줘야 할 것 이다.
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
테마가 적용된 투명한 새로운 테마를 생성하였으면 이를 액티비티에 적용해 줘야 한다.
"AndroidManifest.xml" 파일을 열어 투명효과를 적용할 액티비티에 다음과 같이 테마를 지정해 준다.
<activity
    android:name=".TrasparentTestActivity"
    android:label="@string/app_name"
    android:theme="@style/Translucent_Dialog" >
이렇게 하면 투명한 액티비티 생성 완료~

2012년 3월 22일 목요일

[안드로이드] 사용자 정의 permission의 선언

------------ 요기는 삽질 내용입니다. permission의 선언법만 궁금하시면 넘어가세요.
간단한  ContentProvider를 테스트 하기 위해 샘플 프로젝트를 만들어 보았다. 액티비티 하나,  ContentProvider  하나. 이 App를 CPTestApp1 이라 명명해 보았다.

<provider
            android:name="TestContentProvider"
            android:authorities="com.hermina.testcontent">
</provider>


잘동작한다.

이번엔 신규 App CPTestApp2를 생성해 CPTestApp1에서 만든  ContentProvider를 사용해 보기로 하였다.
뭐 잘 된다.

이번엔 CPTestApp1의 ContentProvider에 permission을 지정 해 보았다. 기왕 하는거 퍼미션명도 다르게 지정해 보았다.

<provider
            android:name="TestContentProvider"
            android:authorities="com.hermina.testcontent"
            android:readPermission="com.hermina.permission.CP_READ" >
</provider>



그리고 나서 CPTestApp2에 해당 권한을 넣어 준다.
<uses-permission android:name="com.hermina.permission.CP_READ"/>

젠장 이번엔 안된다.
"com.hermina.testcontent"에 접근 하려면 "com.hermina.permission.CP_READ"권한이 있어야 한다는데...

이쯤에서 인터넷 검색해보고 별짓 다해봤다. ContentProvider에 관련된 자료와 책을 보고 또보고 다른 소스 코드들을 열심히 보았지만 이유를 몰랐다.
그러던중 <permission android:name="xxx.xxxxxx.xxxxx" /> 를 발견하게되고...
분을 삭힐수 있게 되었는데...
어릴땐 책을 사면 아까워서 글자 한톨 그림 구석구석 정독을 했었다. 하지만 언제부턴가 책을 사도 빠르게 필요한 부분만 뽑아 보게 되었다. 내가 만약 안드로이드 permission에 관해 먼저 자세히 알고 있었다면 이런 한심한 삽질은 하지 않았으랴...

------------ 본론입니다.
안드로이드에서 사용자 정의 퍼미션을 선언하는 방법은 다음과 같다.

<receiver android:name=".NewPhotoReceiver">

컨텐트 프로바이더에서 해당 퍼미션을 사용 하려면 다음과 같이 하면 되고

<provider
            android:name="TestContentProvider"
            android:authorities="com.hermina.testcontent"
            android:readPermission=" xxx.xxxxxx.xxxxx " >
</provider>


이를 사용 하는 어플리케이션에서 해당퍼미션을 허용하려면

<uses-permission android:name=" xxx.xxxxxx.xxxxx "/>

처럼 사용 하면 된다.

2012년 3월 20일 화요일

[안드로이드] Broadcast - 카메라로 사진을 찍을 경우 발생하는 인텐트



카메라에서 사진을 찍으면 com.android.camera.NEW_PICTURE 라는 브로드 케스트가 생성 된다.
이걸 처리하는 인텐트 필터를 선언 하고 브로드 케스트 리시버를 만들어 주면 사진이 찍힐때 마다 하고자 하는 일을 할 수 있게 된다.

* XML 선언 예
<receiver android:name=".NewPhotoReceiver">
<intent-filter>
<action android:name="com.android.camera.NEW_PICTURE" />
<data android:mimeType="image/*"/>
</intent-filter>
</receiver>

* 브로드케스트리시버 샘플
public class NewPhotoReceiver extends BroadcastReceiver
{
 @Override
 public void onReceive(Context context, Intent intent) {
  Log.d("Test", "START OF NewPhotoReceiver");
  
  Uri uri = intent.getData();
  
  Toast.makeText(context, "Photo taken - " + uri, Toast.LENGTH_SHORT).show();
  
  Log.d("Test", "[onReceive] URI - " + uri);
 }
}

[안드로이드] animation 리소스의 특정 프레임을 Bitmap으로 바꾸는 법

android.R.drawable.stat_sys_upload
이녀석은 움직이는 이미지다.
따라서 다음과 같이 하면 null값이 리턴되는데...
Resources res = ctx.getResources();
Bitmap bmpOneFrame = BitmapFactory.decodeResource(res, 
                                                android.R.drawable.stat_sys_upload);
그럼 움직이는 이미지의 특정 프레임을 Bitmap으로 얻어 오려면 어떻게 해야 할까?

1. 먼저 움직이는 이미지의 리소스 ID로 AnimationDrawable을 얻어 온다.
2. AnimationDrawabled의 특정 프레임을 Drawable로 얻어온다.
3. Drawable을 Bitmap으로 변환 한다.

이것을 코드로 나타내면,

public static Bitmap getFrameToBitmap(Context ctx, int resId, int nFrame)
{
    Resources res = ctx.getResources();     
    Bitmap bmpOneFrame = BitmapFactory.decodeResource(res, resId);
     
    if(bmpOneFrame == null)
    {
        AnimationDrawable ani = (AnimationDrawable)res.getDrawable(resId);
        Drawable drawableFrame = ani.getFrame(nFrame);
   
        bmpOneFrame = Bitmap.createBitmap(drawableFrame.getIntrinsicWidth(), 
                                          drawableFrame.getIntrinsicHeight(), 
                                          Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bmpOneFrame);
        drawableFrame.setBounds(0, 0, drawableFrame.getIntrinsicWidth(), 
                                      drawableFrame.getIntrinsicHeight());
        drawableFrame.draw(canvas);
    }
  
    return bmpFirstFrame;
}
참고로 리소스가 그냥 Drawable인 경우는 바로 Bitmap이 리턴된다.
또한 프레임 번호에 관련한 에러 처리는 없다 ^^;;

[안드로이드] ICS에서 Notification에 ProgressBar가 깨짐

ICS에서 RemoteView를 이용해 ProgressBar를 그리면 ProgressBar의 끝부분이 꺽여서 보기 흉해지는 경우가 있다.
원인은 잘모르겠으나 아마 ICS의 새로운  ProgressBar 는 (직접 그리는게 아니고)이미지로 되어 있기 때문인듯 한데...
그렇게 깨지는 경우 padding값이나 margin 값을 주어 ProgressBar의 위치를 조정해 주면된다.
상당히 꼴사나운 방법이지만 다른 방법은 찾지 못했다.
참고로 padding값이나 margin 값을 px가 아닌 dp로 줘야 한다.
요즘엔 폰마다 해상도가 천차 만별 -ㅁ-;;

아 그리고 ProgressBar의 스타일은 예전 버전처럼 주면 꺽이는 문제는 발생하지 않는다.
다만 촌스럽게 보일뿐 ^^;;
뭐 개인차겠지만;;
스타일에 Widget.ProgressBar.Horizontal 지정하여 사용 하시길...

[안드로이드] ICS에서 Notification RemoteView 사용하기

ICS에선 노티피케이션이 좀 멋있어 졌다.
좌측의 아이콘 화면이 노티피케이션 항목의 높이 만큼 커졌는데..
리모트 뷰를 사용 하던 기존 소스를 이용하면 새로운 노티피케이션과 어울리지않는 촌스러운 화면으로 보여 지게 된다.
그렇다고 RemoteView로 ICS스타일 처럼 똑같이 만들자니 쉽지가 않다.

자 그럼 왼쪽에 큰 아이콘을 유지 하면서 그 오른쪽에 RemoteView를 그리려면?
방법은 간단하다.
1. 먼저 기존의 RemoteView 의 레이아웃에서 아이콘을 제거 한다.
2. 좌측에 큰 아이콘을 넣을 것 이므로 그에 맞춰 레이아웃을 조정한다. 그럼 xml은 완성.
3. 다음으로 Notification을 만드는 코드에서 다음과 같이 largeIcon 값을 지정한다.
noti.largeIcon = BitmapFactory.decodeResource(res, resourceID);
    Notification.builder를 이용한다면 다음과 같이 지정 하면 된다.
notiBuilder.setLargeIcon(BitmapFactory.decodeResource(res, resourceID));
이렇게 하면 ICS에서도 이쁘게 보이는 Notification이 된다.

2012년 2월 26일 일요일

[안드로이드] 쓸모 없는 미디어 파일(음악,사진,동영상) 안보이게 하기.

얼마전 스트리트 파이터를 LG World에서 받았다.
의외로 재밌었지만 14000원이 약간 아까웠다 ㅠㅠ

그건 그렇고..
이녀석을 설치 하고 나서 음악에 들어가면 쓸때 없는 파일들이 너무 많아 원하는 음악 파일을 찾기가 힘들어 졌다.

이런 경우 쓸때 없는 파일들이 들어 있는 디렉토리에 .nomedia 란 파일을 만들어 주면 되는데...

먼저 .nomedia 파일을 만들어 두자.
시작메뉴 -> 실행 -> cmd
하여 명령프롬프트를 열고
copy con .nomedia
를 쳐넣고 엔터를 친다.
그뒤 Ctrl+Z 키를 누르면 파일이 하나 생성 된다.
탐색기로 그 파일이 있는 디렉토리로 가면 .nomedia 파일이 있을 것이다.

다음 USB로 휴대폰을 연결한 후 SD 카드를 마운트 한다.
내컴퓨터에서 연결된 SD 카드를 열어 쓸때 없는 파일들이 있는 디렉토리로 이동한다.
앞서 만들어 둔 .nomedia 파일을 끌어다 그 디렉토리에 복사 한다.

휴대폰에서 SD 카드 마운트를 해제 하면 SD카드를 다시 읽게 되고.
SD카드 확인이 끝나고 음악앱에 들어가면 쓸때 없는 파일이 안보이게 된다.

음악 파일 뿐만 아니고 갤러리에서 쓸때 없는 그림파일들이 자꾸 뜨는 경우에도 응용 할 수 있다.

[안드로이드] 에뮬레이터 단축키

안드로이드 에뮬레이터를 사용 하면서 유용한 단축키를 정리해 보았다.
표준 해상도가 아닌 경우 버튼 스킨이 나오지 않으므로 단축키를 사용한다면 무리 없이 사용 할 수 있다.

Emulated Device KeyKeyboard Key
Home 버튼HOME
Menu 버튼 (left softkey)F2 또는 Page-up
Star 버튼 (right softkey)Shift-F2 또는 Page Down
Back 버튼ESC
전화 걸기/통화 버튼F3
전화 끊기/통화 종료 버튼F4
Search 버튼F5
전원 버튼F7
볼륨 업 버튼KEYPAD_PLUS, Ctrl-5
볼륨 다운 버튼KEYPAD_MINUS, Ctrl-F6
카메라 버튼Ctrl-KEYPAD_5, Ctrl-F3
화면 회전 < (가로모드 < 세로모드)KEYPAD_7, Ctrl-F11
화면 회전 > (가로모드 > 세로모드)KEYPAD_9, Ctrl-F12
네트워크 On/OffF8
Toggle code profilingF9 (only with -trace startup option)
전체화면 모드Alt-Enter
트렉볼 모드 전환 (마우스 조작에 따라 트렉볼을 굴리는 듯한 효과를 나타 낸다.)F6
트렉볼 모드 (위와는 다르게 키를 누르는 동안에만 트렉볼 모드가 된다.)Delete
키패드 좌 상 우 하KEYPAD_4/8/6/2
키패드 가운데 버튼KEYPAD_5
Onion alpha increase/decreaseKEYPAD_MULTIPLY(*) / KEYPAD_DIVIDE(/)

2012년 2월 22일 수요일

[안드로이드] public.xml - 리소스값 고정하기

기본적으로 안드로이드에서는 리소스를 자동으로 관리해 준다.
res/ 이하의 디렉토리에 리소스 값을 넣어두면
Pre-compile시 재네레이터가
gen/ 폴더에 해당 리소스의 id값을 R.java 에 넣어 주게 된다.
개발자는 그 값을 이용해 리소스를 이용하기만 하면 아무 문제가 없는데...

문제는 만든 앱이 점점 버젼업을 해가고 다른 앱과 연동을 할때,
그것도 다른앱과 리소스를 공유한다면 발생하게 된다.

사실 거의 드문 케이스이기 때문에 예를 자세히 들면,

먼저 A 라는 앱이 있다.
이 앱엔 다른 앱의 아이콘 리소스 값을 등록해 해당 아이콘을 표시해 주는 기능이 있다.

B라는 앱에서 aa 라는 리소스를 만들었고,
A앱이 제공 하는 기능으로 aa의 값(0x71c4ee68 라고 하자)을 A앱에 등록 하였다.

시간이 흘러 B앱이 업데이트 되었고, 그와중에 리소스가 몇가지 추가 되어
aa의 값이 뒤로 밀리게 되었다. (0x71c4eee6)
A앱에 리소스가 등록된 상태에서 B앱이 업데이트 되면
A앱엔 B앱의(0x71c4ee68) 에 해당하는 아이콘이 보여 지게 될 것이다.
물론 B앱에서 기동시에 A앱의 값을 갱신해 주면 되지만,
뭔가 찝찝 하다.

이런 경우 aa 의 값을 고정해 줄수 있는 방법이 있다.
public.xml 이 바로 그것이다.

B앱의 res/values에 다음과 같이 public.xml을 추가 한다.
<resources>
 <!-- Fix resource value for app A -->
        <public type="drawable" name="aa" id=" 0x71c4ee68" />
</resources>
이렇게 하면 R.java의 aa값이 0x71c4ee68 로 고정될 것이다.
또한 재미있게도 주석으로 표시된 "Fix resource value for app A" 도
R.java에 주석으로 들어가게 된다.

2012년 2월 21일 화요일

[안드로이드] 에뮬레이터에 문자열 붙여 넣기

에뮬레이터를 이용해 개발 하다 보면 웹페이지나 텍스트 데이터 등을 카피 앤 페이스트 하고 싶어질때가 많다.
카피 앤 페이스트 만큼 간단하진는 않지만, 에뮬레이터에 문자열을 전달하는 방법을 소개 한다.

PC 에서
1. 먼저 이클립스에서 DDMS를 연다.
2. 다음 Emulator Control 탭을 선택 한다.
3. Emulator Control 중에 Telephony Actions 라는 그룹에
4. Incoming number 에 적당한 전화 번호를 넣고
5. SMS 를 선택 한 후
6. Message에 원하는 문자열을 넣는다 (제한이 있는듯 하다 2500자까진 된듯)
7. Send 버튼을 누른다.

Emulator 에서
1. SMS문자가 오면 해당 문자를 연다.
2. 문자를 롱클릭(누르고 있기) 하면 팝업이 뜨는데 Copy text 를 선택 한다.
3. 원하는  EditView(또는 입력하고자 하는 뷰)에 에서 롱클릭을 해 Paste 하면 된다.

뭐 10단계를 거쳐야 하니 복잡해 보이지만, 해보면 간단하게 할 수 있다.
무엇보다 20자 넘어가거나 특수 문자가 섞여 있다면 그냥 타이핑 하는것 보다 쉽고 정확하게 입렵이 가능하니 이 방법을 이용하길 권한다.

2012년 1월 31일 화요일

[안드로이드] String.xml 사용하기2 - Format 이용하기

스트링을 이용하다 보면 가끔 C에서의 printf가 너무 그립다.
물론 java도 그에 해당되는 녀석이 있다.
(Formatter는 요기 참고~)
http://developer.android.com/reference/java/util/Formatter.html#format(java.lang.String, java.lang.Object...)

이러한 포맷을 string.xml에도 지정 할 수 있는데,
UI의 고정된 메시지에 숫자만 바뀌거나 어떤 한 값만 바뀌는 경우 유용하게 사용 할 수 있다.

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

<resources>
    <string name="like_message">%1$d명의 사용자가 좋아 합니다.</string>
</resources>

1명의 사용자가 좋아 합니다.
27명의 사용자가 좋아 합니다.
같이 몇명인가의 값만 바뀐다면,
    String strLike = getString(R.string.like_message, 27);
이런식으로 뒤에 해당 값을 대입 시켜 주면 된다.


    <string name="like_message">%1$d명의 사용자가 좋아 합니다.</string>


를 좀더 자세히 살펴 보면 %1$d 가 있는데 여기서,
%1은 첫번째 항목을 뜻하고,
$d는 익숙한 정수형값임을 뜻한다.


따라서 
    홍길동27명의 사용자가 좋아 합니다.
와 같이 홍길동 과 27 이 변경 되는 값이라면,
    <string name="like_message">%1$s외 %2$d명의 사용자가 좋아 합니다.</string>
처럼 하면 된다.


java파일 에서는 


    String strHello = getString(R.string.like_message, "홍길동", 27);


처럼 사용 하면 된다.

2012년 1월 30일 월요일

[안드로이드] String.xml 사용하기

프로그래밍을 하다보면 문자열을 사용 하는 경우가 많다.
보통 귀찮아서 하드코딩 하지만;;;
수정이 빈번해 지던가 상사의 갈굼이 들어 오면 몰아서 상수로 정의 하기도 한다.
하지만 안드로이드 Context를 사용 할 수 있다면 string.xml을 사용 하는 것이 좋다.
string.xml의 경로는 기본적으로 
     ProjectName/res/values/string.xml
이다.

열어 보면 

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

<resources>
    <string name="hello">Hello string</string>
</resources>

처럼 되어 있는데, <resources> </Resources> 사이에 <string> </string> 으로 값을 넣어 주면 된다.

위 예와 같이
    <string name = "이름">내용</string>
하면 되는데,
[이름]에는 나중에 java코드나 다른 xml 파일에서 사용할 변수명을,
[내용]에는 실제로 대치될 스트링 값을 넣어 주는 것이다.
또한 주의 할점은 [이름]의 변수 명을 짓을 때는 자바 변수명명 규칙을 준수 해야 되며,
[내용]의 경우 xml의 string 형식을 준수 해야 한다.
xml의 string 형식을 보충 하자면 
    & : &amp; 
    < : &lt; 
    > : &gt; 
    ' : &apos; 
    " : &quot;
와 같은 문자는 xml 예약어 이므로 위의 표대로 써줘야 한다.

자 그럼 자바 코드에서 위의 스트링 값을 사용 하려면??

    String strHello = getString(R.string. hello);

이렇게 해주면 된다.

2012년 1월 19일 목요일

[안드로이드] Logcat창에 logcat session filter 가 자꾸 떠서 디버깅을 방해할 경우

안드로이드 API 버젼 14가 나오면서 ADT 또한 1.6으로 업데이트 되었다.
이번 ADT의 Logcat은 전버전에 비해 필터 기능이 창 편해 졌는데...

어느날 인가?
Eclipse의 설정값이 초기화 되었다.
귀찮아 하면서 설정을 복원했는데...
다하고 나서 디버깅을 하려 하니

 Logcat창에 logcat session filter 라는 항목이 생기면서 포커스를 자꾸 뺐어 가는 것이었다.
자동스크롤마저 되어서 이건 뭐 USB 케이블을 빼기 전까진 디버깅이 불가능 하다.

어딜 감히 건방지게 지맘대로 스크롤을해 -ㅁ-;;
가뜩이나 버그나서 짬뽕나는데;;

아무튼 이런 열받는 상황을 개선할 방법이 있다.

Eclipse Menu -> Preferences -> Android -> Logcat 에 보면..
Display logcat view when there are messages from an application in the workspace

이 옵션을 체크 해제 하면 된다.

2012년 1월 12일 목요일

[Android] Emulator 4.0.2 자동 업데이트;;

4.0 에뮬레이터를 사용중에 어느날 갑자기부팅 중 낯선 화면이 떴다.
뭔가 업그레이드를 한다는듯 한데;;

부팅이 끝난뒤 Setting -> About phone 에 들어가 보니,
4.0.2 로 업데이트 되어 있다;;

구글링좀 해보니 Minor 버그를 해결한 버젼이라 한다.
AVD엔 여전히 4.0으로 나온다.
API레벨도 여전히 14...

암튼 에뮬에서 업데이트를 하니 좀 신기한 경험 이었다 ㅋ

2012년 1월 4일 수요일

[Android] Activity xxx has leaked window xxxxxxx that was originally added here.

Dialog를 사용하다가 제목과 같은 에러를 만났다.
다른 경우에도 발생 할 법한 에러이긴 한데 아직 접해 본적은 없다.

일단 원인은 엑티비티에서 생성한 다이얼로그가 떠있는데,
액티비티가 종료되어 메모리 누수가 발생 했기 때문이다.

해결 방법은...
물론 액티비티가 종료될때 떠있을지 모르는 다이얼로그를 닫아 주면 되는데,

액티비티의 onPause()에서 다이얼로그의 dismiss() 를 호출 하거나,
다른 방법으로 닫아 주면 된다.

나의 경우
서비스에서 투명 액티비티를 띄워 투명액티비티상에서
다시 다이얼로그를 띄웠고 다이얼로그에서 뭔가 작업을 한뒤
다이얼로그가 닫히면서 액티비티도 종료 되는 것을 개발 하려 했는데,
실수로 액티비티만 닫히고 다이얼로그는 종료되지 않았던 것이었다.

알면 쉽지만..
이것 때문에 4시간은 해맨듯 하다.
ㅠㅠ