我正在开发一个发送和接收 SMS 消息的应用程序。基本思想是有一个活动来处理用户已发送消息的联系人列表,以及一个活动来查看与特定联系人的对话。所以第一个活动是一个联系人列表,当用户选择一个时,另一个活动开始,显示与所选用户的对话线程。
如果对话不太长,我所做的工作:在这种情况下,对话线程已成功显示。另一方面,如果对话包含大量消息,应用程序会加载一段时间,然后返回联系人列表,将所选联系人的电话号码添加到联系人列表中,或者只是返回联系人列表联系方式。
我不明白为什么会这样,我希望你能帮助我。这是代码:
联系人列表
import java.util.ArrayList;
import android.app.ListActivity;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.PhoneLookup;
import android.database.Cursor;
import android.widget.ArrayAdapter;
public class myActivity extends ListActivity implements onClickListener {
ArrayList<ArrayList<String>> nameAndNumbers = new ArrayList<ArrayList<String>>();
ArrayList<String> listItems=new ArrayList<String>();
ArrayAdapter<String> adapter;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
/* here I find the phone numbers of the contacts from the SMS content
provider and then I find their contact name as saved in the address book */
Uri messagesUri = Uri.parse("content://sms/");
Cursor cursor = getContentResolver().query(messagesUri,new String[] { "_id", "thread_id", "address", "person", "date", "body", "type" }, null, null, null);
startManagingCursor(cursor);
String[] columns = new String[] { "address", "person", "date", "body", "type" };
ArrayList<String> names = new ArrayList<String>();
if (cursor.getCount() > 0) {
int counter = 0;
while (cursor.moveToNext()){
String address = cursor.getString(cursor.getColumnIndex(columns[0]));
String contact=address;
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address));
Cursor cs= getContentResolver().query(uri, new String[]{PhoneLookup.DISPLAY_NAME},PhoneLookup.NUMBER+"='"+address+"'",null,null);
startManagingCursor(cs);
if(cs!=null) {
if(cs.getCount()>0)
{
cs.moveToFirst();
contact=cs.getString(cs.getColumnIndex(PhoneLookup.DISPLAY_NAME));
}
if (!names.contains(contact)) {
/* this part is needed to make it so that the app
does not create two separate threads if the phone number comes with or without
international prefix code
*/
names.add(contact);
if (contact.startsWith("+1")) {
names.add(contact.substring(2));
} else {
names.add("+1" + contact);
}
nameAndNumbers.add(new ArrayList<String>());
nameAndNumbers.get(counter).add(contact);
nameAndNumbers.get(counter).add(address);
listItems.add(contact);
counter = counter + 1;
}
}
}
}
adapter=new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
listItems);
setListAdapter(adapter);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
String number = nameAndNumbers.get(position).get(1);
Intent i = new Intent(this, myThread.class);
i.putExtra("key", number);
startActivity(i);
}
}
对话线程
import java.util.ArrayList;
import android.app.ListActivity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.PhoneLookup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
public class myThread extends ListActivity {
EditText txtMessage;
String phoneNum;
ArrayList<String> listItems=new ArrayList<String>();
ArrayAdapter<String> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.thread);
txtMessage = (EditText) findViewById(R.id.txtMessage);
ArrayList<String> list = new ArrayList<String>();
String number = getIntent().getStringExtra("key");
phoneNum = number;
list.add(number);
if (number.startsWith("+1")) {
list.add(number.substring(2));
} else {
list.add("+1" + number);
}
String[] smsNo = new String[list.size()];
list.toArray(smsNo);
Uri messagesUri = Uri.parse("content://sms/");
Cursor cursor = getContentResolver().query(messagesUri, null,"address=? or address=?", smsNo, null);
startManagingCursor(cursor);
String[] columns = new String[] { "thread_id", "address", "person", "date", "body", "type" };
String sms = "";
if (cursor.getCount() > 0) {
while (cursor.moveToNext()){
String address = cursor.getString(cursor.getColumnIndex(columns[1]));
String contact=address;
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address));
Cursor cs= getContentResolver().query(uri, new String[]{PhoneLookup.DISPLAY_NAME},PhoneLookup.NUMBER+"='"+address+"'",null,null);
startManagingCursor(cs);
if(cs!=null) {
if(cs.getCount()>0)
{
cs.moveToFirst();
contact=cs.getString(cs.getColumnIndex(PhoneLookup.DISPLAY_NAME));
}
}
sms += contact + " ";
String name = cursor.getString(cursor.getColumnIndex(columns[2]));
sms += name + " ";
String date = cursor.getString(cursor.getColumnIndex(columns[3]));
sms += date + " ";
String msg = cursor.getString(cursor.getColumnIndex(columns[4]));
sms += msg + " ";
String type = cursor.getString(cursor.getColumnIndex(columns[5]));
sms += type;
listItems.add(sms);
sms = "";
}
}
adapter=new ArrayAdapter<String>(this,
R.layout.sms_list_item,
listItems);
setListAdapter(adapter);
}
}
日志猫
我只粘贴错误消息。
05-08 10:25:52.955: E/Mms(268): [1] Tried to add duplicate Conversation to Cache
.
.
.
05-08 10:27:32.865: W/dalvikvm(175): Last 10 entries in JNI global reference table:
05-08 10:27:32.865: W/dalvikvm(175): 1991: 0x40719248 cls=Landroid/database/CursorToBulkCursorAdaptor; (44 bytes)
05-08 10:27:32.865: W/dalvikvm(175): 1992: 0x40719248 cls=Landroid/database/CursorToBulkCursorAdaptor; (44 bytes)
05-08 10:27:32.865: W/dalvikvm(175): 1993: 0x406f8b38 cls=Ljava/lang/ref/WeakReference; (28 bytes)
05-08 10:27:32.865: W/dalvikvm(175): 1994: 0x406f4d98 cls=Ljava/lang/ref/WeakReference; (28 bytes)
05-08 10:27:32.865: W/dalvikvm(175): 1995: 0x406bfd08 cls=Landroid/database/ContentObserver$Transport; (36 bytes)
05-08 10:27:32.865: W/dalvikvm(175): 1996: 0x406bc5a8 cls=Landroid/database/CursorToBulkCursorAdaptor; (44 bytes)
05-08 10:27:32.865: W/dalvikvm(175): 1997: 0x406bc5a8 cls=Landroid/database/CursorToBulkCursorAdaptor; (44 bytes)
05-08 10:27:32.865: W/dalvikvm(175): 1998: 0x406809b8 cls=Ljava/lang/ref/WeakReference; (28 bytes)
05-08 10:27:32.865: W/dalvikvm(175): 1999: 0x406809f8 cls=Ljava/lang/ref/WeakReference; (36 bytes)
05-08 10:27:32.865: W/dalvikvm(175): 2000: 0x40612b68 cls=Landroid/database/ContentObserver$Transport; (28 bytes)
05-08 10:27:32.885: W/dalvikvm(175): JNI global reference table summary (2001 entries):
05-08 10:27:32.885: W/dalvikvm(175): 36 of Ljava/lang/Class; 164B (29 unique)
05-08 10:27:32.885: W/dalvikvm(175): 44 of Ljava/lang/Class; 188B (15 unique)
05-08 10:27:32.885: W/dalvikvm(175): 6 of Ljava/lang/Class; 212B (6 unique)
05-08 10:27:32.885: W/dalvikvm(175): 10 of Ljava/lang/Class; 236B (5 unique)
05-08 10:27:32.885: W/dalvikvm(175): 1 of Ljava/lang/Class; 260B
05-08 10:27:32.895: W/dalvikvm(175): 4 of Ljava/lang/Class; 284B (2 unique)
05-08 10:27:32.895: W/dalvikvm(175): 6 of Ljava/lang/Class; 308B (5 unique)
05-08 10:27:32.895: W/dalvikvm(175): 3 of Ljava/lang/Class; 332B (2 unique)
05-08 10:27:32.895: W/dalvikvm(175): 1 of Ljava/lang/Class; 356B
05-08 10:27:32.895: W/dalvikvm(175): 2 of Ljava/lang/Class; 380B (1 unique)
05-08 10:27:32.895: W/dalvikvm(175): 1 of Ljava/lang/Class; 428B
05-08 10:27:32.895: W/dalvikvm(175): 1 of Ljava/lang/Class; 452B
05-08 10:27:32.895: W/dalvikvm(175): 1 of Ljava/lang/Class; 476B
05-08 10:27:32.895: W/dalvikvm(175): 1 of Ljava/lang/Class; 500B
05-08 10:27:32.895: W/dalvikvm(175): 1 of Ljava/lang/Class; 572B
05-08 10:27:32.895: W/dalvikvm(175): 2 of Ljava/lang/Class; 596B (2 unique)
05-08 10:27:32.895: W/dalvikvm(175): 1 of Ljava/lang/Class; 692B
05-08 10:27:32.895: W/dalvikvm(175): 1 of Ljava/lang/Class; 1004B
05-08 10:27:32.895: W/dalvikvm(175): 1 of Ljava/lang/Class; 1172B
05-08 10:27:32.895: W/dalvikvm(175): 1 of Ljava/lang/Class; 1316B
05-08 10:27:32.895: W/dalvikvm(175): 1 of Ljava/lang/Class; 3452B
05-08 10:27:32.895: W/dalvikvm(175): 1 of Ljava/lang/String; 28B
05-08 10:27:32.895: W/dalvikvm(175): 2 of Ldalvik/system/VMRuntime; 12B (1 unique)
05-08 10:27:32.895: W/dalvikvm(175): 724 of Ljava/lang/ref/WeakReference; 28B (724 unique)
05-08 10:27:32.895: W/dalvikvm(175): 28 of Ljava/lang/ref/WeakReference; 36B (28 unique)
05-08 10:27:32.895: W/dalvikvm(175): 1 of Landroid/app/ActivityThread$ProviderClientRecord; 28B
05-08 10:27:32.895: W/dalvikvm(175): 1 of Landroid/app/ActivityThread$ApplicationThread; 28B
05-08 10:27:32.905: W/dalvikvm(175): 5 of Landroid/content/ContentProvider$Transport; 28B (5 unique)
05-08 10:27:32.905: W/dalvikvm(175): 3 of Landroid/app/LoadedApk$ReceiverDispatcher$InnerReceiver; 28B (3 unique)
05-08 10:27:32.905: W/dalvikvm(175): 2 of Landroid/app/LoadedApk$ReceiverDispatcher$InnerReceiver; 36B (2 unique)
05-08 10:27:32.905: W/dalvikvm(175): 345 of Landroid/database/ContentObserver$Transport; 28B (345 unique)
05-08 10:27:32.905: W/dalvikvm(175): 23 of Landroid/database/ContentObserver$Transport; 36B (23 unique)
05-08 10:27:32.905: W/dalvikvm(175): 2 of Landroid/view/inputmethod/InputMethodManager$ControlledInputConnectionWrapper; 36B (2 unique)
05-08 10:27:32.905: W/dalvikvm(175): 2 of Landroid/view/ViewRoot$InputMethodCallback; 28B (2 unique)
05-08 10:27:32.905: W/dalvikvm(175): 1 of Landroid/view/ViewRoot$W; 28B
05-08 10:27:32.905: W/dalvikvm(175): 1 of Landroid/view/inputmethod/InputMethodManager$1; 28B
05-08 10:27:32.905: W/dalvikvm(175): 1 of Landroid/view/accessibility/AccessibilityManager$1; 28B
05-08 10:27:32.905: W/dalvikvm(175): 703 of Landroid/database/CursorToBulkCursorAdaptor; 44B (355 unique)
05-08 10:27:32.905: W/dalvikvm(175): 31 of Landroid/database/CursorToBulkCursorAdaptor; 52B (16 unique)
05-08 10:27:32.905: W/dalvikvm(175): Memory held directly by tracked refs is 73876 bytes
05-08 10:27:32.905: E/dalvikvm(175): Excessive JNI global references (2001)
05-08 10:27:32.905: E/dalvikvm(175): VM aborting
.
.
.
05-08 10:40:52.426: E/InputDispatcher(61): channel '407dd458 myApp/myApp.myActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x8
05-08 10:40:52.426: E/InputDispatcher(61): channel '407dd458 myApp/myApp.myActivityy (server)' ~ Channel is unrecoverably broken and will be disposed!
.
.
.
05-08 10:30:27.586: E/ContactsProvider(1309): Cannot determine the default account for contacts compatibility
05-08 10:30:27.586: E/ContactsProvider(1309): android.accounts.AuthenticatorException: bind failure
05-08 10:30:27.586: E/ContactsProvider(1309): at android.accounts.AccountManager.convertErrorToException(AccountManager.java:1437)
05-08 10:30:27.586: E/ContactsProvider(1309): at android.accounts.AccountManager.access$400(AccountManager.java:138)
05-08 10:30:27.586: E/ContactsProvider(1309): at android.accounts.AccountManager$BaseFutureTask$Response.onError(AccountManager.java:1342)
05-08 10:30:27.586: E/ContactsProvider(1309): at android.accounts.IAccountManagerResponse$Stub.onTransact(IAccountManagerResponse.java:69)
05-08 10:30:27.586: E/ContactsProvider(1309): at android.os.Binder.execTransact(Binder.java:320)
05-08 10:30:27.586: E/ContactsProvider(1309): at dalvik.system.NativeStart.run(Native Method)