Android 在MarashMallow上运行时,由于请求的游标索引超出范围索引z(大小为z),应用程序崩溃

Android 在MarashMallow上运行时,由于请求的游标索引超出范围索引z(大小为z),应用程序崩溃,android,database,cursor,Android,Database,Cursor,下面是我使用的代码: Activitymain_txt.java import android.content.ActivityNotFoundException; import android.content.DialogInterface; import android.content.Intent; import android.content.res.Configuration; import android.database.ContentObserver; import androi

下面是我使用的代码:

Activitymain_txt.java

import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;

import com.example.apple.qs.Activity.db.Constant;
import com.example.apple.qs.Activity.db.DatabaseHandler_txt;
import com.example.apple.qs.Activity.fragment.ContactFragment;
import com.example.apple.qs.Activity.fragment.FragmentAdapter;
import com.example.apple.qs.Activity.fragment.MessageFragment;
import com.example.apple.qs.Activity.db.model.Message;
import com.example.apple.qs.Activity.db.Store.ContactStore;
import com.example.apple.qs.Activity.db.Store.MessageStore;


import java.util.ArrayList;
import com.example.apple.qs.Activity.R;
import java.util.List;

public class ActivityMain_txt extends AppCompatActivity {



    private ActionBarDrawerToggle mDrawerToggle;
    private Toolbar toolbar;
    private DrawerLayout drawerLayout;
    public static MessageFragment f_message;
    private ContactFragment f_contact;
    public FloatingActionButton fab;

    private Toolbar searchToolbar;
    private boolean isSearch = false;
    private ViewPager viewPager;
    private DatabaseHandler_txt db;

    public ContactStore contacsStore;
    public MessageStore messageStore;
    public static List<Message> messageList = new ArrayList<>();

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



        setupDrawerLayout();

        db  = new DatabaseHandler_txt(getApplicationContext());

        toolbar = (Toolbar) findViewById(R.id.toolbar_viewpager);
        searchToolbar = (Toolbar) findViewById(R.id.toolbar_search);
        fab = (FloatingActionButton) findViewById(R.id.fab);

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i = new Intent(getApplicationContext(), ActivityNewMessage_txt.class);
                startActivity(i);
            }
        });

        //initToolbar();
        prepareActionBar(toolbar);

        contacsStore = new ContactStore(getApplicationContext());
        messageStore = new MessageStore(ActivityMain_txt.this);
        messageList = messageStore.getAllconversation();

        viewPager = (ViewPager) findViewById(R.id.viewpager);
        if (viewPager != null) {
            setupViewPager(viewPager);
        }

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {

                closeSearch();
                viewPager.setCurrentItem(tab.getPosition());
                if (tab.getPosition() == 0) {
                    fab.show();
                } else {
                    fab.hide();
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
            }

        });

        // for system bar in lollipop
        Window window = this.getWindow();

        if (Constant.getAPIVerison() >= 5.0) {
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setStatusBarColor(this.getResources().getColor(R.color.colorPrimaryDark));
        }
    }


    private void setupViewPager(ViewPager viewPager) {
        FragmentAdapter adapter = new FragmentAdapter(getSupportFragmentManager());

        if (f_message == null) {
            f_message = new MessageFragment();
        }

        if (f_contact == null) {
            f_contact = new ContactFragment();
        }

        adapter.addFragment(f_message, "MESSAGE");
        adapter.addFragment(f_contact, "CONTACT");

        viewPager.setAdapter(adapter);
    }

    private void prepareActionBar(Toolbar toolbar) {
        setSupportActionBar(toolbar);
        ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeButtonEnabled(true);
        if (Build.VERSION.SDK_INT >= 21) {
            getWindow().setStatusBarColor(getResources().getColor(isSearch ? android.R.color.darker_gray : R.color.colorPrimary));
        }
        if (!isSearch) {
            settingDrawer();
        }
    }

    private void settingDrawer() {
        mDrawerToggle = new ActionBarDrawerToggle( this, drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close ) {
            /** Called when a drawer has settled in a completely closed state. */
            public void onDrawerClosed(View view) {
                super.onDrawerClosed(view);
            }

            /** Called when a drawer has settled in a completely open state. */
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
            }
        };
        // Set the drawer toggle as the DrawerListener
        drawerLayout.setDrawerListener(mDrawerToggle);
    }

    private void setupDrawerLayout() {
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        NavigationView view = (NavigationView) findViewById(R.id.nav_view);
        view.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {
                menuItem.setChecked(true);
                drawerLayout.closeDrawers();
                actionDrawerMenu(menuItem.getItemId());
                return true;
            }
        });
    }

    private void actionDrawerMenu(int itemId) {
        switch (itemId) {
            case R.id.nav_notif:
                Intent i = new Intent(getApplicationContext(), ActivityNotificationSettings_txt.class);
                startActivity(i);
                break;
            case R.id.nav_rate:
                Uri uri = Uri.parse("market://details?id=" + getPackageName());
                Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
                try {
                    startActivity(goToMarket);
                } catch (ActivityNotFoundException e) {
                    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=" + getPackageName())));
                }
                break;
            case R.id.nav_about:
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("About");
                builder.setMessage(getString(R.string.about_text));
                builder.setNeutralButton("OK", null);
                builder.show();
                break;
        }
    }


    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (!isSearch) {
            mDrawerToggle.onConfigurationChanged(newConfig);
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(isSearch ? R.menu.menu_search_toolbar_txt : R.menu.menu_main_txt, menu);
        if (isSearch) {
            //Toast.makeText(getApplicationContext(), "Search " + isSearch, Toast.LENGTH_SHORT).show();
            final SearchView search = (SearchView) menu.findItem(R.id.action_search).getActionView();
            search.setIconified(false);
            if (viewPager.getCurrentItem() == 0) {
                search.setQueryHint("Search message...");
            } else {
                search.setQueryHint("Search contact...");
            }
            search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                @Override
                public boolean onQueryTextSubmit(String s) {
                    return false;
                }

                @Override
                public boolean onQueryTextChange(String s) {
                    if (viewPager.getCurrentItem() == 0) {
                        f_message.mAdapter.getFilter().filter(s);
                    } else {
                        f_contact.mAdapter.getFilter().filter(s);
                    }
                    return true;
                }
            });
            search.setOnCloseListener(new SearchView.OnCloseListener() {
                @Override
                public boolean onClose() {
                    closeSearch();
                    return true;
                }
            });
        }
        return super.onCreateOptionsMenu(menu);
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        switch (id) {
            case R.id.action_search: {
                isSearch = true;
                searchToolbar.setVisibility(View.VISIBLE);
                prepareActionBar(searchToolbar);
                supportInvalidateOptionsMenu();
                return true;
            }
            case android.R.id.home:
                closeSearch();
                return true;
            case R.id.action_refresh: {
                if(viewPager.getCurrentItem()==0){
                    new RefreshMessage().execute("");
                }else{
                    new RefreshContact().execute("");
                }
            }
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    private void closeSearch() {
        if (isSearch) {
            isSearch = false;
            if (viewPager.getCurrentItem() == 0) {
                f_message.mAdapter.getFilter().filter("");
            } else {
                f_contact.mAdapter.getFilter().filter("");
            }
            prepareActionBar(toolbar);
            searchToolbar.setVisibility(View.GONE);
            supportInvalidateOptionsMenu();
        }
    }



    private long exitTime = 0;
    public void doExitApp() {
        if ((System.currentTimeMillis() - exitTime) > 2000) {
            Toast.makeText(this, R.string.press_again_exit_app, Toast.LENGTH_SHORT).show();
            exitTime = System.currentTimeMillis();
        } else {
            finish();
        }
    }


    @Override
    public void onResume(){
        try{
            Uri uri = MessageStore.URI;
            changeObserver = new ChangeObserver();
            this.getContentResolver().registerContentObserver(uri, true, changeObserver);
        }catch (Exception e){

        }
        super.onResume();
    }

    @Override
    protected void onRestart() {
        try{
            f_message.bindView();
        }catch (Exception e){

        }
        super.onRestart();
    }

    @Override
    public void onPause(){
        this.getContentResolver().unregisterContentObserver(changeObserver);
        super.onPause();
    }

    @Override
    public void onBackPressed() {
        doExitApp();
    }

    private ChangeObserver changeObserver;
    // wil update only when there a change
    private class ChangeObserver extends ContentObserver {
        public ChangeObserver() {
            super(new Handler());
        }

        @Override
        public void onChange(boolean selfChange) {
            try{
                if(!loadRunning) {
                    loadRunning = true;
                    changeLoad = new ChangeLoad();
                    changeLoad.execute("");
                }
            }catch (Exception e){

            }

        }
    }

    private ChangeLoad changeLoad;
    private boolean loadRunning = false;

    private class ChangeLoad extends AsyncTask<String, String, String>{

        @Override
        protected String doInBackground(String... strings) {
            messageStore.update();
            return null;
        }

        @Override
        protected void onPostExecute(String s) {
            loadRunning = false;
            messageList = messageStore.getAllconversation();
            f_message.bindView();
            super.onPostExecute(s);
        }
    }

    private class RefreshMessage extends AsyncTask<String, String, String>{

        @Override
        protected void onPreExecute() {
            f_message.onRefreshLoading();
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(String... strings) {
            try {
                Thread.sleep(100);
                messageStore = new MessageStore(ActivityMain_txt.this);
                messageList = messageStore.getAllconversation();
            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPostExecute(String s) {
            f_message.onStopRefreshLoading();
            super.onPostExecute(s);
        }
    }

    private class RefreshContact extends AsyncTask<String, String, String>{

        @Override
        protected void onPreExecute() {
            f_contact.onRefreshLoading();
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(String... strings) {
            try {
                Thread.sleep(10);
                db.truncateDB();
                contacsStore = new ContactStore(getApplicationContext());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String s) {
            f_contact.onStopRefreshLoading();
            super.onPostExecute(s);
        }
    }




}
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;

import com.example.apple.qs.Activity.db.DatabaseHandler_txt;
import com.example.apple.qs.Activity.db.model.Contact;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ContactStore {
    private static Context ctx;
    private static ContentResolver sResolver;
    private static final String TAG = "ContactStore";

    private DatabaseHandler_txt db;
    private List<Contact> allContacts = new ArrayList<>();

    public ContactStore(Context context) {
        ctx = context;
        sResolver = ctx.getContentResolver();
        db = new DatabaseHandler_txt(context);

        // populate contact to database when first time
        if(db.isDatabaseEmpty()){
            //init contact data
            retriveAllContact();
            // save to database
            db.addListContact(allContacts);
        }else{
            allContacts.clear();
            allContacts = db.getAllContacts();
        }
        Collections.sort(allContacts, new Comparator<Contact>() {
            @Override
            public int compare(Contact c1, Contact c2) {
                String l1 = c1.name.toLowerCase();
                String l2 = c2.name.toLowerCase();
                return l1.compareTo(l2);
            }
        });
    }

    public Contact getByRecipientId(long recipientId) {
        Cursor addrCursor = sResolver.query(Uri.parse("content://mms-sms/canonical-address/" + recipientId), null,null, null, null);
        addrCursor.moveToFirst();
        String number = addrCursor.getString(0); // we got number here
        number=number.replace(" ", "");
        number=number.replace("-", "");
        Contact c = db.findContactByNumber(number);
        return c;
    }

    public List<Contact> getAllContacts() {
        return allContacts;
    }

    public Contact getDetailsContact(Contact c){
        return db.getDetailsContact(c);
    }

    private void retriveAllContact() {
        ContentResolver cr = ctx.getContentResolver();
        Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
        if (cur.getCount() > 0) {
            while (cur.moveToNext()) {
                long id = cur.getLong(cur.getColumnIndex(ContactsContract.Contacts._ID));
                String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                String photoId;
                try {
                    photoId = cur.getString(cur.getColumnIndex(ContactsContract.Data.PHOTO_URI));
                } catch (Exception e) {
                    photoId = "";
                }

                if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
                    List<String> phones = new ArrayList<>();
                    Cursor cursor = cr.query(
                            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                            null,
                            ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
                            new String[]{id+""}, null);

                    while (cursor.moveToNext()){
                        String p = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        p=p.replace(" ", "");
                        p=p.replace("-", "");
                        if(!phones.contains(p)){
                            phones.add(p);
                        }
                    }
                    Contact c = new Contact();
                    c.id = id;
                    c.name = name;
                    c.photoUri = photoId;
                    c.allPhoneNumber = phones;
                    allContacts.add(c);
                    cursor.close();
                }
            }
        }
    }
}
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;

import com.example.apple.qs.Activity.Activity.ActivityMain_txt;
import com.example.apple.qs.Activity.db.Constant;
import com.example.apple.qs.Activity.db.SharedPref_txt;
import com.example.apple.qs.Activity.db.model.Contact;
import com.example.apple.qs.Activity.db.model.Message;
import com.example.apple.qs.Activity.receiver.BedgeNotifier;

import java.util.ArrayList;
import java.util.List;

public class MessageStore {

    public static final Uri URI = Uri.parse("content://mms-sms/conversations?simple=true");

    public static final Uri URI_SMS = Uri.parse("content://sms");

    private ContentResolver mResolver;
    public static List<Message> allconv = new ArrayList<>();
    static Cursor cursor = null;
    private ContactStore contactStore;
    private ActivityMain_txt act;
    private Context ctx;

    private static final String TAG = "/ConvStore";

    public static final String[] PROJECTION = new String[] {
            "_id",
            "date",
            "message_count",
            "recipient_ids",
            "snippet",
            "read",
            "type"
    };

    public MessageStore(ActivityMain_txt act) {
        this.ctx = act.getApplicationContext();
        this.act = act;
        contactStore = new ContactStore(ctx);
        mResolver = ctx.getContentResolver();
        allconv = new ArrayList<>(20);
        cursor = mResolver.query(URI,
                PROJECTION,
                null,
                null,
                "date DESC"
        );
//      cursor.registerContentObserver(new ChangeObserver());
            retrieveAllConversation();
    }


    private void retrieveAllConversation(){
        update();
    }

    public void update() {
        int unread_counter = 0;
        allconv.clear();
        cursor.requery();

        if(cursor == null || cursor.getCount() == 0) {
            return;
        }



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

        cursor.moveToFirst();
        do {

            Message conv = new Message();
            conv.threadId = cursor.getLong(0);
            conv.date = cursor.getLong(1);
            conv.msgCount = cursor.getInt(2);
            conv.snippet = cursor.getString(4);
            conv.read = cursor.getInt(5) == 1;
            if(!conv.read){
                unread_counter++;
            }

            if(!allconv.contains(conv)) {
                allconv.add(conv);
            }

            int recipient_id = cursor.getInt(3);

            Contact recipient = contactStore.getByRecipientId(recipient_id);
            conv.contact = recipient;
        } while(cursor.moveToNext()); }
        SharedPref_txt.setIntPref(Constant.I_KEY_UNREAD_COUNT, unread_counter, ctx);
        BedgeNotifier.setBadge(ctx, unread_counter);
    }

    public List<Message> getAllconversation() {
        return allconv;
    }

    public void markAsRead(long threadId) {
        ContentValues cv = new ContentValues(1);
        cv.put("read", 1);
        mResolver.update(URI_SMS,
                cv,
                "read=0 AND thread_id=" + threadId,
                null
        );
    }

    /**
     * Find conversation by phone number
     *
     * @return conversation id, new id will be assigned if not exist
     **/
    public static long getOrCreateConversationId(Context context, String number){
        long cid = -1;
        Uri uri = Uri.parse("content://sms");
        Cursor cur = context.getContentResolver().query(
                uri,
                new String[] {"thread_id"},
                "address =?",
                new String[] { number},
                null);
        if(cur!=null){
            if(cur.moveToFirst()){
                cid = cur.getLong(0);
            }
            cur.close();
        }

        // Allocate new conversation_id if no match
        if(cid==-1){
            cur = context.getContentResolver().query(
                    uri,
                    new String[] {"thread_id"},
                    null,
                    null,
                    "thread_id DESC ");
            if(cur!=null){
                if(cur.moveToFirst()){
                    // new conversation_id = Max(conversation_id)+1
                    cid = cur.getLong(0)+1;
                }
                cur.close();
            }
            // no entry in the database, start the id from 10 in case smaller numbers are reserved
            if(cid==-1){
                cid=10;
            }
        }

        return cid;
    }

    public static boolean deleteMessage(Context context, String threadId) {
        int result;
        result = context.getContentResolver().delete(URI_SMS, "thread_id = ?", new String[] { threadId });
        if (result > 0) {
            return true;
        }
        return false;
    }

}
但还是无济于事。有人能帮我吗?每次我加载应用程序时,它都会崩溃


提前感谢。

在ContactStore的getRecepientById()方法中引发异常。似乎addrCursor没有记录

添加一个检查addrCursor是否有任何安全记录。如果没有最近的返回空值

Cursor addrCursor = sResolver.query(Uri.parse("content://mms-sms/canonical-address/" + recipientId), null,null, null, null);
if (addrCursor.moveToFirst()) {
  String number = addrCursor.getString(0); // we got number here
  number = number.replace(" ", "");
  number = number.replace("-", "");
  Contact c = db.findContactByNumber(number);
  return c;
} else {
  return null;
}

永远不要上传带有代码的图像,只需在此处复制/粘贴并使用“代码选项”,似乎光标未正确填充。您确定正在运行查询的表中有条目吗?
Cursor addrCursor = sResolver.query(Uri.parse("content://mms-sms/canonical-address/" + recipientId), null,null, null, null);
if (addrCursor.moveToFirst()) {
  String number = addrCursor.getString(0); // we got number here
  number = number.replace(" ", "");
  number = number.replace("-", "");
  Contact c = db.findContactByNumber(number);
  return c;
} else {
  return null;
}