I want to get more than 500 contact list as string in Android 6.0 and above. Below is a code that works perfectly. But if the contact list is more than 100, the application hangs. I can see people on logcat when I want to get 500 contact list. However, the user cannot do anything in the application. And the application may crash. I think this is related to the forage. I've been dealing with this problem for five days. But I didn't get any performance results. Any help, I'd appreciate it.
My Activity;
public class MainActivity extends Activity {
Cursor cursor;
ArrayList<String> vCard;
String vfile;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vfile = "Contacts" + System.currentTimeMillis() +".vcf";
getVcardString();
}
private void getVcardString() {
vCard = new ArrayList<String>();
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
if(cursor!=null&&cursor.getCount()>0){
cursor.moveToFirst();
for(int i =0;i<cursor.getCount();i++){
try {
get(cursor);
} catch (IOException e) {
e.printStackTrace();
}
cursor.moveToNext();
}
cursor.close();
}
else{
ViewAlertDashboard02();
}
}
public void get(Cursor cursor) throws IOException {
String lookupKey = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
AssetFileDescriptor fd = getBaseContext().getContentResolver().openAssetFileDescriptor(uri, "r");
FileInputStream fis = fd.createInputStream();
byte[] buf = readBytes(fis);
try {
fis.read(buf);
vcardstring = new String(buf);
vCard.add(vcardstring);
Log.d("Vcard",vcardstring);
} catch (Exception e1){
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
public byte[] readBytes(InputStream inputStream) throws IOException {
// this dynamically extends to take the bytes you read
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
// this is storage overwritten on each iteration with bytes
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
// we need to know how may bytes were read to write them to the byteBuffer
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
// and then we can return your byte array.
return byteBuffer.toByteArray();
}
}
My LogCat;
> 08-17 14:56:44.984 3530-3289/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.024 3530-32650/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.054 3530-4755/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.084 3530-4546/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.124 3530-4513/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.154 3530-4517/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.184 3530-7059/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.204 3530-3548/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.234 3530-13626/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.264 3530-3290/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.284 3530-3289/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.314 3530-3291/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.334 3530-3550/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.364 3530-3882/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.384 3530-32650/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.424 3530-3292/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.454 3530-4755/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.484 3530-26421/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.504 3530-4546/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.534 3530-3293/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.554 3530-4513/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.584 3530-4517/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.604 3530-7059/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.634 3530-3548/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.664 3530-13626/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.684 3530-3290/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.714 3530-3289/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.744 3530-3291/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.764 3530-3550/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.794 3530-3882/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.814 3530-32650/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.844 3530-3292/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.864 3530-4755/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.894 3530-26421/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.924 3530-4546/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.944 3530-3293/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.974 3530-4513/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:45.994 3530-4517/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.024 3530-7059/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.064 3530-3548/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.094 3530-13626/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.134 3530-3290/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.164 3530-3289/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.204 3530-3291/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.264 3530-3550/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.294 3530-3882/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.314 3530-3292/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.334 3530-4755/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.364 3530-26421/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.384 3530-4546/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.404 3530-3293/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.434 3530-4513/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.464 3530-3548/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.484 3530-13626/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.514 3530-7059/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.544 3530-32650/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.564 3530-4517/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.594 3530-3882/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.614 3530-4755/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.644 3530-3289/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.674 3530-4546/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.714 3530-3293/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.744 3530-3291/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.784 3530-3290/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.814 3530-3292/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.844 3530-26421/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.874 3530-3550/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.904 3530-4513/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.924 3530-3548/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.954 3530-13626/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:46.974 3530-7059/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.014 3530-32650/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.044 3530-4517/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.064 3530-3882/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.094 3530-4755/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.114 3530-3289/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.144 3530-4546/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.174 3530-3293/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.204 3530-3291/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.234 3530-3290/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.264 3530-3292/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.284 3530-26421/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.324 3530-3550/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.354 3530-4513/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.394 3530-3548/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.424 3530-13626/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.464 3530-7059/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.494 3530-32650/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.524 3530-4517/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.564 3530-3882/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.594 3530-4755/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.644 3530-3289/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.694 3530-4546/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.724 3530-3293/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.784 3530-3291/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.814 3530-3290/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.854 3530-3292/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.914 3530-26421/? E/VCardComposer: Cursor#moveToNext() returned false
> 08-17 14:56:47.954 3530-3550/? E/VCardComposer: Cursor#moveToNext() returned false
I have two problems with this code. My first problem is that it doesn't work well and the application may crash. My other problem is that if I have 500 people in my contact list, it shows more. I think the reason for this is that forcing the processor. I think it repeats a process more. Your experience and knowledge can be the solution for me. Thanks in advance.
Note: This code works seamlessly up to 100 contact list on Android 4 and above and supports the latest versions of android. You can use it.
You have two big issues there:
Phone.CONTENT_URI
and the Contacts.CONTENT_URI
For issue #1, you can change your onCreate
code to the following:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vfile = "Contacts" + System.currentTimeMillis() +".vcf";
new Thread(new Runnable() {
@Override
public void run() {
getVcardString();
}
}).start();
}
For issue #2, the problem is that your main query is to get all the phones in the DB, and then go phone-by-phone and convert the contact relevant to that phone to a vcard. so if a single contact has multiple phones, you'll be adding the same contact multiple times.
I'm assuming you need only contacts with phones, so change your main query from:
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
to:
String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1";
cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, selection, null, null);
If the fixed code still crashes, it might be OutOfMemoryError
post the exception stack here, there's some things you can improve.