Записывать информацию о вызовах при каждом телефонном звонке - PullRequest
0 голосов
/ 27 мая 2010

Я написал приложение для 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 Ответ

1 голос
/ 28 мая 2010

По-моему, вы используете BroadcastReciver неправильно. Вы выполняете запрос синхронизации, который может длиться больше времени, чем у вас есть для обработки трансляции. Следующая проблема - вы регистрируете объект слушателя, который, вероятно, будет собран GC сразу после завершения метода onReceive Ваш BroadR должен запустить сервис для обработки этих событий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...