只要有电话,记录通话信息

时间:2010-05-27 18:55:09

标签: android

我已经编写了android应用程序,我希望应用程序在有来电时发送呼叫信息并结束。这样我就可以将所有呼叫发送到服务器,而不管呼叫记录的大小。

这是代码

public class PhoneInfo extends BroadcastReceiver {

    private int incoming_call = 0;
    private Cursor c;
    Context context;

    public void onReceive(Context con, Intent intent) {

        c = con.getContentResolver().query(
                android.provider.CallLog.Calls.CONTENT_URI, null, null, null,
                android.provider.CallLog.Calls.DATE + " DESC");
        context = con;

        IncomingCallListener phoneListener = new IncomingCallListener();
        TelephonyManager telephony = (TelephonyManager) con
                .getSystemService(Context.TELEPHONY_SERVICE);
        telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
    }
}

public class IncomingCallListener extends PhoneStateListener {

    public void onCallStateChanged(int state, String incomingNumber) {

        switch (state) {
        case TelephonyManager.CALL_STATE_IDLE:

            if (incoming_call == 1) {
                CollectSendCallInfo();
                incoming_call = 0;
            }
            break;

        case TelephonyManager.CALL_STATE_OFFHOOK:

            break;

        case TelephonyManager.CALL_STATE_RINGING:

            incoming_call = 1;
            break;

        }
    }

    private void CollectSendCallInfo() {

        int numberColumn = c
                .getColumnIndex(android.provider.CallLog.Calls.NUMBER);
        int dateColumn = c.getColumnIndex(android.provider.CallLog.Calls.DATE);

        int typeColumn = c.getColumnIndex(android.provider.CallLog.Calls.TYPE);
        int durationColumn = c
                .getColumnIndex(android.provider.CallLog.Calls.DURATION);

        ArrayList<String> callList = new ArrayList<String>();

        try {
            boolean moveToFirst = c.moveToFirst();
        }

        catch (Exception e) {
            ; // could not move to the first row.
            return;
        }
        int row_count = c.getCount();
        int loop_index = 0;
        int is_latest_call_read = 0;
        String callerPhonenumber = c.getString(numberColumn);
        int callDate = c.getInt(dateColumn);
        int callType = c.getInt(typeColumn);
        int duration = c.getInt(durationColumn);

        while ((loop_index < row_count) && (is_latest_call_read != 1)) {

            switch (callType) {
            case android.provider.CallLog.Calls.INCOMING_TYPE:
                is_latest_call_read = 1;
                break;
            case android.provider.CallLog.Calls.MISSED_TYPE:
                break;
            case android.provider.CallLog.Calls.OUTGOING_TYPE:
                break;

            }
            loop_index++;
            c.moveToNext();
        }
        SendCallInfo(callerPhonenumber, Integer.toString(duration),
                Integer.toString(callDate));
    }

    private void SendCallInfo(String callerPhonenumber, String callDuration,
            String callDate) {

        JSONObject j = new JSONObject();

        try {
            j.put("Caller", callerPhonenumber);
            j.put("Duration", callDuration);
            j.put("CallDate", callDate);

        } catch (JSONException e) {
            Toast.makeText(context, "Json object failure!", Toast.LENGTH_LONG)
                    .show();
        }

        String url = "http://xxxxxx.xxx.xx/xxxx/xxx.php";
        Map<String, String> kvPairs = new HashMap<String, String>();
        kvPairs.put("phonecall", j.toString());
        HttpResponse re;
        try {
            re = doPost(url, kvPairs);
            String temp;
            try {
                temp = EntityUtils.toString(re.getEntity());
                if (temp.compareTo("SUCCESS") == 0) {
                    ;
                }

                else
                    ;

            } catch (ParseException e1) {

                Toast.makeText(context, "Parse Exception in response!",
                        Toast.LENGTH_LONG).show();
                e1.printStackTrace();
            } catch (IOException e1) {

                Toast.makeText(context, "Io exception in response!",
                        Toast.LENGTH_LONG).show();
                e1.printStackTrace();
            }

        } catch (ClientProtocolException e1) {

            Toast.makeText(context, "Client Protocol Exception!",
                    Toast.LENGTH_LONG).show();
            e1.printStackTrace();
        } catch (IOException e1) {

            Toast.makeText(context, "Client Protocol Io exception!",
                    Toast.LENGTH_LONG).show();
            e1.printStackTrace();
        }
    }
}

这是清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.Friend" android:versionCode="1" android:versionName="1.0">

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission>
    <uses-permission android:name="android.permission.INSTALL_LOCATION_PROVIDER"></uses-permission>
    <uses-permission android:name="android.permission.SET_DEBUG_APP"></uses-permission>
    <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
    <uses-permission android:name="android.permission.READ_SMS"></uses-permission>


    <application android:icon="@drawable/icon" android:label="@string/app_name">


        <activity android:name=".Friend" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>



        <activity android:name=".LoginInfo" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.DEFAULT" />

            </intent-filter>
        </activity>


        <service android:exported="true" android:enabled="true"
            android:name=".GeoUpdateService">
        </service>

        <receiver android:name=".SmsInfo">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>

        <receiver android:name=".PhoneInfo">
            <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE"></action>
            </intent-filter>

        </receiver>


    </application>

</manifest> 

当有来电时,应用程序崩溃了。我已经能够记录有关传入SMS的信息,但此呼叫信息记录失败。

1 个答案:

答案 0 :(得分:1)

在我看来,你以错误的方式使用BroadcastReciver。您执行的同步查询可能比处理广播的时间更长。下一个问题 - 您注册了侦听器对象,该对象可能在onReceive方法结束后由GC收集。您的BroadR应该开始处理这些事件的服务。