एंड्रॉइड के लिए मैं कॉल लॉग का उपयोग कैसे करूं?


95

मैं कॉल लॉग प्राप्त करना चाहूंगा। उदाहरण के लिए उपयोगकर्ता द्वारा की गई कॉलों की संख्या, कहे गए मिनटों की संख्या, आदि।

मैं इसे Android में कैसे प्राप्त करूं?



मुझे लगता है कि यह कंटेंट रिज़ॉल्वर है, हालांकि मुझे इस बात की कोई जानकारी नहीं है कि बात कैसे शुरू की जाए।
3cross

जवाबों:


69

यह फोन कॉल के इतिहास तक पहुँचने के लिए है:

जेलीबीन के रूप में (4.1) आपको निम्नलिखित अनुमति की आवश्यकता है:
<uses-permission android:name="android.permission.READ_CALL_LOG" />

कोड:

 Uri allCalls = Uri.parse("content://call_log/calls");
 Cursor c = managedQuery(allCalls, null, null, null, null);

String num= c.getString(c.getColumnIndex(CallLog.Calls.NUMBER));// for  number
String name= c.getString(c.getColumnIndex(CallLog.Calls.CACHED_NAME));// for name
String duration = c.getString(c.getColumnIndex(CallLog.Calls.DURATION));// for duration
int type = Integer.parseInt(c.getString(c.getColumnIndex(CallLog.Calls.TYPE)));// for call type, Incoming or out going.

11
इस अनुमति को सक्षम करने के लिए मत भूलना: <उपयोग-अनुमति Android: name = "android.permission.READ_CALL_LOG" /> यह कॉल लॉग प्राप्त करने की विधि है:
Aziz

मुझे नहीं पता कि लेकिन सैद्धांतिक रूप से मैं कह सकता हूं कि सभी संदेश एक ही डेटाबेस में संग्रहीत हैं। तो हाँ, यह डुअल सिम या सिंगल सिम की परवाह किए बिना डिवाइस के सभी संदेशों को एक्सेस कर सकता है। इस कोड की जांच करें और मुझे बताएं कि क्या यह दोहरी सिम के साथ काम नहीं कर रहा है। मैं कुछ आर एंड डी करूंगा और आपको उसके लिए एक कोड प्रदान करेगा।
अभिनव सिंह मौर्य

1
get name हमेशा null लौट आएगा, सावधान रहें
vuhung3990

@ अभिनव सिंह मौर्य आपको कॉल लॉग्स से कॉल लॉग फोटो_ुरी प्राप्त करने में मेरी मदद कर सकते हैं क्योंकि मैं कॉल लॉग से फोटो_यूरी प्राप्त करने में सक्षम नहीं हूं
सागर

1
प्रबंधित करें () के बजाय कर्सर कर्सर = deprecated का उपयोग करते हैं।
साई गोपी मी

67

यह कॉल लॉग प्राप्त करने के लिए प्रयोग की जाने वाली विधि है। बस इस विधि को आप कक्षा में रखें और कॉल लॉग की सूची प्राप्त करें।

इसकी जांच करो

private String getCallDetails() {

        StringBuffer sb = new StringBuffer();
        Cursor managedCursor = managedQuery(CallLog.Calls.CONTENT_URI, null,
                null, null, null);
        int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
        int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
        int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
        int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
        sb.append("Call Details :");
        while (managedCursor.moveToNext()) {
            String phNumber = managedCursor.getString(number);
            String callType = managedCursor.getString(type);
            String callDate = managedCursor.getString(date);
            Date callDayTime = new Date(Long.valueOf(callDate));
            String callDuration = managedCursor.getString(duration);
            String dir = null;
            int dircode = Integer.parseInt(callType);
            switch (dircode) {
            case CallLog.Calls.OUTGOING_TYPE:
                dir = "OUTGOING";
                break;

            case CallLog.Calls.INCOMING_TYPE:
                dir = "INCOMING";
                break;

            case CallLog.Calls.MISSED_TYPE:
                dir = "MISSED";
                break;
            }
            sb.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- "
                    + dir + " \nCall Date:--- " + callDayTime
                    + " \nCall duration in sec :--- " + callDuration);
            sb.append("\n----------------------------------");
        }
        managedCursor.close();
        return sb.toString();

    }

आउटपुट दिखता है

यहां छवि विवरण दर्ज करें


मुझे ManageQuery (CallLog.Calls.CONTENT_URI, null, null, null, null) पर त्रुटि मिल रही है;
सुनील परमार

5
मैंने contentResolver.query (CallLog.Calls.CONTENT_URI, null, null, null, null) का उपयोग किया;
सुनील परमार

@ द्विवेदी जी - यह एक पुरानी पोस्ट है - आपका तरीका काम करता है लेकिन मेरे सभी कॉल लॉग्स को लोड करने में कम से कम 10 सेकंड का समय लगता है।
TheDevMan

@ दीमैन, आपकी असुविधा के लिए खेद है, हां आप सही हैं, मैं जल्द ही अपना उत्तर अपडेट करूंगा,
द्विवेदी जी

धन्यवाद मैं आपके उत्तर की प्रतीक्षा करूँगा!
TheDevMan

48

इस विधि का उपयोग हर जगह से संदर्भ के साथ करें

private static String getCallDetails(Context context) {
    StringBuffer stringBuffer = new StringBuffer();
    Cursor cursor = context.getContentResolver().query(CallLog.Calls.CONTENT_URI,
            null, null, null, CallLog.Calls.DATE + " DESC");
    int number = cursor.getColumnIndex(CallLog.Calls.NUMBER);
    int type = cursor.getColumnIndex(CallLog.Calls.TYPE);
    int date = cursor.getColumnIndex(CallLog.Calls.DATE);
    int duration = cursor.getColumnIndex(CallLog.Calls.DURATION);       
    while (cursor.moveToNext()) {
        String phNumber = cursor.getString(number);
        String callType = cursor.getString(type);
        String callDate = cursor.getString(date);
        Date callDayTime = new Date(Long.valueOf(callDate));
        String callDuration = cursor.getString(duration);
        String dir = null;
        int dircode = Integer.parseInt(callType);
        switch (dircode) {
        case CallLog.Calls.OUTGOING_TYPE:
            dir = "OUTGOING";
            break;
        case CallLog.Calls.INCOMING_TYPE:
            dir = "INCOMING";
            break;

        case CallLog.Calls.MISSED_TYPE:
            dir = "MISSED";
            break;
        }
        stringBuffer.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- "
                + dir + " \nCall Date:--- " + callDayTime
                + " \nCall duration in sec :--- " + callDuration);
        stringBuffer.append("\n----------------------------------");
    }
    cursor.close();
    return stringBuffer.toString();
}

7
चूंकि अब प्रबंधित किया गया है इसलिए यह उत्तर सबसे अधिक प्रासंगिक है।
अभि

16

यह पोस्ट थोड़ी पुरानी है, लेकिन यहां CallAndroid में लॉग्स सामग्री प्रदाता से संबंधित डेटा प्राप्त करने का एक और आसान उपाय है:

इस उपयोग का उपयोग करें: https://github.com/EverythingMe/easy-content-providers

सभी कॉल प्राप्त करें:

CallsProvider callsProvider = new CallsProvider(context);
List<Call> calls = callsProvider.getCalls().getList();

प्रत्येक कॉल में सभी फ़ील्ड होते हैं, इसलिए आप अपनी ज़रूरत की कोई भी जानकारी प्राप्त कर सकते हैं:
कॉलडेट, अवधि, संख्या, प्रकार (INCOMING, OUTGOING, MISSED), isRead, ...

यह साथ काम करता है Listया Cursorयह देखने के लिए एक नमूना ऐप है कि यह कैसा दिखता है और कैसे काम करता है।

वास्तव में, सभी Android सामग्री प्रदाताओं के लिए एक समर्थन है जैसे: संपर्क, एसएमएस, कैलेंडर, ... सभी विकल्पों के साथ पूर्ण डॉक्टर: https://github.com/EverythingMe/easy-content-providers/wiki/Android-providers

आशा है कि यह भी मदद की :)


अरे, मैंने आपके समाधान की जाँच की, यह अच्छा है। एकमात्र समस्या जो मुझे आ रही है, वह यह है कि अपने ग्रहण प्रोजेक्ट में निर्भरता को कैसे जोड़ा जाए?
आराधना

@aradhna लाइब्रेरी ग्रेडेल का उपयोग कर रही है और इसे एंड्रॉइड स्टूडियो से बनाया गया था। मुझे लगता है, आपको इसे ग्रहण पर चलने के लिए थोड़ा संशोधित करना होगा
sromku

9

मेरे प्रोजेक्ट में मुझे त्रुटि हो रही है htc device.now यह कोड सार्वभौमिक है। मुझे लगता है कि यह आपके लिए मदद है।

    public class CustomContentObserver extends ContentObserver {        
    public CustomContentObserver(Handler handler) {
        super(handler);
        System.out.println("Content obser");
    }     

    public void onChange(boolean selfChange) {
         super.onChange(selfChange);
         String lastCallnumber;

         currentDate = sdfcur.format(calender.getTime());
         System.out.println("Content obser onChange()");
         Log.d("PhoneService", "custom StringsContentObserver.onChange( " + selfChange + ")");
        //if(!callFlag){                   
         String[] projection = new String[]{CallLog.Calls.NUMBER,
                    CallLog.Calls.TYPE,
                    CallLog.Calls.DURATION,
                    CallLog.Calls.CACHED_NAME,
                    CallLog.Calls._ID};

            Cursor c;   
            c=mContext.getContentResolver().query(CallLog.Calls.CONTENT_URI, projection, null, null, CallLog.Calls._ID + " DESC");
            if(c.getCount()!=0){
                c.moveToFirst();
                 lastCallnumber = c.getString(0);
                 String type=c.getString(1);
                 String duration=c.getString(2);
                 String name=c.getString(3);
                 String id=c.getString(4);
                 System.out.println("CALLLLing:"+lastCallnumber+"Type:"+type);

                 Database db=new Database(mContext);
                 Cursor cur =db.getFirstRecord(lastCallnumber);
                 final String endCall=lastCallnumber;
                 //checking incoming/outgoing call
                 if(type.equals("3")){
                    //missed call
                    }else if(type.equals("1")){
                    //incoming call

                 }else if(type.equals("2")){
                    //outgoing call
                 }                  

            }
            c.close();
    }

}

2

केवल इनकमिंग कॉल इतिहास प्राप्त करने के लिए, नीचे कोड यू की मदद करेगा :)

private void getCallDetailsAgil() {

    StringBuffer sb = new StringBuffer();
    Cursor managedCursor = managedQuery(CallLog.Calls.CONTENT_URI, null, null, null, null);
    int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
    int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
    int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
    int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
    sb.append("Call Details :");
    while (managedCursor.moveToNext()) {
        String phNumber = managedCursor.getString(number);
        String callType = managedCursor.getString(type);
        String callDate = managedCursor.getString(date);
        Date callDayTime = new Date(Long.valueOf(callDate));
        String callDuration = managedCursor.getString(duration);
        String dir = null;
        int dircode = Integer.parseInt(callType);


        switch (dircode) {
            case CallLog.Calls.OUTGOING_TYPE:
                dir = "OUTGOING";
                break;

            case CallLog.Calls.INCOMING_TYPE:
                dir = "INCOMING";
                sb.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " + callDayTime + " \nCall duration in sec :--- " + callDuration);
                sb.append("\n----------------------------------");
                miss_cal.setText(sb);
                break;

            case CallLog.Calls.MISSED_TYPE:
                dir = "MISSED";
                break;
        }
    }

    managedCursor.close();
} 

2

इनकमिंग, आउटगोइंग और मिस्ड कॉल हिस्ट्री पाने के लिए, उम्मीद है कि यह कोड आपको मदद करेगा :)

इस कोड को अपने बैकग्राउंड थ्रेड पर कॉल करें।

StringBuffer sb = new StringBuffer();

String[] projection = new String[] {
    CallLog.Calls.CACHED_NAME,
    CallLog.Calls.NUMBER,
    CallLog.Calls.TYPE,
    CallLog.Calls.DATE,
    CallLog.Calls.DURATION
};

sb.append("Call Details :");

// String strOrder = android.provider.CallLog.Calls.DATE + " DESC";

Cursor managedCursor =  getApplicationContext().getContentResolver().query(CallLog.Calls.CONTENT_URI, projection, null, null, null);
while (managedCursor.moveToNext()) {
    String name = managedCursor.getString(0); //name
    String number = managedCursor.getString(1); // number
    String type = managedCursor.getString(2); // type 
    String date = managedCursor.getString(3); // time 
    @SuppressLint("SimpleDateFormat") 
    SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm");
    String dateString = formatter.format(new Date(Long.parseLong(date)));

    String duration = managedCursor.getString(4); // duration

    String dir = null;
    int dircode = Integer.parseInt(type);
    switch (dircode) {
        case CallLog.Calls.OUTGOING_TYPE:
            dir = "OUTGOING";
            break;
        case CallLog.Calls.INCOMING_TYPE:
            dir = "INCOMING";
            break;
        case CallLog.Calls.MISSED_TYPE:
            dir = "MISSED";
            break;
    }

sb.append("\nPhone Name :-- "+name+"  Number:--- " + number + " \nCall Type:--- " + dir + " \nCall Date:--- " + dateString + " \nCall duration in sec :--- " + duration);
sb.append("\n----------------------------------");

1

नीचे दिए गए कोड का उपयोग करें:

private void getCallDeatils() {
    StringBuffer stringBuffer = new StringBuffer();
    Cursor managedCursor = getActivity().managedQuery(CallLog.Calls.CONTENT_URI, null, null, null, null);
    int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
    int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
    int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);

    int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
    stringBuffer.append("Call Deatils");
    while (managedCursor.moveToNext()) {
        String phNumber = managedCursor.getString(number);
        String callType = managedCursor.getString(type);
        String callDate = managedCursor.getString(date);
        Date callDayTime = new Date(Long.valueOf(callDate));
        DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        String reportDate = df.format(callDayTime);
        String callDuration = managedCursor.getString(duration);
        String dir = null;
        int dircode = Integer.parseInt(callType);
        switch (dircode) {
            case CallLog.Calls.OUTGOING_TYPE:
                dir = "OUTGOING";
                break;

            case CallLog.Calls.INCOMING_TYPE:
                dir = "INCOMING";

                break;

            case CallLog.Calls.MISSED_TYPE:
                dir = "MISSED";
                break;

        }
        stringBuffer.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " +callDate + " \nCall duration in sec :--- " + callDuration);
        stringBuffer.append("\n----------------------------------");

        logs.add(new LogClass(phNumber,dir,reportDate,callDuration));




    }

0

यदि हम कोटलिन का उपयोग करते हैं तो यह छोटा है। क्लास का उदाहरण जो कॉल लॉग प्रदान करने के लिए प्रतिक्रिया करता है:

import android.content.Context
import android.database.Cursor
import android.provider.CallLog.Calls.*

class CallsLoader {

    fun getCallLogs(context: Context): List<List<String?>> {
        val c = context.applicationContext
        val projection = arrayOf(CACHED_NAME, NUMBER, TYPE, DATE, DURATION)

        val cursor = c.contentResolver.query(
             CONTENT_URI,
             projection,
             null,
             null,
             null,
             null
          )

         return cursorToMatrix(cursor)
     }

    private fun cursorToMatrix(cursor: Cursor?): List<List<String?>> {
        val matrix = mutableListOf<List<String?>>()
        cursor?.use {
             while (it.moveToNext()) {
                 val list = listOf(
                    it.getStringFromColumn(CACHED_NAME),
                    it.getStringFromColumn(NUMBER),
                    it.getStringFromColumn(TYPE),
                    it.getStringFromColumn(DATE),
                    it.getStringFromColumn(DURATION)
                 )

                 matrix.add(list.toList())
             }
          }

          return matrix
      }

     private fun Cursor.getStringFromColumn(columnName: String) =
        getString(getColumnIndex(columnName))
}

हम कर्सर को मानचित्र में भी बदल सकते हैं:

fun getCallLogs(context: Context): Map<String, Array<String?>> {
    val c = context.applicationContext
    val projection = arrayOf(CACHED_NAME, NUMBER, TYPE, DATE, DURATION)

    val cursor = c.contentResolver.query(
        CONTENT_URI,
        projection,
        null,
        null,
        null,
        null
    )

    return cursorToMap(cursor)
}

private fun cursorToMap(cursor: Cursor?): Map<String, Array<String?>> {
    val arraySize = cursor?.count ?: 0
    val map = mapOf(
        CACHED_NAME to Array<String?>(arraySize) { "" },
        NUMBER to Array<String?>(arraySize) { "" },
        TYPE to Array<String?>(arraySize) { "" },
        DATE to Array<String?>(arraySize) { "" },
        DURATION to Array<String?>(arraySize) { "" }
    )

    cursor?.use {
        for (i in 0 until arraySize) {
            it.moveToNext()

            map[CACHED_NAME]?.set(i, it.getStringFromColumn(CACHED_NAME))
            map[NUMBER]?.set(i, it.getStringFromColumn(NUMBER))
            map[TYPE]?.set(i, it.getStringFromColumn(TYPE))
            map[DATE]?.set(i, it.getStringFromColumn(DATE))
            map[DURATION]?.set(i, it.getStringFromColumn(DURATION))
        }
    }

    return map
}

0

कॉल लॉग या रीड एसएमएस अनुमति को अपने एप्लिकेशन का हिस्सा बनाने पर विचार करने से पहले, मैं आपको Google Play Market की इस नीति पर एक नज़र डालने की दृढ़ता से सलाह देता हूं: https://support.google.com/googleplay/android-developer/answer/9047303 ? hl = hi

वे अनुमतियां बहुत संवेदनशील हैं और आपको यह साबित करना होगा कि आपके आवेदन को उनकी आवश्यकता है। लेकिन यहां तक ​​कि अगर यह वास्तव में उन्हें जरूरत है, तो Google Play समर्थन टीम आसानी से उचित स्पष्टीकरण के बिना आपके अनुरोध को अस्वीकार कर सकती है।

मेरा साथ ऐसा ही हुआ था। मेरे आवेदन के प्रदर्शन वीडियो के साथ सभी आवश्यक जानकारी प्रदान करने के बाद, इस स्पष्टीकरण के साथ खारिज कर दिया गया कि मेरा "खाता मेरे आवेदन में एक निश्चित उपयोग के मामले का समाधान प्रदान करने के लिए अधिकृत नहीं है" (उपयोग के मामलों की सूची जो वे अपवाद के रूप में विचार कर सकते हैं) उस नीति पृष्ठ पर सूचीबद्ध है)। किसी भी पॉलिसी स्टेटमेंट का कोई लिंक यह बताने के लिए प्रदान नहीं किया गया था कि इसका क्या मतलब है। मूल रूप से उन्होंने सिर्फ उचित स्पष्टीकरण के बिना नहीं जाने के लिए मेरे ऐप को जज किया।

मैं आपको अपने आवेदन दोस्तों के साथ शुभकामनाएं देता हूं, लेकिन सावधान रहना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.