출처: http://i5on9i.blogspot.kr/2015/10/blog-post_70.html
한마디만 하자면 "개판이다."!
구글은 새로운 것도 좋지만 자신들이 싼 똥들을 잘 치울 필요가 있다고 생각한다.
(물론 많이 수정도 됐지만.. 제조사, 통신사 커스텀에 대한 적정 수준의 검수/통제가 필요하다고 생각한다.)
제조사와 통신사 똥까지 합쳐져서 앱 개발자들은 똥사태의 피해자가 될 판이다.
전화번호 가져오기
, 북미에서 예전에는 MIN 을 전화번호로 사용했다고 한다.
getLine1Number 사용
Programmatically obtain the phone number of the Android phone - Stack Overflow
: 전화번호를 가져온다. 그런데 댓글들을 확인해 보면, 문제는 SIM 에 전화번호가 보통 기록되어 있지 않을 수 있다고 한다.
그래서 TelephonyManager 를 이용하는 것은 완전하지 않은 듯 보인다.
android - How to get phone number from an incoming call? - Stack Overflow
: 하지만 이처럼 incoming call 에서 전화번호를 얻어오는 것은 훨씬 가능한 일이다.
getLine1Number로 전화번호를 못가져오는 경우들
Android: getLine1Number로 전화번호가 읽어지지 않는경우? - 앱개발 질문 - 안드로이드 개발 질문/답변
getLine1Number로 전화번호가 읽어지지 않는경우 : 네이버 블로그
연락처 가져오기 방법
IMSI 와 MSISDN
- IMP's Blog: 이동통신 각종 식별번호 개념잡기(IMSI, MSISDN, MIN등)
: 이 글에서 MSISDN 부분을 보면 "전화번호" 가 무엇을 이야기 하는 지 알려준다. - IMSI Vs MSISDN
: MSISDN 이 SIM 에 없다고 이야기 해준다. 우리가 SIM을 잃어버려도 다시 SIM 만 구입해도 원래의 번호를
사용할 수 있는 것도 이 덕분이다. IMSI 는 우리가 전화기 전원을 켜서 통신사 기지국에 대한 사용을 허가받을 때 쓴다.
이녀석은 우리가 웹페이지등에 login 을 할 때 쓰는 id 같은 존재라고 보면 된다.
이 IMSI + MSISDN 을 이용해서 고유한 ID 를 형성하는 듯 하다. - IT는 이제 삶속에.. :: IMEI, IMSI, MSISDN 단말식별자
: 여기서도 IMSI 는 SIM 에 unique 하게 들어있지만, MSISDN 은 그렇지 않다고 한다.
보통 MSISDN 이 call 을 routing 하는 데 쓰인다고 한다.
Phone number 관련 library
- googlei18n/libphonenumber · GitHub : formatter 같은 것들을 제공 해 준다. 이녀석이 아마 android 내부에서 쓰이는 듯 하다.
- PhoneNumberUtils | Android Developers : 이것이 android 에서 제공하는 api 이다. 이 녀석의 내부에서 PhoneNumberUtil 이 쓰인다.
See Also
결론
일단 MSISDN 이 SIM 에 없는 경우도 있다는 것을 알았다.
그러나 기본적으로 이 방법 말고는 딱히 바로 가져올 수 있는 법이 없어 보인다.
(그래서 일부 글에서는 확실한 방법은 직접 입력하도록 하는 것이라고 한다.)
일단 이것을 가져오도록 해 놓고, edittext 등을 통해 수정할 수 있도록 해 놓는 것도 방법이 될 수 있겠다.
소스를 보면, 여러가지 방식으로 시도하는 듯 하다. 대부분의 경우 SDK 가 번호를 가져올 수 있다고 보는게 맞을 지도 모르겠다. (추측)
public String getLine1NumberForSubscriber(int subId) { String number = null; try { ITelephony telephony = getITelephony(); if (telephony != null) number = telephony.getLine1NumberForDisplay(subId, mContext.getOpPackageName()); } catch (RemoteException ex) { } catch (NullPointerException ex) { } if (number != null) { return number; } try { IPhoneSubInfo info = getSubscriberInfo(); if (info == null) return null; return info.getLine1NumberForSubscriber(subId, mContext.getOpPackageName()); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { // This could happen before phone restarts due to crashing return null; } }
안드로이드 6(Marshmallow) 에서 READ_PHONE_STATE 권한 관련 이슈
보통 아래처럼 전화번호를 가져오게 되는데, Android 6에서 갑자기 문제가 발생했다.
TelephonyManager tm = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tm.getLine1Number();
이 때문에 혹시 permission 요청을 해야하나 하고, 요청을 해봤는데도 안됐다. 이미 permission 은 GRANTED 였다.
if (checkSelfPermission(READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) { return true; }
issue 2938
그래서 한참을 찾다가 결국 bug 인 것을 알았다.아직까지 방법은 targetSdkVersion 의 버전을 낮춰놓아야 하는 듯 하다.
android { compileSdkVersion 23 buildToolsVersion "22.0.1" defaultConfig { applicationId "com.ccccc" minSdkVersion 14 targetSdkVersion 22 versionCode 1 versionName "1.0"
Intent intent = new Intent(Intent.ACTION_PICK);
2. 연락처 선택을 하면 결과값을 받아옵니다.
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { Cursor cursor = getContentResolver().query(data.getData(), new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}, null, null, null); cursor.moveToFirst(); name = cursor.getString(0); // 0은 이름을 얻어옵니다. number = cursor.getString(1); // 1은 번호를 받아옵니다. cursor.close(); } super.onActivityResult(requestCode, resultCode, data); |
[참고 1] private ArrayList<Contact> getContactList() { Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; String[] projection = new String[] { ContactsContract.CommonDataKinds.Phone.CONTACT_ID, // 연락처 ID -> 사진 정보 가져오는데 사용 ContactsContract.CommonDataKinds.Phone.NUMBER, // 연락처 ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME }; // 연락처 이름. String[] selectionArgs = null; String sortOrder = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC"; Cursor contactCursor = managedQuery(uri, projection, null, selectionArgs, sortOrder); ArrayList<Contact> contactlist = new ArrayList<Contact>(); if (contactCursor.moveToFirst()) { do { String phonenumber = contactCursor.getString(1).replaceAll("-", ""); if (phonenumber.length() == 10) { phonenumber = phonenumber.substring(0, 3) + "-" + phonenumber.substring(3, 6) + "-" + phonenumber.substring(6); } else if (phonenumber.length() > 8) { phonenumber = phonenumber.substring(0, 3) + "-" + phonenumber.substring(3, 7) + "-" + phonenumber.substring(7); } Contact acontact = new Contact(); acontact.setPhotoid(contactCursor.getLong(0)); acontact.setPhonenum(phonenumber); acontact.setName(contactCursor.getString(2)); contactlist.add(acontact); } while (contactCursor.moveToNext()); } return contactlist; }
|
[참고 2] needMobPhone을 사용할 경우 전화번호 기준으로 중복된 사람들을 필터하도록 했습니다.
|
'IT_Programming > Android_Java' 카테고리의 다른 글
배터리 사용량 액티비티 호출 & 주소록 추가 액티비티 호출 (0) | 2014.11.21 |
---|---|
[펌] 액티비티 전체를 덮는 네비게이션 드로어 만들기 (0) | 2014.11.18 |
안드로이드 커스텀뷰 이해하기 (0) | 2014.11.06 |
[펌] Android L API를 살펴보자 (0) | 2014.11.05 |
[펌] Android AsyncTaskLoader에 대하여 (0) | 2014.11.05 |