펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO


이미지 크기를 절대값으로 주고 여러 단말에서 확인을 해 보면, 단말 해상도에 따라 이미지 크기가


제각각인 경우가 있다.


애초에 이미지를 선언할 때 xml에서 dp로 줘버리면 상관이 없겠지만(drawable 폴더에 제대로 분기했다는 가정 하에),


소스코드상에서 비트맵을 만들고, 그 이미지를 뿌리는 경우 참 애매하다.


이때 해상도별로 사이즈 설정을 통일되게 하는 방법에 대해 알아보자.


예를들어Height1280px인 단말기에서 알맞은 이미지 width28px, height28px 일 때,


이보다 높거나 낮은 해상도에서 그에 맞는 사이즈로 리사이징을 하기 위한 방법이다.


먼저 단말의 해상도를 구해야한다.


Drawable d = getResources().getDrawable(id);

DisplayMetrics displayMetrics = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

float deviceHeight = displayMetrics.heightPixels;


이렇게하면 deviceHeight 에는 단말의 Height 사이즈가 리턴된다.

(어떤 단말에서는 1280, 어떤 단말에서는 2500몇 .. 이런식으로)


int dp = (int) (28 * (deviceHeight / 1280));


여기서 281280은 위에서 예시를 든것과 같이


1280px의 해상도 단말에서 알맞게 표시되는 이미지 크기 28px을 뜻한다.


이렇게 하면 단말 해상도가 커지거나 작아져도 dp값이 그에 따라 커지고 작아져서


모든 단말에서 알맞은 사이즈로 이미지가 표시된다.


디테일을 요구하는 작업에서는 다른 필터링이 추가되어야하겠지만, 일반적인범위 내에서는


위 방법을 이용하면 사이즈가 알맞게 잘 표시가 되었다.




펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO


이 포스팅에서 다루게 될 내용 :

1. Wi-Fi 주파수 추출법

2. 주파수에 다른 채널값 추출법




위 표는 IEEE 802.11b/g/n 2.4GHz 방식과 IEEE 802.11a/n 5GHz 방식의 표준을 나타낸 표이다.


쉽게 말해 일반적으로 말하는 2.4G 대역 와이파이와 5G 대역 와이파이의 주파수와 채널에 대한 정보이다.


먼저 연결된 Wi-Fi의 주파수를 검출하는 방법에 대해 알아보자.


주파수는 WifiManager를 이용하여 와이파이 스캔을 실시하고, 이 결과를 이용하여 추출하게 되는데 방법은 아래와 같다.


WifiManager mWM = (WifiManager) context.getSystemService(WIFI_SERVICE);

WifiInfo wifiInfo = mWM.getConnectionInfo();


try {

for (ScanResult scanResult : mWM.getScanResults()) {

if (wifiInfo != null && wifiInfo.getBSSID() != null

&& wifiInfo.getBSSID().equals(scanResult.BSSID)) {


mCurrentFrequency = scanResult.frequency;

break;

}

}

} catch (Exception e) {


}


주변 Wifi를 스캔하여 현재 연결된 WifiBSSID와 일치하는 와이파이의 주파수를 추출하고 있다.


이렇게 추출된 주파수와 채널값에는 일정한 규칙이 있다.


이 규칙을 공식으로 만들어 채널값을 계산할 수 있다.


방법은 아래와 같다.


public static int convertFrequencyToChannel(int freq) {

if(freq >= 2412 && freq <= 2484) {

if (freq == 2484)

return (freq-2412) /5;

return (freq-2412) /5 + 1;

}else if( freq >= 5170 && freq <= 5825) {

return (freq-5170) /5 + 34;

}

else {

return -1;

}

}


해당 계산식을 적용하면 표에 나와있는 채널값과 동일한 값이 얻어지는것을 확인 할 수 있다.


범위 확인중인 주파수 영역을 벗어나는 새로운 주파수가 추가된다면 소스코드의 수정이 필요할 수 있다.



펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO


1.구버전 안드로이드 기본브라우저 (약 S5 이전단말의 기본브라우저)


try {

String[] proj = new String[] { Browser.BookmarkColumns.TITLE, Browser.BookmarkColumns.URL};

String sel = Browser.BookmarkColumns.BOOKMARK + " = 1"; // 0 = history, 1 = bookmark

Cursor mCur = getContentResolver().query(Browser.BOOKMARKS_URI, proj, sel, null, null);

mCur.moveToFirst();

String title = "";

String url = "";


if (mCur.moveToFirst() && mCur.getCount() > 0) {

boolean cont = true;

while (mCur.isAfterLast() == false && cont) {

title = mCur.getString(mCur.getColumnIndex(Browser.BookmarkColumns.TITLE));

url = mCur.getString(mCur.getColumnIndex(Browser.BookmarkColumns.URL));

mCur.moveToNext();

      }


}

}

catch (Exception e) {

}



2. 크롬 브라우저


try {

String[] proj = new String[] { Browser.BookmarkColumns.TITLE, Browser.BookmarkColumns.URL, Browser.BookmarkColumns.DATE };

Uri uriCustom = Uri.parse("content://com.android.browser/bookmarks");

String sel = Browser.BookmarkColumns.BOOKMARK + " = 1"; // 0 = history, 1 = bookmark

Cursor mCur = getContentResolver().query(uriCustom, proj, sel, null, null);

mCur.moveToFirst();

String title = "";

String url = "";


if (mCur.moveToFirst() && mCur.getCount() > 0) {

boolean cont = true;

while (mCur.isAfterLast() == false && cont) {

title = mCur.getString(mCur.getColumnIndex(Browser.BookmarkColumns.TITLE));

url = mCur.getString(mCur.getColumnIndex(Browser.BookmarkColumns.URL));


        }

mCur.moveToNext();

      }


}

}

catch (Exception e) {

}


3. 최신단말의 안드로이드 S브라우저 (약 S5이후 단말에서 많이 사용하는것같음)


try {

String[] proj = new String[] { Browser.BookmarkColumns.TITLE, Browser.BookmarkColumns.URL, Browser.BookmarkColumns.DATE };

Uri uriCustom = Uri.parse("content://com.sec.android.app.sbrowser.browser/bookmarks");

String sel = Browser.BookmarkColumns.BOOKMARK + " = 1"; // 0 = history, 1 = bookmark

Cursor mCur = getContentResolver().query(uriCustom, proj, sel, null, null);

mCur.moveToFirst();

String title = "";

String url = "";


if (mCur.moveToFirst() && mCur.getCount() > 0) {

boolean cont = true;

while (mCur.isAfterLast() == false && cont) {

if (!TextUtils.isEmpty(url)) {

title = mCur.getString(mCur.getColumnIndex(Browser.BookmarkColumns.TITLE));

url = mCur.getString(mCur.getColumnIndex(Browser.BookmarkColumns.URL));


}

mCur.moveToNext();

      }


}

}

catch (Exception e) {

}



Android/기본스킬 | Posted by 덩치 2014. 11. 17. 17:19

전원버튼 이벤트 감지하기

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO


IntentFilter powerFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);

registerReceiver(mPowerBroadcast, powerFilter);



BroadcastReceiver mPowerBroadcast = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

if(Intent.getAction().equals("android.intent.action.SCREEN_OFF") {

// 스크린이 꺼질때 이벤트

}

else if(Intent.getAction().equals("android.intent.action.SCREEN_ON") {

// 스크린이 켜질때 이벤트

}

else

return;

}


}


그리고 onDestroy 등에서

unregisterReceiver(mPowerBroadcast);

를 이용해 브로드캐스트를 종료한다.



Android/기본스킬 | Posted by 덩치 2014. 11. 17. 17:12

홈버튼 이벤트 감지하기

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

@Override

protected void onUserLeaveHint() {

//여기서 감지

Log.d(TAG, "Home Button Touch");

super.onUserLeaveHint();

}


홈키 눌렀을때 작동되어야 하는 작업들을 위의 소스코드를 이용하여 처리할 수 있다.




펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO


아래서 제시하는 방법은 InstallerPackageName을 이용하여 자신을 인스톨 한 마켓이 어딘지 체크하는 방법이다.


Play스토어는 com.android.vending이 마켓의 패키지명이고,

T스토어는 com.skt.skaf.A000Z00040 이다.


따라서


PackageManager pm = mContext.getPackageManager();

if("com.android.vending".equals(pm.getInstallerPackageName("검사하려는 패키지명"))) { // PlayStore 다운


} else { // T Stroe 다운


}


이렇게 판단이 가능하다.


끝.


Android/NFC | Posted by 덩치 2014. 9. 26. 17:02

NFC 태그 쓰기(Write)

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

이전 포스팅 NFC 태그 읽기 에 이어서 쓰기에 대해 알아보자


NFCWrite하기 위해서는 NDEF Message를 구성해야한다. (참고 : http://biig.tistory.com/77)


참고 글을 봤다면 NDEF Message가 어떻게 구성되는지는 다 알것이고 설명은 생략하겠다.



우선, NFC 관련 객체를 생성한다.


public static final int TYPE_TEXT = 1;

public static final int TYPE_URI = 2;


EditText mWriteText;

NfcAdapter mNfcAdapter;

PendingIntent mPendingIntent;


protected void onCreate(Bundle saveInstanceState) {


mWriteText = (EditText) findViewById(R.id.et_write);

mNfcAdapter = NfcAdapter.getDefaultAdapter(this);

Intent inent = new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

mPendingIntent = PendingIntent.getActivity(this,0,intent,0);


}


다음, 이전 글에서 설명했듯이 태그를 인식하게되면 onNewIntent 메소드가 호출된다.


onNewIntent가 호출되면 태그에 실제로 값을 Write하는 작업을 수행해야한다.


@Override

protected void onNewIntent(Intent intent) {

super.onNewIntent(intent);

if (intent == null)

return;


Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

writeTag(getTextAsNdef(), detectedTag);


}


private NdefMessage getTextAsNdef() { 


byte[] textBytes = mWriteText.getText().toString().getBytes();


NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, 

"text/plain".getBytes(),

new byte[] {}, 

textBytes);

return new NdefMessage(new NdefRecord[] {textRecord});

}


private NdefMessage getUriAsNdef() { 


byte[] textBytes = mWriteText.getText().toString().getBytes();


NdefRecord record1 = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,

new String("U").getBytes(Charset.forName("US-ASCII")),

new byte[0],

textBytes) ;

return new NdefMessage(new NdefRecord[] {textRecord});

}


private void toast(String text) {

Log.i("fureun","toast");

Toast.makeText(this, text, Toast.LENGTH_SHORT).show();

}


이렇게 하면 기본적인 Write가 완료가 된다. 이후 Read를 하게되면 자신이 입력한 태그의 정보를 확인할 수 있다.



'Android > NFC' 카테고리의 다른 글

NFC 태그 읽기(Read)  (0) 2014.09.26
NFC란 ?  (0) 2014.09.25
Android/NFC | Posted by 덩치 2014. 9. 26. 11:33

NFC 태그 읽기(Read)

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

NFC 하드웨어에 접근하기 위한 엘리먼트 -


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



NFC를 지원하는 SDK 버전 -


API Level 9 - ACTION_TAG_DISCORVERED 만 지원


API Level 10 - EXTRA_NDEF_MESSAGES extra를 통해 NDEF 메시지에 접근 가능

 - 다른 태그의 프로퍼티와 I/O 연산 미지원


API Level 14 - 포괄적인 Read/Write 지원

 - Foreground NDEF 푸싱 지원

 - NDEF 레코드를 생성하기 위한여러 메소드 지원



NFC 읽기 -


태그 정보는 onNewIntentOverride 하거나 onResume 에서 받을 수 있다.


아무데서나 태그 읽기를 구현할 수 있다.


onNewIntentIntent 값을 리턴해주며, onResume에서는 getIntent로 태그정보를 받을 수 있다.





NfcAdapter 클래스를 이용하여 NFC 지원/미지원을 판단할 수 있다.


mNfcAdapter =  NfcAdapter.getDefaultAdapter(this) ;


if (mNfcAdapter == null) {

// NFC 미지원단말

Toast.makeText(getApplicationContext(), "NFC를 지원하지 않는 단말기입니다.", Toast.LENGTH_SHORT).show();

return;

}


먼저 TAG의 스팩에 대해알아보자


(아래부터는  onResume() 또는 onNewIntent(Intent intent)에 아래와같은 작업을 수행한다)


Tag myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);


Ndef ndefTag = Ndef.get(myTag);


// 태그 크기

int size = ndefTag.getMaxSize();

// 쓰기 가능 여부

boolean writable = ndefTag.isWritable();

// 태그 타입

String type = ndefTag.getType();

// 태그 ID

String id = byteArrayToHexString(myTag.getId());



public static String byteArrayToHexString(byte[] b) {
int len = b.length;
String data = new String();

for (int i = 0; i < len; i++){
data += Integer.toHexString((b[i] >> 4) & 0xf);
data += Integer.toHexString(b[i] & 0xf);
}
return data;
}

다음은 실제 TAG의 메시지를 확인한다

@Override
protected void onResume() {
super.onResume();

Parcelable[] messages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);


if (messages == null) return;


for (int i = 0; i < messages.length; i++)

setReadTagData((NdefMessage)messages[0]);

}


public void setReadTagDataa(NdefMessage ndefmsg) {

if(ndefmsg == null ) {

return ;

}

String msgs = "";

msgs += ndefmsg.toString() + "\n";

NdefRecord [] records = ndefmsg.getRecords() ;

for(NdefRecord rec : records) {

byte [] payload = rec.getPayload() ;

String textEncoding = "UTF-8" ;

if(payload.length > 0)

textEncoding = ( payload[0] & 0200 ) == 0 ? "UTF-8" : "UTF-16";


Short tnf = rec.getTnf();

String type = String.valueOf(rec.getType());

String payloadStr = new String(rec.getPayload(), Charset.forName(textEncoding));

}

}


이렇게 태그의 주요 정보를 읽을 수 있다.


다음 포스팅에서는 태그 쓰기에 대해 다루겠다.  끝





'Android > NFC' 카테고리의 다른 글

NFC 태그 쓰기(Write)  (0) 2014.09.26
NFC란 ?  (0) 2014.09.25
Android/NFC | Posted by 덩치 2014. 9. 25. 11:36

NFC란 ?

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

NFC (Near Field Communication)



RFID(무선 주파수 통신) 기술의 총체로 


카드 모드, 태그 쓰기/읽기 모드, P2P 모드로 사용할 수 있다.




NDEF (NFC Data Exchange Format)


NFC 데이터 교환에 이용되는 데이터 교환 포멧으로 NFC 포럼에서 정의



NDEF Message


기본적인 NFC 데이터 교환 메시지 단위 하나를 NDEF Message라고 한다.


하나의 NDEF Message는 한개 이상의 NDEF Record로 구성되며, 하나의 NDEF Record는 하나의 데이터를 가지고 이를 


'페이로드(payload)' 라고 한다.


개념도


이미지 : http://ibadrinath.blogspot.kr/2012/07/nfc-data-exchange-format-ndef.html




NDEF Record 구성


 항목 길이  설명
 레코드 헤더 (header) 1byte  레코드에 대한 기본적인 정보
 타입 길이 (type length) 1byte 데이터 타입의 길이
 페이로드 길이 (payload length) 1byte 혹은 4byte 페이로드의 길이
 ID 길이 (id length) 1byte ID의 길이
 타입 (type) '타입 길이' byte 레코드가 담고 있는 페이로드의 타입
 ID 'ID 길이' byte 페이로드 ID
 페이로드 (payload) '페이로드 길이' byte 레코드가 담고 있는 페이로드

-표 출처 : http://blog.startnfc.com/entry/NDEF



레코드 헤더(header)의 구성


  헤더 항목 길이  설명
 MB (Message Begin) 1bit NDEF 메시지의 첫 레코드는 이 비트가 1 입니다.
 ME (Message End) 1bit NDEF 메시지의 마지막 레코드는 이 비트가 1입니다. 
 CF (Chunk Flag) 1bit 하나의 페이로드를 여러 개의 레코드로 나누어 전송하는 경우가 있는데, 이때 사용합니다.
 SR (Short Record) 1bit 이 비트가 1이면 '페이로드 길이'의 크기는 1byte이고, 0이면 4byte입니다.
 IL (ID Length) 1bit 레코드 ID가 존재하는 경우 이 비트가 1입니다.
 TNF (Type Name Format) 3bit (별도로 설명)

-표 출처 : http://blog.startnfc.com/entry/NDEF



NDEF Record - 타입(type)과 TNF


인터넷에 존재하는 대부분의 콘텐츠는 MIME 타입으로 구분이 가능하다.


하지만 NFC에서는 MIME 타입 이외에 다른 타입도 포함한다.


TNF는 위와 같은 타입이 어떤 형태로 되어 있는지를 나타낸다.


Android 에서 사용되는 TNF의 종류는 아래와 같다.


TNF_ABSOLUTE_URI

TNF_EMPTY

TNF_EXTERNAL_TYPE
(자세한 사항은 클릭)

3비트 TNF의 구성


 TNF (Type Name Format)  설명
 Empty 0x00 

 비어있는 레코드. 즉, 페이로드가 없음.

 WKT (NFC Forum well-known type)

 0x01

 NFC 포럼에서 정의한 타입 형식. (예: URI, Text, Smart Poster)

 MIME (MIME Media type)

 0x02

 MIME 타입 형식. (예: plain/text, image/jpeg)

 AURI (Absolute URI type)

 0x03

 예를 들어 XML의 경우 URI 형식의 DTD나 XML Schema를 타입으로 사용함. (예: http://www.w3.org/TR/html4/strict.dtd, http://www.w3.org/2000/svg)

 EXT (NFC Forum external type)

 0x04

 NFC 포럼에서 정의한 규칙대로, 임의의 타입 형식을 만들어 사용할 수 있음. (예: startnfc.com:U)

 Unknown 0x05

 알 수 없는 형식의 페이로드. 그냥 byte 덩어리로 취급됨.

 Unchanged

 0x06

 데이터를 여러 조각으로 나누어 전송하는 경우 (chunked record) 이전 레코드의 타입과 같은 타입이라는 것을 나타내기 위해 사용.

 Reserved 0x07

 사용하지 않음.


-표 출처 : http://blog.startnfc.com/entry/NDEF




지금까지 NFC와 핵심 내용에 대한 이론을 알아보았고, 실제 Android에서 NFC를 어떻게 사용하는지 


다음 포스팅에 기술하겠다.




'Android > NFC' 카테고리의 다른 글

NFC 태그 쓰기(Write)  (0) 2014.09.26
NFC 태그 읽기(Read)  (0) 2014.09.26

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO



숫자형 값을 출력했더니 NaN값이 발생한다. 이유를 알아보자


NaN은 여러가지 경우에 발생한다.


데이터를 0으로 나눈 값을 입력하거나, 숫자로 바꿀 수 없는 문자열을 숫자로 입력받거나,


데이터형이 감당할 수 없는 크기의 값을 입력받게 되는 등등 다양한 경우에 걸쳐 발생한다.


필자도 org.json.JSONException: Forbidden numeric value: NaN 가 발생하여 고생했는데,

(제이슨 오브젝트에 NaN값을 가진 벨류를 put하여 발생)


다음과 같이 처리를 해주면 NaN 체크가 가능하다.


if (Float.isNaN(num))

if (Double.isNaN(num))


위와같이 체크를 하여 boolean값을 리턴받을 수 있다.


조건을 만족할 경우 Default 값을 설정 해 주면 되겠다.

'Android > Exception' 카테고리의 다른 글

Error:Apostrophe not preceded by 에러 발생시 대처  (1) 2015.01.26