Monday, December 23, 2013

Android: How to get Call Log (통화목록 가져오기)

1. Permission

    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />      
    <uses-permission android:name="android.permission.WRITE_CALL_LOG" />

2. Source

public class MainActivity extends Activity {
   
    public static final String MESSAGE_TYPE_INBOX = "1";
    public static final String MESSAGE_TYPE_SENT = "2";
    public static final String MESSAGE_TYPE_CONVERSATIONS = "3";
    public static final String MESSAGE_TYPE_NEW = "new";

    final static private String[] CALL_PROJECTION = { CallLog.Calls.TYPE,
                                                      CallLog.Calls.CACHED_NAME, CallLog.Calls.NUMBER,
                                                      CallLog.Calls.DATE,        CallLog.Calls.DURATION };
   
    private static final String TAG = "Victor-Manage_Clique";

    private Cursor getCallHistoryCursor(Context context) {
        Cursor cursor = context.getContentResolver().query(
                                                CallLog.Calls.CONTENT_URI, CALL_PROJECTION,
                                                null, null, CallLog.Calls.DEFAULT_SORT_ORDER);      
        return cursor;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        callLog();

    }

    private void callLog() {
        int callcount = 0;
        String callname = "";
        String calltype = "";
        String calllog = "";
        Cursor curCallLog = getCallHistoryCursor(this);
        Log.i( TAG , "processSend() - 1");
        // Log.i( TAG , "curCallLog: " + curCallLog.getCount());
        if (curCallLog.moveToFirst() && curCallLog.getCount() > 0) {
            while (curCallLog.isAfterLast() == false) {
                 StringBuffer sb = new StringBuffer();

                if (curCallLog.getString(curCallLog
                        .getColumnIndex(CallLog.Calls.TYPE)).equals(MESSAGE_TYPE_INBOX)){
                    calltype = "수신";
                }
                else if (curCallLog.getString(curCallLog
                        .getColumnIndex(CallLog.Calls.TYPE)).equals(MESSAGE_TYPE_SENT)){
                    calltype = "발신";                  
                }
                else if (curCallLog.getString(curCallLog
                        .getColumnIndex(CallLog.Calls.TYPE)).equals(MESSAGE_TYPE_CONVERSATIONS)){
                    calltype = "부재중";                  
                }
               
                if (curCallLog.getString(curCallLog
                        .getColumnIndex(CallLog.Calls.CACHED_NAME)) == null) {
                    callname = "NoName";
                }
                else {
                    callname = curCallLog.getString(curCallLog
                            .getColumnIndex(CallLog.Calls.CACHED_NAME));
                }
                sb.append(timeToString(curCallLog.getLong(curCallLog
                        .getColumnIndex(CallLog.Calls.DATE))));
                sb.append("\t").append(calltype);
                sb.append("\t").append(callname);
                sb.append("\t").append(curCallLog.getString(curCallLog.getColumnIndex(CallLog.Calls.NUMBER)));
                curCallLog.moveToNext();
               
                String backupData = sb.toString();
             
                callcount++;
                Log.i("call history[", sb.toString());
            }
        }
    }

    private String timeToString(Long time) {
        SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = simpleFormat.format(new Date(time));
        return date;
    }  
}


Sunday, December 22, 2013

GSM 7Bit Table with UCS2 value


UCS2 0x82 Encoding


The encoding for '0x82' format is as follow

   1. The first octet is '0x82'

   2. The second octet is the number of UCS2 characters

   3. The third octet and fourth octet is full 16-bit Base Pointer for the UCS2

   4. The following octets are the coded characters with the following rule:

     If the MSB (most significant bit) is zero, 
       the remaining 7 bits contain GSM Default Alphabet.

     If the MSB is one, the remaining 7 bits are offset value added to Base Pointer 
       which the result defines the UCS2 character.


Example:
We have 3 UCS2: Sকদ
The characters in bytes are: '0x0053' for "S", '0x0995' for "", and '0x09A6' for "".
The coding for Alpha field for this format is: '82 03 09 95 53 80 91'.

How can we get that value?
The first octet and second octet is quite clear.
For the third and fourth octet, the Base Pointer, we can get it from the lowest value from all UCS characters. Of course, it is better if we have the UCS2 characters look-up table which indicates the Base Pointer for each specific set.

In this example, I set the Base Pointer as '0x0995'.
The fifth octet is the character "S" ('0x0053').

Since it is default alphabet, then the octet value is '0x53'.

The sixth octet is the character "" ('0x0995'). 
To encode this character, we calculate the additional offset from the Base Pointer.
Additional value = '0x0995' - '0x0995' = '0x00' = 000 0000 (only 7 bit)
The coded character has MSB set to 1. Hence the value is (1000 0000) = '0x80'.

The seventh octet is the character for "" ('0x09A6').
Additional value = 0x'09A6' - '0x0995' = '0x11' = 001 0001 (only 7 bit)
The coded character has MSB set to 1. Hence the value is (1001 0001)b = '0x91'.

UCS2 0x81 Encoding


The encoding for '81' format is as follow
   1. The first octet is '0x81'
   2. The second octet is the number of UCS2 characters
   3. The third octet is Base Pointer for bit15 to bit8 for the UCS2: 0xxxxxxxx0000000
   4. The following octets are the coded characters with the following rule: 
        - If the MSB (most significant bit) is zero, 
          the remaining 7 bits contain GSM Default Alphabet.
        If the MSB is one, the remaining 7 bits are offset value added to Base Pointer 
          which the result defines the UCS2 character.

Example:
We have 3 UCS2: Sকদ
The characters in bytes are: '0x0053' for "S", '0x0995' for "", and '0x09A6' for "".
The coding for Alpha field for this format is: '81 03 13 53 95 A6'.

How can we get that value?
First, the first octet is '0x81'.
The second octet shall be '03' since we have 3 UCS2.
The third octet is the Base Pointer. If we look at all UCS2 characters which high byte (two first digits) is not '00', then we get '0995' and '09A6'. In binaries we get:
                16                           1 (bit position)
     '0995' = 0000 1001 1001 0101
     '09A6' = 0000 1001 1010 0110

     >> 0000 1001 1000 0000 : Base pointer '0980' coded as '0x13'
So, the Base pointer value is 0001 0011 or '0x13'.
The fourth octet is the first character "S".
Since it is default alphabet, we simply set bit 7 with zero, and get 7-bits of "S":
"S" = '0053' = 0000 0000 0101 0011
                                    (0 + 1010011) = 0101 0011 = '53'
TIPS: when you get '00XX', then the octet is always the low byte XX.

The fifth octet is for character "
" ('0x0995').
To encode this character, we calculate the additional offset from the Base Pointer.
Additional value = '
0x0995' - '0x0980' = '0x15' = 001 0101 (only 7 bit)
The coded character has MSB set to 1. Hence the value is (1001
 0101) = '0x95'.

The sixth octet is the character for "
" ('0x09A6').
By doing the same way as fifth octet, we get '
0xA6'.

UCS2 0x80 Encoding


The encoding for '0x80' format is as follow:
   1. the first octet/byte is '0x80'
   2. The following octets are the 16 bit UCS characters, Little Endian format.


Example:
 We have 3 UCS2: Sকদ
The characters in bytes are: '0053' for "S", '0995' for "", and '09A6' for "".
The coding for Alpha field for this format is: '80 0053 0995 09A6'.

UCS2 Format (Kind of UCS2)


 Octet/Byte number
 1
Format 1 
0x80 
Char1 
Char1 
Char2 
Char2 
... 
... 
Format 2
0x81 
BP 
Char1 
Char2 
... 
... 
 Format 3
0x82 
BP 
BP 
Char1 
Char2 
... 


There are 3 kinds of format used by SIM to display UCS2.
N   : Count
BP : Base Point

Which one to choose: 'UCS 0x80', 'UCS 0x81', or 'UCS 0x82'?


Step1. Whenever possible, use '0x81' format.

      Strong point  : '0x81' offers smallest number of memory required, 
                           i.e. (3 + N) bytes

      Weak point    : this format only works for character set containing 128 characters 
                            that lies between 'XX00' to 'XX7F', or between 'XX80' to 'XXFF'.


Step2. If '0x81' is impossible, try the '0x82' format

      Strong point  : '0x82' offers slightly bigger number of memory required compared

                           to '0x81' format,

                           i.e. (4 + N) bytes

      Weak point    : this format only works for character set containing 128 characters


Step3. If '0x81' and '0x82' is not possible, you must use '0x80'

      Strong point  : '0x80' can cover all UCS2 range from '0000' to 'FFFF'

      Weak point    : the number of bytes required is large, i.e. (1 + 2 * N) bytes