안드로이드에서의 dp, dpi, px
dp를 평소에 즐겨사용했지만, 확실히 무슨 개념인지를 몰라 조사하던중에
잘 정리되어있는 블로그를 발견 !
수정(101130)
단순히 px을 dp로 변환하고자 한다면 dp = px * 0.66625로 계산한다.(해상도480*800 기준)
480*800 px => 320*533 dp이다.
출처 : http://blog.naver.com/dythmall?Redirect=Log&logNo=30096162077
dp (dip, density independent pixel) 은 안드로이드에서 여러 화면 크기를 서포트 해주기 위해서 만든 유닛이다.
[출처] 안드로이드의 dp와 px 그들은 무었인가?|작성자 dythmall
안드로이드 수신/발신 정보 가져오기 android call log
폰 사용량을 알기 위해 안드로이드 수신/발신 정보를 가져오려고 한다.
안드로이드 수신/발신 정보 가져오기 CallLog 이용
- private void getHistory() {
- String[] projection = { CallLog.Calls.CONTENT_TYPE, CallLog.Calls.NUMBER, CallLog.Calls.DURATION, CallLog.Calls.DATE };
Cursor cur = managedQuery(CallLog.Calls.CONTENT_URI, null, CallLog.Calls.TYPE + "= ?",
new String[]{ String.valueOf(CallLog.Calls.OUTGOING_TYPE) }, CallLog.Calls.DEFAULT_SORT_ORDER);
Log.d("db count=", String.valueOf(cur.getCount()));
Log.d("db count=", CallLog.Calls.CONTENT_ITEM_TYPE);
Log.d("db count=", CallLog.Calls.CONTENT_TYPE);
if(cur.moveToFirst() && cur.getCount() > 0) {
while(cur.isAfterLast() == false) {
StringBuffer sb = new StringBuffer();
sb.append("call type=").append(cur.getString(cur.getColumnIndex(CallLog.Calls.TYPE)));
sb.append(", cashed name=").append(cur.getString(cur.getColumnIndex(CallLog.Calls.CACHED_NAME)));
sb.append(", content number=").append(cur.getString(cur.getColumnIndex(CallLog.Calls.NUMBER)));
sb.append(", duration=").append(cur.getString(cur.getColumnIndex(CallLog.Calls.DURATION)));
sb.append(", new=").append(cur.getString(cur.getColumnIndex(CallLog.Calls.NEW)));
sb.append(", date=").append(timeToString(cur.getLong(cur.getColumnIndex(CallLog.Calls.DATE)))).append("]");
cur.moveToNext();
Log.d("call history[", sb.toString());
}
} - }
- androidManifest.xml에 추가
- <uses-permission android:name="android.permission.READ_CONTACTS" />
아주 편리하게도 api가 있다. CallLog를 이용해서 DB 에 저장된 내용을 가져올 수 있다.
주석 없이도 볼 수 있을 거란 생각에 주석은 생략한다.
CallLog의 경우 사용자가 전화통화내역 삭제를 누를 경우 볼 수 없다.
그리하야 별도로 call log 를 쌓으려고 한다.
방법은 직접 action을 감지하고, 통화 내역을 계산하여 별도의 DB에 쌓는 것이다.
안드로이드 수신/발신 정보 모니터링 하기
- private String LOG_TAG = "CheckCall";
private static int pState = TelephonyManager.CALL_STATE_IDLE; - public void onReceive(Context context, final Intent intent) {
TelephonyManager telManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
telManager.listen(new PhoneStateListener(){
public void onCallStateChanged(int state, String incomingNumber){
if(state != pState){
if(state == TelephonyManager.CALL_STATE_IDLE){
Toast.makeText(mContext, "IDLE" + String.valueOf(System.currentTimeMillis()), Toast.LENGTH_SHORT).show();
}
else if(state == TelephonyManager.CALL_STATE_RINGING){
Toast.makeText(mContext, "RINGING" + String.valueOf(System.currentTimeMillis() +incomingNumber), Toast.LENGTH_SHORT).show();
}
else if(state == TelephonyManager.CALL_STATE_OFFHOOK){
Toast.makeText(mContext, "OFFHOOK" + String.valueOf(System.currentTimeMillis()), Toast.LENGTH_SHORT).show();
}
pState = state;
}
}
}, PhoneStateListener.LISTEN_CALL_STATE);
if(Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())){
Log.i(LOG_TAG, "out=" + intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));
}
} -
AndroidManifest.xml
-
<receiver android:name=class name>
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver> -
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
- 참고자료
이정도 코드 역시 주석이 없이도 쉬이 할 수 있을 것 같아서 그냥 붙여 넣었다. 매니페스트에 권한과 인텐트 필터 넣는 것을 몰라 한참을 리서치 했다.
-
state
- 발신시
-
Intent.ACTION_NEW_OUTGOING_CALL -> offhook -> idle
- 수신시
-
Ring -> offhook -> idle
원문 :http://whdnfl21.springnote.com/pages/6833219
다이얼로그 생성시 BadTokenException 이슈
요즘 어플리케이션 개발에 한창입니다. 점점 안드로이드 플랫폼에 익숙해져 가는것 같습니다. 그러나 때로는 명확해 보이는 코드가 오류를 던져 대면 당혹스러워 지는군요. 이번 경우가 그렀습니다.
오류 발생 코드
- public void onCreate( Bundle $bundle ) {
- super.onCreate( $bundle ) ;
- setContentView( R.layout.ui_setting ) ;
- Button dialogShowBtn = (Button) findViewById( R.id.dialogShowBtn ) ;
- dialogShowBtn.setOnClickListener( this ) ;
- }
- public void onClick(View v) {
- // TODO Auto-generated method stub
- switch( v.getId() ) {
- case R.id.dialogShowBtn :
- CustomDialog customDialog = new CustomDialog( getApplicationContext() ) ;
- customDialog.show() ;
- break ;
- }
- }
public void onCreate( Bundle $bundle ) { super.onCreate( $bundle ) ; setContentView( R.layout.ui_setting ) ; Button dialogShowBtn = (Button) findViewById( R.id.dialogShowBtn ) ; dialogShowBtn.setOnClickListener( this ) ; } public void onClick(View v) { // TODO Auto-generated method stub switch( v.getId() ) { case R.id.dialogShowBtn : CustomDialog customDialog = new CustomDialog( getApplicationContext() ) ; customDialog.show() ; break ; } }
오류 메세지
Uncaught handler: thread main exiting due to uncaught exception android.view.WindowManager$BadTokenException: Unable to add window — token null is not for an application
해결책
- public void onCreate( Bundle $bundle ) {
- super.onCreate( $bundle ) ;
- setContentView( R.layout.ui_setting ) ;
- Button dialogShowBtn = (Button) findViewById( R.id.dialogShowBtn ) ;
- dialogShowBtn.setOnClickListener( this ) ;
- }
- public void onClick(View v) {
- // TODO Auto-generated method stub
- switch( v.getId() ) {
- case R.id.dialogShowBtn :
- CustomDialog customDialog = new CustomDialog( this ) ;
- customDialog.show() ;
- break ;
- }
- }
public void onCreate( Bundle $bundle ) { super.onCreate( $bundle ) ; setContentView( R.layout.ui_setting ) ; Button dialogShowBtn = (Button) findViewById( R.id.dialogShowBtn ) ; dialogShowBtn.setOnClickListener( this ) ; } public void onClick(View v) { // TODO Auto-generated method stub switch( v.getId() ) { case R.id.dialogShowBtn : CustomDialog customDialog = new CustomDialog( this ) ; customDialog.show() ; break ; } }
토의
일단 다이얼로그의 생성자에 인자로 보내는 Context를 getApplicationContext()로 얻어서 넘기는 대신에, Activity 자신을 직접 넘김으로써 오류를 잡는데는 성공했지만 아직까지는 명확하게 왜 이렇게 해야 하는지 알아가는 중입니다. 다만, 레퍼런스를 읽어보면 다이얼로그는 Owner Activity에 종속적으로 실행이 된다고 하는데 위에 오류 발생하는 코드를 보면 Activity를 알 길이 없습니다.
하지만 그렇다고 아래와 같은 코드도 BadTokenException 오류를 발생하기는 마찬가지였습니다.
- public void onCreate( Bundle $bundle ) {
- super.onCreate( $bundle ) ;
- setContentView( R.layout.ui_setting ) ;
- Button dialogShowBtn = (Button) findViewById( R.id.dialogShowBtn ) ;
- dialogShowBtn.setOnClickListener( this ) ;
- }
- public void onClick(View v) {
- // TODO Auto-generated method stub
- switch( v.getId() ) {
- case R.id.dialogShowBtn :
- CustomDialog customDialog = new CustomDialog( getApplicationContext() ) ;
- customDialog.setOwnerActivity( this ) ;
- customDialog.show() ;
- break ;
- }
- }
public void onCreate( Bundle $bundle ) { super.onCreate( $bundle ) ; setContentView( R.layout.ui_setting ) ; Button dialogShowBtn = (Button) findViewById( R.id.dialogShowBtn ) ; dialogShowBtn.setOnClickListener( this ) ; } public void onClick(View v) { // TODO Auto-generated method stub switch( v.getId() ) { case R.id.dialogShowBtn : CustomDialog customDialog = new CustomDialog( getApplicationContext() ) ; customDialog.setOwnerActivity( this ) ; customDialog.show() ; break ; } }