質問

I am experiencing some unusual behaviour from my app - I cannot fathom why, but when a user selects a contact from my listview, the contact which is later retrieved from the handset is somehow not the one the user chose...

UPDATED New code, still not working.

    public class nominateContactsActivity extends ListActivity {
public String strName;
public String strTelNo;
public static final String PREFS_NAME = "locationPrefs";
public static final ArrayList<NameValuePair> contactsArray = new ArrayList<NameValuePair>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.nominatecontactsactivitytest);

this.getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
this.getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

//String[] projection = new String[] { ContactsContract.PhoneLookup.NUMBER};
String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + " = '1'";
Cursor cursor = managedQuery(ContactsContract.Contacts.CONTENT_URI,null, selection, null, null);
startManagingCursor(cursor);
String[] columns = new String[] { 
        ContactsContract.Contacts.DISPLAY_NAME
        };

int[] to = new int[] { android.R.id.text1 };

SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_multiple_choice, cursor, columns, to);
this.setListAdapter(adapter);

Button finishButton = (Button) this.findViewById(R.id.finishButton);
finishButton.setOnClickListener(new OnClickListener() {

    public void onClick(View v) {

        SimpleCursorAdapter adapter = (SimpleCursorAdapter) nominateContactsActivity.this.getListAdapter();
        ListView lv = nominateContactsActivity.this.getListView();
        SparseBooleanArray selectedItems = lv.getCheckedItemPositions();
        Cursor contactsCursor = adapter.getCursor();

        /*for (long id : lv.getCheckedItemIds()) {
            String selection = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?";
            String[] args = new String[] { String.valueOf(contactId) };
            Cursor cursor=managedQuery(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, selection, args, null);
        }*/


        for (long id : lv.getCheckedItemIds()) {
            long contactId = contactsCursor.getInt(contactsCursor.getColumnIndex(BaseColumns._ID));
            String selection = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?";
            String[] args = new String[] { String.valueOf(contactId) };
            Cursor cursor=managedQuery(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, selection, args, null);
            if (cursor.moveToFirst()) {
                strName=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                strTelNo = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));                                                      
            }
        ;}
            try {
                //Name not operationally useful - why bother storing it - keep this in case later implemented.
                //contactsArray.add(new BasicNameValuePair ("name", strName));
                contactsArray.add(new BasicNameValuePair("number", strTelNo));
            } catch(Exception e){
                e.printStackTrace();
            }

        try {
            storeContacts();
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    });
}

public void storeContacts() throws ClientProtocolException, IOException{
    SharedPreferences userPrefs = this.getSharedPreferences("PREFS_NAME", 0);
    Editor edit = userPrefs.edit();
    //edit.remove("contactsData").commit();
    String formattedString = contactsArray.toString()
            .replace("number=", "") //remove number name
            .replace(" ","")        //remove spaces
            .replace("[", "")       //remove the right bracket
            .replace("]", "");      //remove the left bracket
    edit.putString("contactsData", formattedString);
    edit.commit();
    String name = userPrefs.getString("Name", null);
    String test = userPrefs.getString("contactsData", null);
    Log.d("", formattedString);
    Log.d("test = ", test);
    Intent myIntent = new Intent(nominateContactsActivity.this, rootMenuActivity.class);
    startActivity(myIntent);
          String textSMS = "You have been nominated as a contact by " + name +". Check out www.mywebsite.com for info"; 
          String retrievedContacts = userPrefs.getString("contactsData", null);
          String textPhoneNo;
          textPhoneNo = retrievedContacts;
          //textSMS = "My current location is: " + currentLocation;
          String phoneNo = textPhoneNo;
          try {
                SmsManager smsManager = SmsManager.getDefault();
                smsManager.sendTextMessage(phoneNo, null, textSMS, null, null);
                Toast.makeText(getApplicationContext(), "SMS Sent!", Toast.LENGTH_LONG).show();
                Intent myIntent1 = new Intent(nominateContactsActivity.this, rootMenuActivity.class);
                startActivity(myIntent1);       
          } 
          catch (Exception e) {
                Toast.makeText(getApplicationContext(),
                "SMS failed, please try again later!",
                Toast.LENGTH_LONG).show();
                e.printStackTrace();
          } 

The above code works fine except from returning the wrong contact. Is this a scrolling problem, where the id of the checkbox is lost? Please help!!

Thank you

UPDATE -STACKTRACE

04-11 15:29:43.646: E/AndroidRuntime(3976): FATAL EXCEPTION: main
04-11 15:29:43.646: E/AndroidRuntime(3976): android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
04-11 15:29:43.646: E/AndroidRuntime(3976):     at android.database.AbstractCursor.checkPosition(AbstractCursor.java:424)
04-11 15:29:43.646: E/AndroidRuntime(3976):     at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
04-11 15:29:43.646: E/AndroidRuntime(3976):     at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
04-11 15:29:43.646: E/AndroidRuntime(3976):     at android.database.CursorWrapper.getString(CursorWrapper.java:114)
04-11 15:29:43.646: E/AndroidRuntime(3976):     at com.app.protect3d.nominateContactsActivity$1.onClick(nominateContactsActivity.java:123)
04-11 15:29:43.646: E/AndroidRuntime(3976):     at android.view.View.performClick(View.java:4204)
04-11 15:29:43.646: E/AndroidRuntime(3976):     at android.view.View$PerformClick.run(View.java:17355)
04-11 15:29:43.646: E/AndroidRuntime(3976):     at android.os.Handler.handleCallback(Handler.java:725)
04-11 15:29:43.646: E/AndroidRuntime(3976):     at android.os.Handler.dispatchMessage(Handler.java:92)
04-11 15:29:43.646: E/AndroidRuntime(3976):     at android.os.Looper.loop(Looper.java:137)
04-11 15:29:43.646: E/AndroidRuntime(3976):     at android.app.ActivityThread.main(ActivityThread.java:5226)
04-11 15:29:43.646: E/AndroidRuntime(3976):     at java.lang.reflect.Method.invokeNative(Native Method)
04-11 15:29:43.646: E/AndroidRuntime(3976):     at java.lang.reflect.Method.invoke(Method.java:511)
04-11 15:29:43.646: E/AndroidRuntime(3976):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
04-11 15:29:43.646: E/AndroidRuntime(3976):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
04-11 15:29:43.646: E/AndroidRuntime(3976):     at dalvik.system.NativeStart.main(Native Method)
役に立ちましたか?

解決

in onClick, you have the adapter. From it, you can get the cursor of the contacts.

Cursor contactsCursor = adapter.getCursor();

in your loop, you can get the contact id :

contactsCursor.moveToPosition(selectedPosition);
long contactId = contactsCursor.get(contactsCursor.getColumnIndex(BaseColumn._ID));

From there, you can search the Phone like this :

String selection = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?";
String[] args = new String[] { String.valueOf(contactId) };
Cursor cursor=managedQuery(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, selection, args, null);
if (cursor.moveToFirst()) {
    // Get content here
}

from there you can use the obtained cursor the way you already are.

edit - simplification (re-edit, id is really contactId)

you can simply loop on this:

for (long contactId : lv.getCheckedItemIds()) {
    String selection = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?";
    String[] args = new String[] { String.valueOf(contactId) };
    Cursor cursor=managedQuery(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, selection, args, null);
    if (cursor.moveToFirst()) {
        // Get content here
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top