Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I am trying to select the first index in listview on first load onCreate. I've try the listView.setSelection(0) but some error occur. this is my code...
public class QandAPractice extends AppCompatActivity {
String qsid;
ListView listView;
ArrayList<String> myqid;
RadioButton r1,r2,r3,r4;
String txtcontent, txtTimer,txtAnskey,txtImg, txtA, txtB, txtC, txtD, txtID;
private static final String TAG_QID = "id";
private static final String TAG_TITLE = "content";
private static final String TAG_TIMER = "timer";
private static final String TAG_IMAGE = "images";
private static final String TAG_QSID = "qsid";
private static final String TAG_KEY = "key";
private static final String TAG_A = "A";
private static final String TAG_B = "B";
private static final String TAG_C = "C";
private static final String TAG_D = "D";
ArrayList<HashMap<String, String>> questions;
Dialog quizDialog;
public int i = 60;
public int loadindex = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qand_apractice);
questions = new ArrayList<>();
myqid = new ArrayList<>();
Bundle b = getIntent().getExtras();
setTitle(b.getString("subject"));
qsid = b.getString("qsid");
quizDialog = new Dialog(this,android.R.style.Theme_Black_NoTitleBar_Fullscreen);
listView = findViewById(R.id.lvquestions);
getJSON(Constants.ROOT_URL+"mobile_question_index.php?qsid="+qsid);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
txtID = ((TextView) view.findViewById(R.id.quiz_id)).getText()
.toString();
txtcontent = ((TextView) view.findViewById(R.id.quiz_content)).getText()
.toString();
txtTimer = ((TextView) view.findViewById(R.id.quiz_timer)).getText()
.toString();
txtAnskey = ((TextView) view.findViewById(R.id.quiz_key)).getText()
.toString();
txtA = ((TextView) view.findViewById(R.id.quiz_A)).getText()
.toString();
txtB = ((TextView) view.findViewById(R.id.quiz_B)).getText()
.toString();
txtC = ((TextView) view.findViewById(R.id.quiz_C)).getText()
.toString();
txtD = ((TextView) view.findViewById(R.id.quiz_D)).getText()
.toString();
txtImg = ((TextView) view.findViewById(R.id.quiz_image)).getText()
.toString();
showQuiz();
}
});
listView.setSelection(0);
listView.getSelectedView().setSelected(true);
}
private void getJSON(final String urlWebService) {
class GetJSON extends AsyncTask<Void, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
loadIntoListView(s);
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
protected String doInBackground(Void... voids) {
try {
URL url = new URL(urlWebService);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
StringBuilder sb = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String json;
while ((json = bufferedReader.readLine()) != null) {
sb.append(json + "\n");
}
return sb.toString().trim();
} catch (Exception e) {
return null;
}
}
}
GetJSON getJSON = new GetJSON();
getJSON.execute();
}
private void loadIntoListView(String json) throws JSONException {
JSONArray jsonArray = new JSONArray(json);
//String[] question = new String[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
String id = obj.getString(TAG_QID);
String content = obj.getString(TAG_TITLE);
String image = obj.getString(TAG_IMAGE);
String a = obj.getString(TAG_A);
String b = obj.getString(TAG_B);
String c = obj.getString(TAG_C);
String d = obj.getString(TAG_D);
String key = obj.getString(TAG_KEY);
String timer = obj.getString(TAG_TIMER);
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_QID,id);
map.put(TAG_TITLE,content);
map.put(TAG_IMAGE,image);
map.put(TAG_A,a);
map.put(TAG_B,b);
map.put(TAG_C,c);
map.put(TAG_D,d);
map.put(TAG_KEY,key);
map.put(TAG_TIMER,timer);
myqid.add(id);
questions.add(map);
}
// ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, question);
SimpleAdapter adapter = new SimpleAdapter(
QandAPractice.this, questions,
R.layout.quizlayout, new String[]{TAG_QID,
TAG_TITLE, TAG_IMAGE,TAG_A,TAG_B,TAG_C,TAG_D,TAG_KEY,TAG_TIMER},
new int[]{R.id.quiz_id, R.id.quiz_content, R.id.quiz_image,R.id.quiz_A,R.id.quiz_B,
R.id.quiz_C,R.id.quiz_D,R.id.quiz_key,R.id.quiz_timer});
/* AtomicReference<ListAdapter> la =
new AtomicReference<>(new ListAdapter(getApplicationContext(), questions));*/
listView.setAdapter(adapter);
}
this is the Error fetch in debug logcat..
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setSelected(boolean)' on a null object reference
at com.example.jhan08.engineeringexclusivereviewer.QandAPractice.onCreate(QandAPractice.java:90)
at android.app.Activity.performCreate(Activity.java:6351)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1114)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2470)
I've read some thread that has the same issue like mine. They use adapter to fix the issue but still in my case this error still occur. Any help is much appreciated.
Do Your Selection after you set Your Adapter to the Listview
private void loadIntoListView(String json) throws JSONException {
JSONArray jsonArray = new JSONArray(json);
//String[] question = new String[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
String id = obj.getString(TAG_QID);
String content = obj.getString(TAG_TITLE);
String image = obj.getString(TAG_IMAGE);
String a = obj.getString(TAG_A);
String b = obj.getString(TAG_B);
String c = obj.getString(TAG_C);
String d = obj.getString(TAG_D);
String key = obj.getString(TAG_KEY);
String timer = obj.getString(TAG_TIMER);
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_QID,id);
map.put(TAG_TITLE,content);
map.put(TAG_IMAGE,image);
map.put(TAG_A,a);
map.put(TAG_B,b);
map.put(TAG_C,c);
map.put(TAG_D,d);
map.put(TAG_KEY,key);
map.put(TAG_TIMER,timer);
myqid.add(id);
questions.add(map);
}
// ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, question);
SimpleAdapter adapter = new SimpleAdapter(
QandAPractice.this, questions,
R.layout.quizlayout, new String[]{TAG_QID,
TAG_TITLE, TAG_IMAGE,TAG_A,TAG_B,TAG_C,TAG_D,TAG_KEY,TAG_TIMER},
new int[]{R.id.quiz_id, R.id.quiz_content, R.id.quiz_image,R.id.quiz_A,R.id.quiz_B,
R.id.quiz_C,R.id.quiz_D,R.id.quiz_key,R.id.quiz_timer});
/* AtomicReference<ListAdapter> la =
new AtomicReference<>(new ListAdapter(getApplicationContext(), questions));*/
listView.setAdapter(adapter);
listView.setSelection(0);
listView.getSelectedView().setSelected(true);
}
I think I got the main issue you have faced. You try to select an item before populating the list view. You need to set this after adapter added on the listview.
Add this lines after adding the adapter.
listView.setAdapter(adapter);
listView.setSelection(0);
listView.getSelectedView().setSelected(true);
or use
listView.setAdapter(adapter);
listView.setItemChecked(0, true)
This will show a toast message for first opening. This should be added after the adapter set.
Iterator myVeryOwnIterator = questions.get(0).keySet().iterator();
while(myVeryOwnIterator.hasNext()) {
String key=(String)myVeryOwnIterator.next();
String value=(String)meMap.get(key);
Toast.makeText(ctx, "Key: "+key+" Value: "+value, Toast.LENGTH_LONG).show();
}
i want to load group of images and text to item in list,so every item have 3 text view and group of image in viewpager , so i make java class contain methods to get and set text and images url,that is my code
updates i solve previous problem but when send array of string to projects class it gives me red underline error
public class Projects {
private String yourText = "";
private String yourstatu= "";
private String yourdes= "";
private String yourversion= "";
private String[] img;
public String getyourText () {
return yourText ;
}
public void setyourText(String yourText) {
this.yourText = yourText;
}
public String getyourdescription () {
return yourdes ;
}
public void setyourdescription( String yourdes) {
this.yourdes = yourdes;
}
public String getyourstatu () {
return yourstatu ;
}
public void setyourstatu( String yourstatu) {
this.yourstatu = yourstatu;
}
public String getYourversion() {
return yourversion ;
}
public void setYourversion( String yourversion) {
this.yourversion = yourversion;
}
public String getYourimages() {
return new String[] img ; // here red underline
}
public void setYourimages( String []img) {
this.img = img;
}
}
part of my main page
mProduct.setyourText(name11);
mProduct.setyourstatu(status);
mProduct.setYourversion(version);
mProduct.setyourdescription(description);
mArrayList.add(mProduct);
for (int i = 0; i < jreimages.length(); i++) {
JSONObject jjobject = jreimages.getJSONObject(i);
String imageid=jjobject.getString("project_id");
if(imageid==id){
String urlimage=jjobject.getString("screenshot");
String total=url+urlimage;
images[j]=total;
}
mProduct.getYourimages(images); // here underline error says getYourimages cannot be applied to java.lang,string[]
how to return array of strings ?
You defined an array of Strings - String[] img, so you can just return it from your function.
Just remove new String[] and left 'img' and change the return type from String to String[]
public String[] getYourimages() {
return img ;
}
maybe i can't explain exactly my problem but with the code below i hope that helps you to answering my question. am trying to pass a String data between two Activities using Intent, in the same time, inside my StringRequest, i use jSonObject to recuperate data from server using volley, so i'd like to know how to put the sames variables recuperated from server to second activity using putExtra, because i have problem of modifier, if a remove modifier for my variables i have an error in the putExtra it should be final modifier and if i put it i have an error with my jsonobject, So, what's the solution please ? thank's in advance.
String idMed;
final String numTelMed;
final String communeMed;
final String nomMed;
final String emailMed;
final String codePostalMed;
final String prenomMed;
final String rueMed;
final String villeMed;
final String specialiteMed;
final String latitude;
final String longitude;
ListView listeView;
listeView = (ListView) findViewById(R.id.sampleListView);
List<String> listeMed = new ArrayList<String>();
ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(Main_Activity.this,android.R.layout.simple_list_item_1, listeMed);
listeView.setAdapter(adapter1);
JSONArray jObjectSearch = new JSONArray(response);
Log.i("OK","JSONObjectOK : "+jObjectSearch);
Log.i("OK","JSONObjectOK : "+jObjectSearch.getString(0));
for(int i=0; i<jObjectSearch.length();i++)
{
JSONObject j = new JSONObject(jObjectSearch.getString(0));
idMed = j.getString("id");
nomMed = j.getString("nomMed");
prenomMed = j.getString("prenomMed");
numTelMed = j.getString("numTelMed");
emailMed = j.getString("emailMed");
rueMed = j.getString("rueMed");
communeMed = j.getString("communeMed");
codePostalMed = j.getString("codePostalMed");
villeMed = j.getString("villeMed");
specialiteMed = j.getString("specialiteMed");
latitude = j.getString("latitude");
longitude = j.getString("longitude");
listeMed.add("Nom : "+nomMed+"\n "+"Prénom : "+prenomMed+"\n "+"Numéro Téléphone : "+numTelMed+"\n "
+"Email : "+emailMed+"\n "+"Adresse : "+rueMed+" "+codePostalMed+" "
+villeMed+" "+communeMed+"\n "+"Spécialité : "+specialiteMed);
listeView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
medecinSearched = new Intent(Main_Activity.this, MedecinSearched.class);
medecinSearched.putExtra("nomMed", nomMed);
medecinSearched.putExtra("prenomMed", prenomMed);
medecinSearched.putExtra("numTelMed", numTelMed);
medecinSearched.putExtra("emailMed", emailMed);
medecinSearched.putExtra("rueMed", rueMed);
medecinSearched.putExtra("communeMed", communeMed);
medecinSearched.putExtra("codePostalMed", codePostalMed);
medecinSearched.putExtra("villeMed", villeMed);
medecinSearched.putExtra("specialiteMed", specialiteMed);
medecinSearched.putExtra("latitude", latitude);
medecinSearched.putExtra("longitude", longitude);
startActivity(medecinSearched);
finish();
}
});
}
If you want to use a variable inside an anonymous class you have to use the final keyword.
However, in this case I would solve this with another approach:
Create a Med class with all the properties you need id, nom, prenom, etc.
Create a MedAdapter extending BaseAdapter instead of using an ArrayAdapter<String>.
onCreate method:
listeView = (ListView) findViewById(R.id.sampleListView);
listeMed = new ArrayList<Med>();
MedAdapter adapter1 = new MedAdapter<String>(Main_Activity.this, listeMed);
listeView.setAdapter(adapter1);
listeView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Med med = listeMed.get(position);
Intent medecinSearched = new Intent(Main_Activity.this, MedecinSearched.class);
medecinSearched.putExtra("EXTRA_MED", med); // Med must implement Serializable or Parcelable
startActivity(medecinSearched);
finish();
}
});
Response callback:
JSONArray jObjectSearch = new JSONArray(response);
for(int i=0; i<jObjectSearch.length(); i++) {
JSONObject jsonObject = new JSONObject(jObjectSearch.getString(0));
Med med = new Med(jsonObject); // Med must have a constructor which receives the JSONObject.
listeMed.add(med);
}
adapter1.notifyDataSetChanged();
Hope it helps.
thank's for All, it helps me so much
I have solution but i don't know if it has an inconvenient, here is my solution :
`
String idMed; String numTelMed; String communeMed;
String nomMed; String emailMed; String codePostalMed;
String prenomMed; String rueMed; String villeMed;
String specialiteMed; String latitude; String longitude;
ListView listeView;
listeView = (ListView) findViewById(R.id.sampleListView);
List<String> listeMed = new ArrayList<String>();
ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(Main_Activity.this,android.R.layout.simple_list_item_1, listeMed);
listeView.setAdapter(adapter1);
JSONArray jObjectSearch = new JSONArray(response);
Log.i("OK","JSONObjectOK : "+jObjectSearch);
Log.i("OK","JSONObjectOK : "+jObjectSearch.getString(0));
for(int i=0; i<jObjectSearch.length();i++)
{
JSONObject j = new JSONObject(jObjectSearch.getString(0));
final String idMedF = idMed = j.getString("id");
final String nomMedF = nomMed = j.getString("nomMed");
final String prenomMedF =prenomMed = j.getString("prenomMed");
final String numTelMedF =numTelMed = j.getString("numTelMed");
final String emailMedF =emailMed = j.getString("emailMed");
final String rueMedF= rueMed = j.getString("rueMed");
final String communeMedF =communeMed = j.getString("communeMed");
final String codePostalMedF = codePostalMed = j.getString("codePostalMed");
final String villeMedF =villeMed = j.getString("villeMed");
final String specialiteMedF =specialiteMed = j.getString("specialiteMed");
final double latitudeF = j.getDouble("latitude");
final double longitudeF = j.getDouble("longitude");
listeMed.add("Nom : "+nomMed+"\n "+"Prénom : "+prenomMed+"\n "+"Numéro Téléphone : "+numTelMed+"\n "
+"Email : "+emailMed+"\n "+"Adresse : "+rueMed+" "+codePostalMed+" "
+villeMed+" "+communeMed+"\n "+"Spécialité : "+specialiteMed);
listeView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
putData(idMedF, nomMedF, prenomMedF, numTelMedF, emailMedF, rueMedF, communeMedF, codePostalMedF, villeMedF, specialiteMedF, latitudeF, longitudeF);
}
});
}
} catch (JSONException e) {
e.printStackTrace();
}
}`
Here is my main issue, after some researches, I didn't find a solution so... I would like to sort my list of custom objects. These items have a price, but for a reason they are strings not int. I would like to know how to achieve this, thanks for helping !
Little personnal question, sorting a listview and a recyclerview are they done the same way ?
EDIT:
public class Product implements Parcelable {
private String imgUrl, titre, description, prix, nomAgence, pays, ville, type_produit, nbPieces = null;
List<String> urlImageList_thumb = new ArrayList<>();
List<String> urlImageList_full = new ArrayList<>();
private int isAdded = 0;
/* getters and setters*/
}
EDIT 2 :After your help, here's my code for comparable
#Override
public int compareTo(Product otherProduct) {
String tmp = prix.replace(" €", "");
String tmp2 = otherProduct.prix.replace(" €", "");
//Integer p1 = Integer.valueOf(tmp); --> does not work
//Integer p2 = Integer.valueOf(tmp2); --> does not work
Integer p1 = Integer.parseInt(tmp); //same error
Integer p2 = Integer.parseInt(tmp2); // same error
return p1.compareTo(p2);
}
Here's the code in the activity:
bouton_tri.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Collections.sort(productList);
}
});
EDIT 3 :
#Override
public int compareTo(Product otherProduct) {
String tmp = prix.replace(" €", "").replaceAll(" ", "");
String tmp2 = otherProduct.prix.replace(" €", "").replaceAll(" ", "");
Integer p1 = Integer.valueOf(tmp);
Integer p2 = Integer.valueOf(tmp2);
return p1.compareTo(p2);
}
I still have an error, but when I just take off " €" the value is "5 300 000", if only spaces "5300000€". But putting both together gives me this error java.lang.NumberFormatException: Invalid int: "-" ... Any ideas ? Thanks
You can make modify your Product class to implement Comparable
Before converting the String to an Integer you need to remove the €and all spaces.
public class Product implements Parcelable, Comparable<Product> {
private String prix;
//...
#Override
public int compareTo(Product otherProduct) {
String tmp = prix.replace(" €", "").replaceAll(" ", "");
String tmp2 = otherProduct.prix.replace(" €", "").replaceAll(" ", "");
Integer p1 = Integer.valueOf(tmp);
Integer p2 = Integer.valueOf(tmp2);
return p1.compareTo(p2);
}
}
Once done to sort your collection you can use : Collections.sort(...); this method will take as parameter the list of custom objects you are using in your adapter.
For example:
List<Product> l = new ArrayList();
Collections.sort(l);
Note that sorting the collection will not refresh the views of the recyclerview.
You will have to call notifyDataSetChanged() on your adapter to refresh the recyclerview:
You can do this in your main activity where you have declared your adapter :
yourAdapter.notifyDataSetChanged();
Just assuming you have List<String> sampleData object
Collections.sort(sampleData, new Comparator<String>() {
#Override
public int compare(String c1, String c2) {
return Integer.valueOf(c1) - Integer.valueOf(c2);
}
});
This will sort your data.
(int) Integer.parseInt(p2.getNumberOfRecords()) - Integer.parseInt(p1.getNumberOfRecords())
So the simple compare of an integer in a String data type would not result correctly but to parse the string first by:
int value = Integer.parseInt(string)
Try this:
Collections.sort (list, new Comparator<String> () {
#Override
public int compare (String s1, String s2) {
return s1.compareToIgnoreCase(s2);
}
});
OR
Collections.sort (list, new Comparator<String> () {
#Override
public int compare (String s1, String s2) {
//cast string price to integer
int price1 = Integer.parseInt(s1);
int price2 = Integer.parseInt(s2);
if (price1 > price1) {
return 1;
}
else if (price2 > price1) {
return -1;
}
else {
return 0;
}
}
});
I use the following code to read each contacts along with their details.
private static final String[] PROJECTION =
{
Data._ID,
Data.MIMETYPE,
Data.DATA1,
Data.DATA2,
Data.DATA3,
Data.DATA4,
Data.DATA5,
Data.DATA6,
Data.DATA7,
Data.DATA8,
Data.DATA9,
Data.DATA10,
Data.DATA11,
Data.DATA12,
Data.DATA13,
Data.DATA14,
Data.DATA15
};
private static final String SELECTION = Data.LOOKUP_KEY + " = ?";
private String[] mSelectionArgs = { "" };
private static final String SORT_ORDER = Data.MIMETYPE;
private static final int MIME_TYPE_INDEX = 1;
private static final int DISPLAY_NAME_INDEX = 3;//data2
private static final int GIVEN_NAME_INDEX = 3;//data2
private static final int FAMILY_NAME_INDEX = 4;//data3
private static final int MIDDLE_NAME_INDEX = 6;//data5
private static final int ORGANIZATION_INDEX = 2;//data2
private static final int PHONE_TYPE_INDEX = 3;//data2
private static final int PHONE_LABEL_INDEX = 4;//data3
private static final int PHONE_NUMBER_INDEX = 2;//data1
private static final int EMAIL_TYPE_INDEX = 3;//data2
private static final int EMAIL_LABEL_INDEX = 4;//data1
private static final int EMAIL_INDEX = 2;//data1
private byte[] createJsonData(ArrayList<String> selected) throws JSONException, IOException{
Log.d("SynchContactActivity", "Time 1: " + java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime()));
int current = 0;
final String messagePrep = getResources().getString(R.string.progress_message_prep);
final String messageCompress = getResources().getString(R.string.progress_message_compress);
final String messageUpload = getResources().getString(R.string.progress_message_upload);
if(selected == null ){
selected = getContacts();
}
final int count = selected.size();
mHandler.post(new Runnable() {
#Override
public void run() {
if(mProgressDialog != null){
mProgressDialog.setMax(count);
mProgressDialog.setMessage(messagePrep);
}
}
});
updateProgress(current);
JSONObject root = new JSONObject();
JSONArray contactsArray = new JSONArray();
JSONObject contactJSON, phoneJSON, emailJSON;
JSONArray phonesArray,emailsArray;
String name, lastName, middleName,organization;
for (String key : selected) {
contactJSON = new JSONObject();
phonesArray = new JSONArray();
emailsArray = new JSONArray();
mSelectionArgs[0] = key;
//Cursor details = managedQuery(Data.CONTENT_URI, PROJECTION, SELECTION, mSelectionArgs, SORT_ORDER);
Cursor details = getApplicationContext().getContentResolver().query(Data.CONTENT_URI, PROJECTION, SELECTION, mSelectionArgs, SORT_ORDER);
//initialize null variables
name = null;
lastName = null;
middleName = null;
organization = null;
while(details.moveToNext()){
String mimeType = details.getString(MIME_TYPE_INDEX);
if(mimeType.equals(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)){
name = details.getString(GIVEN_NAME_INDEX);
lastName = details.getString(FAMILY_NAME_INDEX);
middleName = details.getString(MIDDLE_NAME_INDEX);
}
else if(mimeType.equals(ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE)){
organization = details.getString(ORGANIZATION_INDEX);
}
else if(mimeType.equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)){
phoneJSON = new JSONObject();
String phoneNumber = details.getString(PHONE_NUMBER_INDEX);
int type = details.getInt(PHONE_TYPE_INDEX);
String typeLabel = phoneTypeMap.get(String.valueOf(type));
if (typeLabel == null) {
typeLabel = details.getString(PHONE_LABEL_INDEX);
}
phoneJSON.put("ptype", typeLabel);
phoneJSON.put("number", phoneNumber);
phonesArray.put(phoneJSON);
}
else if(mimeType.equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)){
emailJSON = new JSONObject();
String email = details.getString(EMAIL_INDEX);
int type = details.getInt(EMAIL_TYPE_INDEX);
String typeLabel = emailTypeMap.get(String.valueOf(type));
if (typeLabel == null) {
typeLabel = details.getString(EMAIL_LABEL_INDEX);
}
emailJSON.put("etype", typeLabel);
emailJSON.put("address",email);
emailsArray.put(emailJSON);
}
}
contactJSON.put("firstname", name==null?"null":name);
contactJSON.put("middlename", middleName==null?"null":middleName);
contactJSON.put("lastname", lastName==null?"null":lastName);
contactJSON.put("organization", organization==null?"null":organization);
contactJSON.put("phones", phonesArray);
contactJSON.put("emails", emailsArray);
contactsArray.put(contactJSON);
details.close();
++current;
updateProgress(current);
}
root.put("contacts", contactsArray);
Log.d("SynchContactActivity", "Time 1: " + java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime()));
mHandler.post(new Runnable() {
#Override
public void run() {
if(mProgressDialog != null){
mProgressDialog.setMessage(messageCompress);
}
}
});
// to compress
String json_doc = root.toString();
byte[] compressed = compress(json_doc);
mHandler.post(new Runnable() {
#Override
public void run() {
if(mProgressDialog != null){
mProgressDialog.setMessage(messageUpload);
}
}
});
return compressed;
}
This code is too slow - that reads 3-4 contacts per second on average. Is this normal or can be optimized?
I think projection might be a good candidate to be optimized but I'm not sure.
Thanks in advance.
It's hard for me to tell exactly what you're trying to do, but it looks like you're trying to read data from the Contacts Provider and send it to a server using JSON. I suggest you look at the ContactsContract.RawContacts.Entity table, which contains all the data you're probably looking for without the mess of trying to figure out the MIME type of the DATA row you've just retrieved. You're certainly slowing down your app by getting the entire contents of the DATA row.
In addition, you should use a SyncAdapter to do this work. See Transferring Data Using Sync Adapters
Reading contacts can be made in 2-5 seconds. See the example app here
Source code attached