펌 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



public Boolean isServiceRunning(String serviceName) {

ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);

for (RunningServiceInfo runningServiceInfo :                                                   activityManager.getRunningServices(Integer.MAX_VALUE)) {

if (serviceName.equals(runningServiceInfo.service.getClassName())) {

return true;

   }

}

return false;

}


serviceName : 매니패스트에서 설정한 서비스의 이름.


ex ) <service android:name="com.biig.tistory.service.BiigService" >

에서 String serviceName = "com.biig.tistory.service.BiigService";



Android/기본스킬 | Posted by 덩치 2014. 6. 24. 17:49

LocationManager로 위치값 받아오기

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


LocationManager를 사용하기 위한 퍼미션 ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION 


모바일의 Gps 또는 Network 정보로 위치좌표를 받아오는 방법에 대해 알아보겠다.


LocationManager mLM = (LocationManager) getSystemService(Context.LOCATION_SERVICE);


이렇게 로케이션 매니저를 선언 한 뒤, 위치값 갱신을 호출 해 보자.


위치 제공자는 총 2가지 종류가 있다.


1. GPS_PROVIDER

2. NETWORK_PROVIDER


실내에서는 GPS_PROVIDER를 호출해도 응답이 없다. 응답을 기다리는 형태로 코딩을 했다면


별다른 처리를 하지 않으면 실내에서는 무한정 대기한다.


따라서 타이머를 설정하여 GPS_PROVIDER를 호출 한 뒤 일정 시간이 지나도 응답이 없을 경우


NETWORK_PROVIDER를 호출 하거나,


또는 둘 다 한꺼번에 호출하여 들어오는 값을 사용하는 방식으로 코딩을 하는것이 일반적이겠다.


private void registerLocationUpdates() {

        mLM.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,

1000, 1, mLocationListener);

mLM.requestLocationUpdates(LocationManager.GPS_PROVIDER,

1000, 1, mLocationListener);

//1000은 1초마다, 1은 1미터마다 해당 값을 갱신한다는 뜻으로, 딜레이마다 호출하기도 하지만

//위치값을 판별하여 일정 미터단위 움직임이 발생 했을 때에도 리스너를 호출 할 수 있다.

}



private final LocationListener mLocationListener = new LocationListener() {

public void onLocationChanged(Location location) {

//여기서 위치값이 갱신되면 이벤트가 발생한다.

//값은 Location 형태로 리턴되며 좌표 출력 방법은 다음과 같다.


    if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) {

//Gps 위치제공자에 의한 위치변화. 오차범위가 좁다.

double longitude = location.getLongitude();    //경도

double latitude = location.getLatitude();         //위도

float accuracy = location.getAccuracy();        //신뢰도

    }

    else {

//Network 위치제공자에 의한 위치변화

//Network 위치는 Gps에 비해 정확도가 많이 떨어진다.

    }

   }

public void onProviderDisabled(String provider) {

}


public void onProviderEnabled(String provider) {

}


public void onStatusChanged(String provider, int status, Bundle extras) {

}

}


위와같이 사용하면 된다. 그리고 더이상 위치값을 호출하지 않아도 되는 경우에는

mLM.removeUpdates(mLocationListener);자원해제를 반드시 해 준다. 누락하면 딜레이마다 계속 호출한다.





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


현재 단말기의 전화번호를 가져오고자 할때 사용한다. 

     ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)).getLine1Number()


그리고 아래는 단말기와 관련된 내용

 

  1. AndroidManifest.xml 에 아래 권한 추가
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />

  2. 아래와 같이 Context.getSystemService 를 통해 TelephonyManager 를 가져옴.
       TelephonyManager telephony = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
        
  3. TelephonyManager 의 메소드 들 중, getLine1Number() 메소드가 전화번호를 반환
       String  telPhoneNo = telephony.getLine1Number();  

 

   출처 ( http://icess.egloos.com/3279459 )     





그리고 아래는 좀 더 많은 내용. 
분명 필요한 순간이 있을것이다. 잘 기억해두자.
=========================================================================================

android.telephony 패키지의 TelephonyManager클래스에서 담당한다.

단말기의 모뎀상태에 대한 정보를 얻기 위해서는 READ_PHONE_STATE권한이 필요하다.
AndroidManifest.xml파일에 아래 내용을 추가한다.
<uses-permission 
android:name="android.permission.READ_PHONE_STATE">
</uses-permission>

◆ 단말기의 모뎀상태 조회
TelephonyManager 객체를 얻기 위해서는 Context 객체에서 제공하는 getSystemService() 메서드를 이용한다.
TelephonyManager tm = (TelephonyManager)  
getSystemService(TELEPHONY_SERVICE);

음성통화 상태 조회
CALL_STATE_IDLE/CALL_STATE_OFFHOOK/CALL_STATE_RINGING 등의 값을 반환
Log.d("PHONE", "getCallState :" + tm.getCallState());
데이터통신 상태 조회
DATA_DISCONNECTED/DATA_CONNECTING/DATA_CONNECTED/DATA_SUSPENDED 등의 값을 반환
Log.d("PHONE", "getDataState :" + tm.getDataState());
단말기 ID 조회
GSM방식 IMEI 또는 CDMA방식의 MEID 값을 반환
Log.d("PHONE", "getDeviceId :" + tm.getDeviceId());
SW버전 조회
GSM방식의 IMEI/SV와 같은 SW버전을 반환
Log.d("PHONE", "getDeviceSoftwareVersion :" + tm.getDeviceSoftwareVersion());
전화번호 조회
GSM방식의 MSISDN과 같은 전화번호 반환
Log.d("PHONE", "getLine1Number :" + tm.getLine1Number());
국가코드 조회
현재 등록된 망 사업자의 MCC(Mobile Country Code)에 대한 ISO 국가코드 반환
Log.d("PHONE", "getNETWORKCountryIso :" + tm.getNetworkCountryIso());
Log.d("PHONE", "getSimCountryIso :" + tm.getSimCountryIso());
망 사업자코드 조회
현재 등록된 망 사업자의 MCC+MNC(Mobile Network Code) 반환
Log.d("PHONE", "getNetworkOperator :" + tm.getNetworkOperator());
Log.d("PHONE", "getSimOperator :" + tm.getSimOperator());
망 사업자명 조회
현재 등록된 망 사업자명 반환
Log.d("PHONE", "getNetworkOperatorName :" + tm.getNetworkOperatorName());
Log.d("PHONE", "getSimOperatorName :" + tm.getSimOperatorName());
망 시스템 방식 조회
현재 단말기에서 사용중인 망 시스템 방식을 반환
NETWORK_TYPE_UNKNOWN/
GSM방식 :  NETWORK_TYPE_GPRS/NETWORK_TYPE_EDGE/NETWORK_TYPE_UMTS/
NETWORK_TYPE_HSDPA/NETWORK_TYPE_HSUPA/NETWORK_TYPE_HSPA
CDMA방식 : NETWORK_TYPE_CDMA/NETWORK_TYPE_EVDO_0/NETWORK_TYPE_EVDO_A/NETWORK_TYPE_1xRTT
Log.d("PHONE", "getNetworkType :" + tm.getNetworkType());
단말기 종류 조회
단말기에서 지원하는 망의 종류를 반환
PHONE_TYPE_NONE/PHONE_TYPE_GSM/PHONE_TYPE_CDMA 등의 값을 반환
Log.d("PHONE", "getPhoneType :" + tm.getPhoneType());
SIM카드 Serial Number 조회
Log.d("PHONE", "getSimSerialNumber :" + tm.getSimSerialNumber());
SIM카드 상태 조회
SIM_STATE_UNKNOWN/SIM_STATE_ABSENT/SIM_STATE_PIN_REQUIRED/SIM_STATE_PUK_REQUIRED/
SIM_STATE_NETWORK_LOCKED/SIM_STATE_READY 등의 값을 반환
Log.d("PHONE", "getSimState :" + tm.getSimState());
가입자 ID 조회
GSM방식의 IMSI와 같은 가입자 ID 반환
Log.d("PHONE", "getSubscriberId :" + tm.getSubscriberId());

◆ 조회결과
getCallState :0(CALL_STATE_IDLE)
getDataState :2(DATA_ACTIVITY_OUT)
getDeviceId :000000000000000
getDeviceSoftwareVersion :null
getLine1Number :15555218135
getNetworkCountryIso :us
getNetworkOperator :310260
getNetworkOperatorName :Android
getNetworkType :3(NETWORK_TYPE_UMTS)
getPhoneType :1(PHONE_TYPE_GSM)
getSimCountryIso :us
getSimOperator :310260
getSimOperatorName :Android
getSimSerialNumber :89014103211118510720
getSimState :5(SIM_STATE_READY)
getSubscriberId :310260000000000

실제상황에서는 이와같이 현재 단말기의 상태를 직접 조회하는것이 아니라 
상태정보가 변경될 때 자동으로 인식해야하는 상황이 훨씬 많을것이다.
이럴때는 TelephonyManager의 listen()를 이용하여 콜백메서드를 등록하면 가능하다.
        tm.listen(new PhoneStateListener(){
         public void onCallStateChanged(int state, String incomingNumber){
         if (state == TelephonyManager.CALL_STATE_RINGING){
         Log.d("Telephony", "state = " + state + ", number = " + incomingNumber);
         }else{
         Log.d("Telephony", "state = " + state);
         }        
         }
        }, PhoneStateListener.LISTEN_CALL_STATE);

onCallStateChanged() 이외에도 아래와 같은 상태변화를 감지할 수 있다.
- onCallForwardingIndicatorChanged() : 호전환(Call Forwarding) 상태 변화
- onCellLocationChanged() : 단말기의 Cell위치 변화
- onDataActivity() : Data 활성화 상태 변화
- onDataConnectionStateChanged() : Data 연결상태 변화
- onMessageWaitingIndicatorChanged() : 메시지 대기상태 변화
- onServiceStateChanged() : 단말기의 서비스 상태 변화
- onSignalStrengthsChanged() : 망의 신호강도 변화

◆ 전화번호 처리
각 국가별로 전화번호의 형식이 다르다. 
한국은 01x-xxxx-xxxx 이 일반적이고,
북미는 xxx-xxx-xxxx가 된다.
PhoneNumberUtils.formatNumber() 메서드를 사용하면 설정된 Locale에 맞게 형식화 된다.
String formattedTelNumber = PhoneNumberUtils.formatNumber("01098761234");
        Log.d("Telephony", "formattedTelNumber :" + formattedTelNumber);
Locale을 English(United States)로 할경우 010-987-61234로 출력된다.
한국어로 할 경우는 01098761234가 그대로 출력된다.
formatNumber() 메서드의 구현내용을 살펴봐야 할듯 하다.

EditText에서 전화번호를 입력받을 경우에도 자동으로 형식화가 가능하다.
EditText객체의 addTextChangedListener에 PhoneNumberFormattingTextWatcher()를 등록하기만 하면 된다.
        EditText tn = (EditText) findViewById(R.id.edtTelNumber);
        tn.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
그러나 역시 한국어로는 동작하지 않았다


Android/View | Posted by 덩치 2014. 4. 24. 16:18

TextView에 marquee 적용하기

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


Marquee란, 전광판같은곳에서 문장을 좁은 공간에 표시하기위해


옆으로 이동하면서 숨겨진부분의 글자들이 표시되도록 하는것이다.


앞의 글자가 왼쪽으로 사라지고 뒤에 글자가 나타나는형식


Xml 레이아웃에서 텍스트뷰 속성에


        android:ellipsize="marquee"

        android:focusable="true"

        android:marqueeRepeatLimit="marquee_forever"

        android:singleLine="true"


를 추가 해 주면 된다.


첫번째는 marquee를 사용하겠다는 뜻이고,

두번째는 focusTextView가 가지고 있어야 하기때문에 설정한다.

세번째는 반복횟수인데, int값을 줘도 되고 저렇게 계~속 움직이도록 할 수 있다.

네번째는 텍스트뷰의 라인을 한줄로 표시하는것으로, 텍스트가 영역을 벗어날정도로 긴 경우에도

줄내림을 하지 않는다는것이다. 그래야 marquee가 적용된다.



아주 중요한것. 오늘 이것때문에 하루종일 씨름했는데,

setText 할 때 마다 marquee초기화되어 처음부터 표시되기에 setText가 자주 발생하는 뷰에 적용하기에는


성격이 맞지 않다.



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


Uri uri = Uri.fromParts("package", "패키지명", null);

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

startActivity(delIntent);


메소드를 하나 만들어서 패키지명을 인자로 넘겨받으면


입력값으로 넘어온 패키지를 삭제할 수 있다.


바로 삭제가 되는것이 아니라, 삭제가 가능한 화면을 띄워주는것이다.


어플단에서 바로 삭제처리하는것은 일반적으로 불가능하다고 보면 된다.



설치된 패키지 정보를 보는 방법은 이전 포스팅을 보면 된다.



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




웹뷰(Javascript)와 안드로이드간 메소드를 호출하려고 하는데 ,


안드로이드 > 자바스크립트로는 메소드 호출이 되지만


자바스크립트 > 안드로이드로는 메소드 호출이 안되는 경우가 있다.



오늘 이 현상때문에 개고생을 하다가 결국 원인을 찾아냈다.



수없이 올라오는 로그를 자세히 보니 웹뷰에서 안드로이드의 메소드를 호출 할 때


Writing exception to parcel

java.lang.SecurityException: Permission Denial: get/set setting for user asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL

at com.android.server.am.ActivityManagerService.handleIncomingUser(ActivityManagerService.java:13192)

at android.app.ActivityManager.handleIncomingUser(ActivityManager.java:2044)

at com.android.providers.settings.SettingsProvider.callFromPackage(SettingsProvider.java:615)

at android.content.ContentProvider$Transport.call(ContentProvider.java:279)

at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:273)

at android.os.Binder.execTransact(Binder.java:388)

at dalvik.system.NativeStart.run(Native Method)



이런 에러코드가 발생한다는걸 알았고,


소스코드를 아무리 변경해봐도 안되고, 퍼미션에 찾아봐도 저런 퍼미션은 없었다.


원인은 AndroidManifest.xml 파일의 android:targetSdkVersion="18" 이 문제였다.


웹뷰 > 안드로이드는 4.2버전부터 호출이 막혔다고 한다.


(http://ttorr.blogspot.kr/2014/03/kitkat44-loadurl.html)



android:targetSdkVersion16 이하로 설정하거나, 아예 없어버린 뒤 해결되었다.


==================================================================================


14/10/14 추가 : import android.webkit.JavascriptInterface; + 메소드에 @JavascriptInterface 어노테이션을 추가하면 api level 17 이상에서도 작동한다.

(http://stackoverflow.com/questions/16353430/appview-addjavascriptinterface-does-not-work-on-api-17)