我已经编写了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的信息,但此呼叫信息记录失败。
答案 0 :(得分:1)
在我看来,你以错误的方式使用BroadcastReciver。您执行的同步查询可能比处理广播的时间更长。下一个问题 - 您注册了侦听器对象,该对象可能在onReceive方法结束后由GC收集。您的BroadR应该开始处理这些事件的服务。