如何从另一个 activity 刷新我的光标?

How do I refresh my cursor from another activity?

如何从另一个 activity 刷新我的光标?

在我的主 activity 中,我启动了一个游标来查询 phone 联系人并显示在列表视图中。

在这个主 activity 中,我还有一个菜单,'Add new Contact',它开始添加新联系人 activity。正确添加了一个新联系人(我可以在 phone 上的其他联系人应用程序中看到它),但是当用户返回主 activity.

时,它在我的列表视图中不可见

有没有办法从 'add new contact' activity 刷新光标,以便用户在返回主 activity 时可以在列表视图中看到它?

我在我的主 activity 中使用 AsyncTask,如果这是任何有用的信息。我阅读了有关 swapcursor 和 changecursor 的信息,但是当我尝试使用它们时它不起作用。这是我的 'add new contact' 代码:

(我在 "Contact Saved" toast 之前调用了 changecursor,但我确定它没有正确完成。

package com.example.chris.contactlistcustomlistview;

import android.content.ContentProviderOperation;
import android.content.OperationApplicationException;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import java.util.ArrayList;

/**
 * Created by Chris on 06/05/2016.
 */
public class AddContact extends AppCompatActivity {

    EditText nameofcontact;
    EditText numberofcontact;
    public String contactname;
    public String contactnumber;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.addcontact);


        nameofcontact = (EditText) findViewById(R.id.edittextname);
        numberofcontact = (EditText) findViewById(R.id.edittextnumber);


    }

    public void createButton(View view) {
        contactname = nameofcontact.getText().toString();
        contactnumber = numberofcontact.getText().toString();

        if (contactname.length() == 0) {

            Toast.makeText(this, "Please enter a name",
                    Toast.LENGTH_LONG).show();
            return;
        }

        ArrayList<ContentProviderOperation> contentProviderOperations = new ArrayList<ContentProviderOperation>();
        //insert raw contact using RawContacts.CONTENT_URI
        contentProviderOperations.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
                .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null).withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null).build());
        //insert contact display name using Data.CONTENT_URI
        Log.d("ffff","wwww");
        contentProviderOperations.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
                .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,contactname ).build());
        //insert mobile number using Data.CONTENT_URI
        contentProviderOperations.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, contactnumber).withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE).build());
        try {
            //apply the changes
            getApplicationContext().getContentResolver().
                    applyBatch(ContactsContract.AUTHORITY, contentProviderOperations);
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (OperationApplicationException e) {
            e.printStackTrace();
        }

//        SelectContactAdapter.changeCursor(cursor);

        Toast.makeText(this, "Contact saved",
                Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return true;
    }

    //This clears the edittext next time user starts the application, rather than
//    having the same numbers there, which the user probably doesn't want anymore
    protected void onResume() {
        final EditText editText = (EditText) findViewById(R.id.edittextname);
        super.onResume();
        editText.setText("");
    }


}

这是我的 MainActivity 代码:

package com.example.chris.contactlistcustomlistview;

        import android.app.Activity;
        import android.content.ContentResolver;
        import android.content.ContentUris;
        import android.content.Intent;
        import android.database.Cursor;
        import android.database.DatabaseUtils;
        import android.graphics.Bitmap;
        import android.net.Uri;
        import android.os.AsyncTask;
        import android.os.Bundle;
        import android.provider.BaseColumns;
        import android.provider.ContactsContract;
        import android.provider.MediaStore;
        import android.util.Log;
        import android.view.MenuInflater;
        import android.view.MenuItem;
        import android.view.View;
        import android.widget.AdapterView;
        import android.widget.ImageView;
        import android.widget.ListView;
        import android.widget.PopupMenu;
        import android.widget.SearchView;
        import android.widget.TextView;
        import android.widget.Toast;

        import java.io.IOException;
        import java.util.ArrayList;
        import java.util.HashMap;
        import java.util.HashSet;
        import java.util.List;
        import java.util.Set;

public class MainActivity extends Activity implements PopupMenu.OnMenuItemClickListener {


    // ArrayList
    ArrayList<SelectContact> selectContacts;
    List<SelectContact> temp;
    // Contact List
    ListView listView;
    // Cursor to load contacts list
//    Cursor phones, email;
    Cursor pCur;

    // Pop up
//    ContentResolver resolver;
    SearchView search;
    SelectContactAdapter adapter;
    String phoneContactId;
    String name;
    String phoneNumber;
    CharSequence nameofcontact;
//    String phoneNumber;

    //    *****18-04-2016***
    Cursor cursor;
    ListView mainListView;
    ArrayList hashMapsArrayList;
//    String contactid;
//    *****


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        selectContacts = new ArrayList<SelectContact>();
//        resolver = this.getContentResolver();
        listView = (ListView) findViewById(R.id.contacts_list);



        LoadContact loadContact = new LoadContact();
        loadContact.execute();

        search = (SearchView) findViewById(R.id.searchView);


        //*** setOnQueryTextListener ***
        search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

            @Override
            public boolean onQueryTextSubmit(String query) {
                // TODO Auto-generated method stub

                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                // TODO Auto-generated method stub
                adapter.filter(newText);
                return false;
            }
        });


    }

    // Load data on background
    class LoadContact extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }


        @Override
        protected Void doInBackground(Void... voids) {

            if (cursor != null) {
                cursor.moveToFirst();

            }
            try {

//                get a handle on the Content Resolver, so we can query the provider,
                cursor = getApplicationContext().getContentResolver()
//                the table to query
                        .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
//               Null. This means that we are not making any conditional query into the contacts table.
//               Hence, all data is returned into the cursor.
//                                Projection - the columns you want to query
                                null,
//                                Selection - with this you are extracting records with assigned (by you) conditions and rules
                                null,
//                                SelectionArgs - This replaces any question marks (?) in the selection string
//                               if you have something like String[] args = { "first string", "second@string.com" };
                                null,
//                                display in ascending order
                                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC");

//                get the column number of the Contact_ID column, make it an integer.
//                I think having it stored as a number makes for faster operations later on.
                int Idx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID);
//                get the column number of the DISPLAY_NAME column
                int nameIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
//                 get the column number of the NUMBER column
                int phoneNumberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);

//                int photoIdIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI);


                cursor.moveToFirst();

//              We make a new Hashset to hold all our contact_ids, including duplicates, if they come up
                Set<String> ids = new HashSet<>();
                do {
                    System.out.println("=====>in while");
//                  get a handle on the contactid, which is a string. Loop through all the contact_ids
                    String contactid = cursor.getString(Idx);
//                  if our Hashset doesn't already contain the contactid string,
//                    then add it to the hashset
                    if (!ids.contains(contactid)) {
                        ids.add(contactid);

                        HashMap<String, String> hashMap = new HashMap<String, String>();
//                        get a handle on the display name, which is a string
                        name = cursor.getString(nameIdx);
//                        get a handle on the phone number, which is a string
                         phoneNumber = cursor.getString(phoneNumberIdx);
//                        String image = cursor.getString(photoIdIdx);
//                    System.out.println("Id--->"+contactid+"Name--->"+name);
                        System.out.println("Id--->" + contactid + " Name--->" + name);
                        System.out.println("Id--->" + contactid + " Number--->" + phoneNumber);




                        SelectContact selectContact = new SelectContact();
//                    selectContact.setThumb(bit_thumb);
                        selectContact.setName(name);
                        selectContact.setPhone(phoneNumber);
//                    selectContact.setEmail(id);
//                    selectContact.setCheckedBox(false);
                        selectContacts.add(selectContact);
                    }


                } while (cursor.moveToNext());


            } catch (Exception e) {
                e.printStackTrace();
            } finally {
//                if (cursor != null) {

//                }
            }
            cursor.close();
            return null;

        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
//into each inflate_listview, put a name and phone number, which are the details making
//            our SelectContact, above. And SelectContacts is all these inflate_listviews together
//            This is the first property of our SelectContactAdapter, a list
//            The next part, MainActivity.this, is our context, which is where we want the list to appear
            adapter = new SelectContactAdapter(selectContacts, MainActivity.this);
            listView.setAdapter(adapter);


            // Select item on listclick
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {



                         nameofcontact = ((TextView)view.findViewById(R.id.name)).getText();
//                    }
                    // Creates a new Intent to edit a contact
                        Intent intent = new Intent(Intent.ACTION_EDIT);



                    startActivity(intent);



                        listView.setFastScrollEnabled(true);
                    }



            });
        }}

        //the is the arrow image, it opens the activity for edit or new contact
        public void EditorCreateContact(View v) {


        }


        @Override
        protected void onStop() {
            super.onStop();

        }

    //    this is for the settings menu
    public void settingsPopUp(View view) {

        PopupMenu popup = new PopupMenu(this,view);
        popup.setOnMenuItemClickListener(MainActivity.this);
        MenuInflater inflater = popup.getMenuInflater();
        inflater.inflate(R.menu.popup_actions, popup.getMenu());
        popup.show();
    }



    @Override
    public boolean onMenuItemClick(MenuItem item) {
        switch (item.getItemId()) {
//            from the popup_actions.xml, identify the New_contact id and make it
//            open the AddContact class
            case R.id.New_contact:{
                Intent intent = new Intent(this, AddContact.class);
                startActivity(intent);
//                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//                startActivity(intent);
//                finish(); // Call once you redirect to another activity
            }

//                Toast.makeText(getBaseContext(), "You slected New Contact",Toast.LENGTH_SHORT).show();
//
            return true;


        }
        return false;
    }


    }

您可以使用 startActivityForResult() instead of startActivity and override onActivityResult() to requery your cursor on success. After the toasting, setResult()RESULT_OK 并完成 AddContact activity。

setResult(RESULT_OK);
finish();

首先声明行

final EditText editText = (EditText) findViewById(R.id.edittextname);

in OnCreate() ... 因为每次在 activity.

恢复时初始化视图是一种不好的做法

并查询你activity的OnResume中的数据。这是在您返回 activity.

时刷新数据的更好方法

您可以按照我在评论中提到的 onResume() 方法刷新您的联系人,为此您可以在 onResume() 本身

中执行以下操作
      LoadContact loadContact = new LoadContact();
      loadContact.execute();

你可以从 onCreate() 中删除上面的内容,因为这样调用是多余的,因为 onResume() 每次都会被调用,因为 Activity LifeCycle.

如果您使用这种方法,只需在第一行的 doInBackground() 中执行 selectContacts.clear() 来清除 ArrayList selectContacts,否则它会列出两次和三次联系人等等...

此外,正如您可以使用的同一线程中的另一个答案中提到的,startActivityForResult() 并且在 onActivityResult() 方法中您可以更新联系人列表。