Android 在MarashMallow上运行时,由于请求的游标索引超出范围索引z(大小为z),应用程序崩溃
下面是我使用的代码: Activitymain_txt.javaAndroid 在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
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;
}