각 나라마다 해당 언어를 표시 하는 경우가 생겼다.
project의 res 폴더 하위의 values 의 string.xml을 이용해서 간단히 사용할수 있다.
기본적으로 프로젝트 개발시에 values의 string.xml에 정의된 값을 사용하게 되는데,
각 언어별로 폴더를 따로 구성하게 되면, 디바이스에 설정된 시스템언어에 따라 자동으로
각 언어별로 지정된 values 폴더를 참조해서 표현하게 된다. (아래 첨부 이미지 참고)
만일 사용자가 설정한 국가의 언어 폴더가 없을 경우에는 values를 참조한다.
그러니 기본적으로 표현할 언어를 values폴더에 지정하고 사용하면 된다.
values뒤의 폴더명이 en, ja 가 붙는 이유는 시스템에서 나라를 구분하는데 있어 사용하는
구분자 이다.
'en'은 영어, 'ja'는 일본어, 한국어는 'ko'가 된다.
다른 나라는 Android Developer 사이트의 Reference에서 Locale 클레스를 참고 하면 된다.
[http://developer.android.com/reference/java/util/Locale.html]
string.xml 파일을 참고하자면, (나는 한국어 폴더를 따로 만들지 않고 디폴트로 설정했다.)
[values폴더의 string.xml]
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">안녕!!</string>
<string name="app_name">언어설정 테스트</string>
</resources>
[values-ja폴더의 string.xml]
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">おはよう!</string>
<string name="app_name">言語設定テスト</string>
</resources>
위와 같이 구성해 놓으면 디바이스가 자동으로 설정 되있는 국가별로 폴더를 찾아서 해당 언어를 뿌려 준다는 사실!!
2012년 8월 8일 수요일
2012년 5월 15일 화요일
[android] WebView 안의 스크롤 (iscroll)
작업중 리소스로 만들어 놓은 html파일을 webview에서 로드를 해서 보여 주고 있었는데
웹페이지에서 구성한 스크롤이 먹통인것인다.
하루 꼬박 이리저리 서칭한 결과 모바일웹에서는 일부 css 속성을 지원하지 않는다는... ㅠㅠ
그중 하나가 overflow의 scroll 이였던 거다.
아이폰 같은 경우는 iOS5부터는 이 속성이 지원되는데 이유야 어쨌든 나는 안드로이드에서도 문제없이 뷰를 해야 한다는 사실..
역시 존경해 마지 않는 기술자들.. 방법이 없는건 아니다.
나에게 구세주 같았던 사이트를 참조 했다
참고사이트 :
http://codefactory.kr/2011/08/15/iscroll-mobileweb-inner-scroll-area/
http://cubiq.org/iscroll-4
샘플코드를 보면 아주 간단하게 iscroll를 사용해서 뷰를 하고 있고,
iscroll.js 파일을 잘 활용하면 스크롤 영역 예처리랄지 자신에게 필요하게 수정해서 사용해도 될듯하다.
웹페이지에서 구성한 스크롤이 먹통인것인다.
하루 꼬박 이리저리 서칭한 결과 모바일웹에서는 일부 css 속성을 지원하지 않는다는... ㅠㅠ
그중 하나가 overflow의 scroll 이였던 거다.
아이폰 같은 경우는 iOS5부터는 이 속성이 지원되는데 이유야 어쨌든 나는 안드로이드에서도 문제없이 뷰를 해야 한다는 사실..
역시 존경해 마지 않는 기술자들.. 방법이 없는건 아니다.
나에게 구세주 같았던 사이트를 참조 했다
참고사이트 :
http://codefactory.kr/2011/08/15/iscroll-mobileweb-inner-scroll-area/
http://cubiq.org/iscroll-4
샘플코드를 보면 아주 간단하게 iscroll를 사용해서 뷰를 하고 있고,
iscroll.js 파일을 잘 활용하면 스크롤 영역 예처리랄지 자신에게 필요하게 수정해서 사용해도 될듯하다.
2012년 5월 2일 수요일
[android] 3G/WIFI 체크하기
사용하는 디바이스가 현재 3G를 이용하는지, WIFI를 이용중이지를 체크할일이 있다.
각종 어플에서 이에 관련한 경고다이얼로그를 띄워주는걸 본적이 있을테니!
간단하게 context를 인자로 받아서 해당 체크를 true/false로 리턴하는 메소드를 만들었다.
(본인은 해당 메소드를 activity를 상속받은 클래스가 아닌 여기저기서 사용할수 있게 그냥 클래스에 메소드를 만들어 놨기에 Context를 인자로 받게 작성했다. 작성하고자 하는 클래스에 맞에 알아서들 편집해서 쓰시길..)
/**
* 3G 사용여부 체크
*/
public static boolean is3gNetwork(Context context) {
ConnectivityManager manager =
(ConnectivityManager)context.getSystemService(
Context.CONNECTIVITY_SERVICE);
// 3G 를 사용하는지 확인힌다.
boolean is3g =
manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
.isConnectedOrConnecting();
return is3g;
}
/**
* Wifi 사용여부 체크
*/
public static boolean isWifiNetwork(Context context) {
ConnectivityManager manager =
(ConnectivityManager)context.getSystemService(
Context.CONNECTIVITY_SERVICE);
// Wifi 를 사용하는지 확인힌다.
boolean isWifi =
manager.getNetworkInfo(ConnectivityManager. TYPE_WIFI)
.isConnectedOrConnecting();
return isWifi;
}
각종 어플에서 이에 관련한 경고다이얼로그를 띄워주는걸 본적이 있을테니!
간단하게 context를 인자로 받아서 해당 체크를 true/false로 리턴하는 메소드를 만들었다.
(본인은 해당 메소드를 activity를 상속받은 클래스가 아닌 여기저기서 사용할수 있게 그냥 클래스에 메소드를 만들어 놨기에 Context를 인자로 받게 작성했다. 작성하고자 하는 클래스에 맞에 알아서들 편집해서 쓰시길..)
/**
* 3G 사용여부 체크
*/
public static boolean is3gNetwork(Context context) {
ConnectivityManager manager =
(ConnectivityManager)context.getSystemService(
Context.CONNECTIVITY_SERVICE);
// 3G 를 사용하는지 확인힌다.
boolean is3g =
manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
.isConnectedOrConnecting();
return is3g;
}
/**
* Wifi 사용여부 체크
*/
public static boolean isWifiNetwork(Context context) {
ConnectivityManager manager =
(ConnectivityManager)context.getSystemService(
Context.CONNECTIVITY_SERVICE);
// Wifi 를 사용하는지 확인힌다.
boolean isWifi =
manager.getNetworkInfo(ConnectivityManager. TYPE_WIFI)
.isConnectedOrConnecting();
return isWifi;
}
[android] 위도,경도 ↔ 주소 취득
1. 위도, 경도로 주소 취득 (Geocoder 이용)
Location 와 LocationManager클래스를 이용해서 위도 경도 정보를 가지고 오자!
location 클래스의 getLatitude(), getLongitude() 메소드 사용
(여기서는 생략!)
취득한 위도,경도값을 가지고 주소를 리턴하는 메소드를 만들었다.
/**
* 위도,경도로 주소취득
* @param lat
* @param lng
* @return 주소
*/
private String findAddress(double lat, double lng) {
StringBuffer bf = new StringBuffer();
Geocoder geocoder = new Geocoder(this, Locale.KOREA);
List<Address> address;
try {
if (geocoder != null) {
// 세번째 인수는 최대결과값인데 하나만 리턴받도록 설정했다
address = geocoder.getFromLocation(lat, lng, 1);
// 설정한 데이터로 주소가 리턴된 데이터가 있으면
if (address != null && address.size() > 0) {
// 주소
currentLocationAddress = address.get(0).getAddressLine(0).toString();
// 전송할 주소 데이터 (위도/경도 포함 편집)
bf.append(currentLocationAddress).append("#");
bf.append(lat).append("#");
bf.append(lng);
}
}
} catch (IOException e) {
Toast.makeText(baseContext, "주소취득 실패"
, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
return bf.toString();
}
===============================================================================
2. 주소로 위도, 경도 취득 (Geocoder 이용)
/**
* 주소로부터 위치정보 취득
* @param address 주소
*/
private GeoPoint findGeoPoint(String address) {
Geocoder geocoder = new Geocoder(this);
Address addr;
GeoPoint location = null;
try {
List<Address> listAddress = geocoder.getFromLocationName(address, 1);
if (listAddress.size() > 0) { // 주소값이 존재 하면
addr = listAddress.get(0); // Address형태로
int lat = (int) (addr.getLatitude() * 1E6);
int lng = (int) (addr.getLongitude() * 1E6);
location = new GeoPoint(lat, lng);
Log.d(TAG, "주소로부터 취득한 위도 : " + lat + ", 경도 : " + lng);
}
} catch (IOException e) {
e.printStackTrace();
}
return location;
}
簡単だろ~ ^0^
Location 와 LocationManager클래스를 이용해서 위도 경도 정보를 가지고 오자!
location 클래스의 getLatitude(), getLongitude() 메소드 사용
(여기서는 생략!)
취득한 위도,경도값을 가지고 주소를 리턴하는 메소드를 만들었다.
/**
* 위도,경도로 주소취득
* @param lat
* @param lng
* @return 주소
*/
private String findAddress(double lat, double lng) {
StringBuffer bf = new StringBuffer();
Geocoder geocoder = new Geocoder(this, Locale.KOREA);
List<Address> address;
try {
if (geocoder != null) {
// 세번째 인수는 최대결과값인데 하나만 리턴받도록 설정했다
address = geocoder.getFromLocation(lat, lng, 1);
// 설정한 데이터로 주소가 리턴된 데이터가 있으면
if (address != null && address.size() > 0) {
// 주소
currentLocationAddress = address.get(0).getAddressLine(0).toString();
// 전송할 주소 데이터 (위도/경도 포함 편집)
bf.append(currentLocationAddress).append("#");
bf.append(lat).append("#");
bf.append(lng);
}
}
} catch (IOException e) {
Toast.makeText(baseContext, "주소취득 실패"
, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
return bf.toString();
}
===============================================================================
2. 주소로 위도, 경도 취득 (Geocoder 이용)
/**
* 주소로부터 위치정보 취득
* @param address 주소
*/
private GeoPoint findGeoPoint(String address) {
Geocoder geocoder = new Geocoder(this);
Address addr;
GeoPoint location = null;
try {
List<Address> listAddress = geocoder.getFromLocationName(address, 1);
if (listAddress.size() > 0) { // 주소값이 존재 하면
addr = listAddress.get(0); // Address형태로
int lat = (int) (addr.getLatitude() * 1E6);
int lng = (int) (addr.getLongitude() * 1E6);
location = new GeoPoint(lat, lng);
Log.d(TAG, "주소로부터 취득한 위도 : " + lat + ", 경도 : " + lng);
}
} catch (IOException e) {
e.printStackTrace();
}
return location;
}
簡単だろ~ ^0^
2012년 4월 23일 월요일
[android] sd / assets 경로
1. assets : file:///android_asset/test.png
2. sdcard : file:///sdcard/test/test_img.png
+ 코드상에서 sd path :
Environment.getExternalStorageDirectory().getAbsolutePath();
+ Assets에 있는 이미지 비트맵으로 가져오는 함수
/**
* Assets에 있는 이미지 가져오기
* 작성자 : Choi Areum
*/
public static Bitmap loadBitmap(Resources resources, String urlStr) {
Bitmap bitmap = null;
AssetManager mngr = resources.getAssets();
try {
InputStream is = mngr.open(urlStr);
bitmap = BitmapFactory.decodeStream(is);
} catch(Exception e) {
}
return bitmap;
}
[android] 매니페스트 파일 구조
<?xml version="1.0" encoding="utf-8"?>
<manifest> // 응용 프로그램의 패키지 이름 및 버전 정보를 설정
<uses-permission /> // 응용 프로그램에 필요한 권한 등록
<permission /> // 응용 프로그램이 다른 응용 프로그램에게 허락하는 권한들을 등록
<permission-tree /> // 권한 트리 등록
<permission-group /> // 권한 그룹 등록
<instrumentation /> // 응용 프로그램과 시스템 리소스와의 상호작용을 모니터링하는 데 유효
<uses-sdk /> // 응용프로그램 어느 버전의 안드로이드 환경에서 사용할 수 있는지 설정
<uses-configuration /> // 응용프로그램에 필요한 모든 하드웨어 및 소프트웨어 입력 구성을 정의
<uses-feature /> // 응용프로그램에서 사용되는 특정 Feature를 설정
<supports-screens /> // 응용프로그램에서 지원하는 화면 크기를 설정
<application> // 응용프로그램의 이름과 아이콘을 설정
<activity> // 응용프로그램의 모든 액티비티를 각각 하나의 <activity>요소로 등록
<intent-filter>
<action />
<category />
<data />
</intent-filter>
<meta-data />
</activity>
<activity-alias> // 액티비티 별칭
<intent-filter> . . . </intent-filter>
<meta-data />
</activity-alias>
<service> // 서비스 등록
<intent-filter> . . . </intent-filter>
<meta-data/>
</service>
<receiver> // 방송 수신자 등록
<intent-filter> . . . </intent-filter>
<meta-data />
</receiver>
<provider> // 콘텐트 제공자 등록
<grant-uri-permission />
<meta-data />
</provider>
<uses-library /> // 표준패키지 외에 지도 서비스처럼 추가로 연동되는 다른 패키지들을 링크
</application>
</manifest>
<manifest> // 응용 프로그램의 패키지 이름 및 버전 정보를 설정
<uses-permission /> // 응용 프로그램에 필요한 권한 등록
<permission /> // 응용 프로그램이 다른 응용 프로그램에게 허락하는 권한들을 등록
<permission-tree /> // 권한 트리 등록
<permission-group /> // 권한 그룹 등록
<instrumentation /> // 응용 프로그램과 시스템 리소스와의 상호작용을 모니터링하는 데 유효
<uses-sdk /> // 응용프로그램 어느 버전의 안드로이드 환경에서 사용할 수 있는지 설정
<uses-configuration /> // 응용프로그램에 필요한 모든 하드웨어 및 소프트웨어 입력 구성을 정의
<uses-feature /> // 응용프로그램에서 사용되는 특정 Feature를 설정
<supports-screens /> // 응용프로그램에서 지원하는 화면 크기를 설정
<application> // 응용프로그램의 이름과 아이콘을 설정
<activity> // 응용프로그램의 모든 액티비티를 각각 하나의 <activity>요소로 등록
<intent-filter>
<action />
<category />
<data />
</intent-filter>
<meta-data />
</activity>
<activity-alias> // 액티비티 별칭
<intent-filter> . . . </intent-filter>
<meta-data />
</activity-alias>
<service> // 서비스 등록
<intent-filter> . . . </intent-filter>
<meta-data/>
</service>
<receiver> // 방송 수신자 등록
<intent-filter> . . . </intent-filter>
<meta-data />
</receiver>
<provider> // 콘텐트 제공자 등록
<grant-uri-permission />
<meta-data />
</provider>
<uses-library /> // 표준패키지 외에 지도 서비스처럼 추가로 연동되는 다른 패키지들을 링크
</application>
</manifest>
[android] startActivityForResult 사용시 주의점
A -> B 액티비티 사이에서 데이터를 주고 받는 방법은 많이 있지만
startActivityForResult 를 이용하여 호출한 액티비티의 리턴값을 받아 처리를 하고 싶을 경우
A 액티비티에서 startActivityForResult 로 B액티비티를 호출해 다시 A로 돌아와서
onActivityResult를 오버라이드해서 보통 쓰는데
A액티비티를 destory (종료) 시키거나 A 액티비티를 부르는데 있어서
intent flag에 Intent.FLAG_ACTIVITY_NO_HISTORY 속성을 주게 되면
onActivityResult로 돌아오지도 안고 destory 되 버린다 ㅠ.ㅠ
구조상 여러 액티비티를 호출하고 있어서 태스크에 쌓아두지 않으려고 추가한 속성인데
잘되던 처리가 되지않아서 한참 삽질을.. 흑;
[android] WebView에서 Flipper처리
회사에서 작업하다 웹뷰로 작성한 화면을 플립처리를 해줘하는 상황이 됐다.
웹뷰의 스크롤 처리와 (상하) 해당화면의 플립처리(좌우) 하는데 좀 애를 먹었어서 해당 처리를 정리해놓자!!
우선 XML에 뷰플립퍼를 정의 하고
| <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/layout_article"> <ViewFlipper android:id="@+id/artflipper" android:layout_width="fill_parent" android:layout_height="fill_parent"> </ViewFlipper> </LinearLayout> |
소스코드에서 웹뷰를 등록한다.
final String mimeType = "text/html"; final String encoding = "utf-8"; WebView wv; wv = new WebView(getApplicationContext()); // wv.loadData("<a href='x'>Hello World! - 5</a>", mimeType, encoding); wv.loadDataWithBaseURL("about:blank" ,"<img src=\"file:///android_asset/buttom_bg.png\" width='100%' />" , mimeType, encoding, "");
여기서 loadDataWithBaseURL(디폴트웹화면, 웹화면, 인코딩할 녀석, 인코딩종류
, 히스토리화면) 메소드와 loadData() 메소드의 차이점은 loadData()는 인코딩할때
태그와 텍스트를 구분하지않고 인코딩하므로 html태그가 깨질수 있다.
허나 loadDataWithBaseURL()메소드는 태그와 값을 구분해서
인코딩해주는 아주 착한 녀석 ㅋㅋ
나는 테스트로 이미지를 띄웠는데 해당 이미지는 안드로이드 프로젝트의 assets아래에
있는 녀석이다.
width를 정해준거는 실제 이미지가 디바이스 화면보다 큰 이미지였는데 그냥 이미지
지정만 하면 화면 밖으로 나가버린다 ㅠㅠ 그래서 이래저래 찾아보다 저렇게
너비를 100%로 지정해주면 해당 부모의 너비 만큼 축소해서 보여준다! 착한녀석!!
viewFlipper.addView(wv); //이렇게 플립퍼에 뷰를 추가하고 wv.setOnTouchListener(this); //웹뷰의 터치리스너를 등록해준다. //아무리 플리퍼에 리스너를 등록해서 웹뷰 위에서 터치 이벤트를 //감지하지 못한다 ㅠㅠ 완전 삽질함. wv = new WebView(getApplicationContext()); // wv.loadData("<a href='x'>Hello World! - 6</a>", mimeType, encoding); wv.loadDataWithBaseURL("about:blank", "<table border='0' cellSpacing='1' cellPadding='0' width='300' bgColor='#b7bcc5' height='40'>" + "<tbody><tr bgColor='#ffffff'><td width='329'> <img src=\"file:///android_asset/buttom_bg.png\" width='100%' /></td> <td width='329'> </td></tr>" + "<tr bgColor='#ffffff'><td>한글</td><td> </td></tr></tbody></table>" , mimeType, encoding, ""); viewFlipper.addView(wv); wv.setOnTouchListener(this); // 이번에 테이블 태크를 넣어봤다. 테이블 레이아웃으로 테이블 스러운 디자인이 아무리 해도 // 나오질 않아서 웹뷰를 이용 HTML로 테이블을 표현하기로 결정! // 해당 테이블이 글씨 뿐만 아니라 이미지도 표현해야 하므로 테이블 안에 // 이미지도 넣어보고 한글도 넣어보고 ㅋ wv = new WebView(getApplicationContext()); wv.loadDataWithBaseURL("about:blank", "<table border='0' cellSpacing='1' cellPadding='0' width='300' bgColor='#b7bcc5' height='40'>" + "<tbody><tr bgColor='#ffffff'><td width='329'> <img src=\"file:///sdcard/test/test_img.png\" width='100%' /></td> <td width='329'> </td></tr>" + "<tr bgColor='#ffffff'><td>한글</td><td> </td></tr></tbody></table>" , mimeType, encoding, ""); viewFlipper.addView(wv); wv.setOnTouchListener(this); |
| public boolean onTouch(View arg0, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN:{ // store the X value when the user's finger was pressed down Log.i("ACTION_DOWN", "OK!!!!!!"); downXValue = event.getX(); downYValue = event.getY(); break; } case MotionEvent.ACTION_UP: { // Get the X value when the user released his/her finger Log.i("ACTION_UP", "OK!!!!!!"); // upXValue = event.getX(); // upYValue = event.getY(); if (downXValue > upXValue + 100) viewFlipper.showNext(); Log.i("자식뷰 인덱스", viewFlipper.getChildCount()+""); Log.i(" 터치 확인 ", "left"); if (downXValue+100 < upXValue) viewFlipper.showPrevious(); Log.i(" 터치 확인 ", "right"); // if (downYValue > upYValue +100) // Log.i(" 터치 확인 ", "up"); // if (downYValue+100 < upYValue) // Log.i(" 터치 확인 ", "down"); break; } } return true; } 이렇게 터치 리스너를 오버라이드 해주면 OK 좌우 뿐만 아니라 상하로도 구현할수 있따! 좌우로 터치했을때 플립효과를 주기위해 해당 조건에 맞으면 플리퍼의 이동 메소드를 호출하면 OK!! +100 씩 해주는거 터치해서 잡는 좌표값이 float타입으로 아주 미세한 수치로도 변화가 읽어나므로 확실한 좌우/ 상하 플립으로 인식하기 위한 일종의 값을 넣어준거임 |
피드 구독하기:
글 (Atom)

