SQLite 异常错误,使用 CursorLoader 和 ContactContracts
Posted
技术标签:
【中文标题】SQLite 异常错误,使用 CursorLoader 和 ContactContracts【英文标题】:SQLite Exception error, using CursorLoader & ContactContracts 【发布时间】:2015-02-24 04:46:50 【问题描述】:我正在尝试将 ListView(即片段)填充到加载 android 手机联系人的活动中。而且由于我不熟悉 SQLite 样式的查询,我可能弄乱了语法,因为我收到了这个错误:
java.lang.RuntimeException: An error occurred while executing doInBackground()
Caused by: android.database.sqlite.SQLiteException: near "display_name": syntax error (code 1): , while compiling: SELECT _id, photo_thumb_uri, display_name, has_phone_number FROM view_contacts_restricted WHERE ((1)) AND ((photo_thumb_uri=?display_name=?has_phone_number=?)) ORDER BY display_nameASC
两个问题:
下面是我的片段代码和我的 logcat。有什么看起来不对吗? (是什么导致了错误?)
我没有使用片段 xml 布局(虽然我之前尝试过,所以注释掉的代码仍然存在),因为我读到 CursorLoader 创建自己的布局。这是一个正确的假设吗?
ContactsFragment.java
package org.azurespot.practiceapp.addressbook;
import android.app.ListFragment;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.ContentUris;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import com.example.practiceapp.R;
/*
* Partially from http://***.com/questions/18199359/how-to-display-contacts-in-a-listview-in-android-for-android-api-11
*/
public class ContactsFragment extends ListFragment implements
LoaderCallbacks<Cursor>
private CursorAdapter mAdapter;
public ListView listView;
public Cursor cursor;
private android.content.Context context;
public View view;
public static Uri uri;
public static final String[] FROM =
ContactsContract.Contacts.PHOTO_THUMBNAIL_URI,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
ContactsContract.Contacts.HAS_PHONE_NUMBER ;
private static final int[] TO = R.id.contact_thumbnail,
R.id.contact_name, R.id.contact_number ;
// columns requested from the database
private static final String[] PROJECTION =
Contacts._ID,
ContactsContract.Contacts.PHOTO_THUMBNAIL_URI,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
;
// this goes in the CursorLoader parameter list, it filters
// out only those contacts who have a phone number
private static final String FILTER =
ContactsContract.Contacts.PHOTO_THUMBNAIL_URI + "=?" +
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + "=?" +
ContactsContract.Contacts.HAS_PHONE_NUMBER + "=?";
private static final String[] SELECTION_ARGS =
ContactsContract.Contacts.PHOTO_THUMBNAIL_URI,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
ContactsContract.Contacts.HAS_PHONE_NUMBER
;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
// delete list if already there (old version)
if (!(listView == null))
listView.setAdapter(null);
// create adapter once
context = getActivity();
int layout = android.R.layout.simple_list_item_1;
Cursor c = null; // there is no cursor yet
int flags = 0; // no auto-requery! Loader requeries.
// put List in adapter
mAdapter = new SimpleCursorAdapter(context, layout, c, FROM, TO, flags);
// end onCreate
// Empty public constructor, required by the system
public ContactsFragment()
// A UI Fragment must inflate its View (all fragments must override onCreateView)
// @Override
// public View onCreateView(LayoutInflater inflater, ViewGroup container,
// Bundle savedInstanceState)
// // Inflate the fragment layout
// View view = inflater.inflate(R.layout.fragment_list_view,
// container, false);
// listView = (ListView) view.findViewById(R.id.contact_list);
//
// return view;
//
public void onActivityCreated(Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
// every time we start, use a list adapter
setListAdapter(mAdapter);
// // scroll faster
// listView.setFastScrollEnabled(true);
// and tell loader manager to start loading
getLoaderManager().initLoader(0, null, this);
// a CursorLoader does a query in the background
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args)
// load from the "Contacts table"
Uri contentUri = Contacts.CONTENT_URI;
// no sub-selection, no sort order, simply every row
// projection says we want just the _id and the name column
return new CursorLoader(getActivity(),
contentUri,
PROJECTION,
FILTER,
SELECTION_ARGS,
ContactsContract.Contacts.DISPLAY_NAME + "ASC");
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data)
// Once cursor is loaded, give it to adapter
mAdapter.swapCursor(data);
@Override
public void onLoaderReset(Loader<Cursor> loader)
// Delete the reference to the existing Cursor,
// so it can recycle it
mAdapter.swapCursor(null);
Logcat
12-26 20:45:16.398: I/PersonaManager(18479): getPersonaService() name persona_policy
12-26 20:45:16.478: D/skia(18479): GFXPNG PNG bitmap created width:48 height:48 bitmap id is 270
12-26 20:45:16.478: E/MoreInfoHPW_ViewGroup(18479): Parent view is not a TextView
12-26 20:45:16.488: D/skia(18479): GFXPNG PNG bitmap created width:72 height:72 bitmap id is 271
12-26 20:45:16.498: D/skia(18479): GFXPNG PNG bitmap created width:144 height:144 bitmap id is 272
12-26 20:45:16.508: D/skia(18479): GFXPNG PNG bitmap created width:144 height:144 bitmap id is 273
12-26 20:45:16.558: I/Adreno-EGL(18479): <qeglDrvAPI_eglInitialize:410>: EGL 1.4 QUALCOMM build: ()
12-26 20:45:16.558: I/Adreno-EGL(18479): OpenGL ES Shader Compiler Version: E031.24.00.08+13
12-26 20:45:16.558: I/Adreno-EGL(18479): Build Date: 03/20/14 Thu
12-26 20:45:16.558: I/Adreno-EGL(18479): Local Branch: 0320_AU200_patches
12-26 20:45:16.558: I/Adreno-EGL(18479): Remote Branch:
12-26 20:45:16.558: I/Adreno-EGL(18479): Local Patches:
12-26 20:45:16.558: I/Adreno-EGL(18479): Reconstruct Branch:
12-26 20:45:16.638: D/OpenGLRenderer(18479): Enabling debug mode 0
12-26 20:45:17.678: I/PersonaManager(18479): getPersonaService() name persona_policy
12-26 20:45:17.688: E/MoreInfoHPW_ViewGroup(18479): Parent view is not a TextView
12-26 20:45:17.708: D/skia(18479): GFXPNG PNG bitmap created width:228 height:228 bitmap id is 274
12-26 20:45:17.708: D/skia(18479): GFXPNG PNG bitmap created width:228 height:228 bitmap id is 275
12-26 20:45:17.718: D/skia(18479): GFXPNG PNG bitmap created width:12 height:12 bitmap id is 276
12-26 20:45:17.718: D/AbsListView(18479): Get MotionRecognitionManager
12-26 20:45:17.728: D/AbsListView(18479): onVisibilityChanged() is called, visibility : 8
12-26 20:45:17.728: D/AbsListView(18479): unregisterIRListener() is called
12-26 20:45:17.728: D/AbsListView(18479): onVisibilityChanged() is called, visibility : 0
12-26 20:45:17.728: D/AbsListView(18479): unregisterIRListener() is called
12-26 20:45:17.738: D/AbsListView(18479): onVisibilityChanged() is called, visibility : 4
12-26 20:45:17.738: D/AbsListView(18479): unregisterIRListener() is called
12-26 20:45:17.738: D/AbsListView(18479): onVisibilityChanged() is called, visibility : 0
12-26 20:45:17.738: D/AbsListView(18479): unregisterIRListener() is called
12-26 20:45:17.748: D/AbsListView(18479): unregisterIRListener() is called
12-26 20:45:17.768: W/dalvikvm(18479): threadid=11: thread exiting with uncaught exception (group=0x41737da0)
12-26 20:45:17.768: E/AndroidRuntime(18479): FATAL EXCEPTION: AsyncTask #1
12-26 20:45:17.768: E/AndroidRuntime(18479): Process: com.example.practiceapp, PID: 18479
12-26 20:45:17.768: E/AndroidRuntime(18479): java.lang.RuntimeException: An error occured while executing doInBackground()
12-26 20:45:17.768: E/AndroidRuntime(18479): at android.os.AsyncTask$3.done(AsyncTask.java:300)
12-26 20:45:17.768: E/AndroidRuntime(18479): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
12-26 20:45:17.768: E/AndroidRuntime(18479): at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
12-26 20:45:17.768: E/AndroidRuntime(18479): at java.util.concurrent.FutureTask.run(FutureTask.java:242)
12-26 20:45:17.768: E/AndroidRuntime(18479): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
12-26 20:45:17.768: E/AndroidRuntime(18479): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
12-26 20:45:17.768: E/AndroidRuntime(18479): at java.lang.Thread.run(Thread.java:841)
12-26 20:45:17.768: E/AndroidRuntime(18479): Caused by: android.database.sqlite.SQLiteException: near "display_name": syntax error (code 1): , while compiling: SELECT _id, photo_thumb_uri, display_name, has_phone_number FROM view_contacts_restricted WHERE ((1)) AND ((photo_thumb_uri=?display_name=?has_phone_number=?)) ORDER BY display_nameASC
12-26 20:45:17.768: E/AndroidRuntime(18479): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:181)
12-26 20:45:17.768: E/AndroidRuntime(18479): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
12-26 20:45:17.768: E/AndroidRuntime(18479): at android.content.ContentProviderProxy.query(ContentProviderNative.java:413)
12-26 20:45:17.768: E/AndroidRuntime(18479): at android.content.ContentResolver.query(ContentResolver.java:464)
12-26 20:45:17.768: E/AndroidRuntime(18479): at android.content.CursorLoader.loadInBackground(CursorLoader.java:65)
12-26 20:45:17.768: E/AndroidRuntime(18479): at android.content.CursorLoader.loadInBackground(CursorLoader.java:43)
12-26 20:45:17.768: E/AndroidRuntime(18479): at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:312)
12-26 20:45:17.768: E/AndroidRuntime(18479): at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:69)
12-26 20:45:17.768: E/AndroidRuntime(18479): at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:57)
12-26 20:45:17.768: E/AndroidRuntime(18479): at android.os.AsyncTask$2.call(AsyncTask.java:288)
12-26 20:45:17.768: E/AndroidRuntime(18479): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
12-26 20:45:17.768: E/AndroidRuntime(18479): ... 3 more
12-26 20:45:17.778: D/AbsListView(18479): unregisterIRListener() is called
12-26 20:45:17.818: D/AbsListView(18479): unregisterIRListener() is called
12-26 20:45:17.858: D/AbsListView(18479): unregisterIRListener() is called
12-26 20:45:17.868: D/AbsListView(18479): unregisterIRListener() is called
12-26 20:45:18.398: D/AbsListView(18479): onDetachedFromWindow
12-26 20:45:18.398: D/AbsListView(18479): unregisterIRListener() is called
向“ASC”添加空间后的Logcat
12-26 21:24:44.808: I/PersonaManager(25167): getPersonaService() name persona_policy
12-26 21:24:44.818: E/MoreInfoHPW_ViewGroup(25167): Parent view is not a TextView
12-26 21:24:44.848: D/skia(25167): GFXPNG PNG bitmap created width:228 height:228 bitmap id is 274
12-26 21:24:44.848: D/skia(25167): GFXPNG PNG bitmap created width:228 height:228 bitmap id is 275
12-26 21:24:44.858: D/skia(25167): GFXPNG PNG bitmap created width:12 height:12 bitmap id is 276
12-26 21:24:44.858: D/AbsListView(25167): Get MotionRecognitionManager
12-26 21:24:44.868: D/AbsListView(25167): onVisibilityChanged() is called, visibility : 8
12-26 21:24:44.868: D/AbsListView(25167): unregisterIRListener() is called
12-26 21:24:44.868: D/AbsListView(25167): onVisibilityChanged() is called, visibility : 0
12-26 21:24:44.868: D/AbsListView(25167): unregisterIRListener() is called
12-26 21:24:44.868: D/AbsListView(25167): onVisibilityChanged() is called, visibility : 4
12-26 21:24:44.868: D/AbsListView(25167): unregisterIRListener() is called
12-26 21:24:44.878: D/AbsListView(25167): onVisibilityChanged() is called, visibility : 0
12-26 21:24:44.878: D/AbsListView(25167): unregisterIRListener() is called
12-26 21:24:44.878: D/AbsListView(25167): unregisterIRListener() is called
12-26 21:24:44.898: D/AbsListView(25167): unregisterIRListener() is called
12-26 21:24:44.908: W/dalvikvm(25167): threadid=11: thread exiting with uncaught exception (group=0x41737da0)
12-26 21:24:44.908: E/AndroidRuntime(25167): FATAL EXCEPTION: AsyncTask #1
12-26 21:24:44.908: E/AndroidRuntime(25167): Process: com.example.practiceapp, PID: 25167
12-26 21:24:44.908: E/AndroidRuntime(25167): java.lang.RuntimeException: An error occured while executing doInBackground()
12-26 21:24:44.908: E/AndroidRuntime(25167): at android.os.AsyncTask$3.done(AsyncTask.java:300)
12-26 21:24:44.908: E/AndroidRuntime(25167): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
12-26 21:24:44.908: E/AndroidRuntime(25167): at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
12-26 21:24:44.908: E/AndroidRuntime(25167): at java.util.concurrent.FutureTask.run(FutureTask.java:242)
12-26 21:24:44.908: E/AndroidRuntime(25167): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
12-26 21:24:44.908: E/AndroidRuntime(25167): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
12-26 21:24:44.908: E/AndroidRuntime(25167): at java.lang.Thread.run(Thread.java:841)
12-26 21:24:44.908: E/AndroidRuntime(25167): Caused by: android.database.sqlite.SQLiteException: near "display_name": syntax error (code 1): , while compiling: SELECT _id, photo_thumb_uri, display_name, has_phone_number FROM view_contacts_restricted WHERE ((1)) AND ((photo_thumb_uri=?display_name=?has_phone_number=?)) ORDER BY display_name ASC
12-26 21:24:44.908: E/AndroidRuntime(25167): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:181)
12-26 21:24:44.908: E/AndroidRuntime(25167): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
12-26 21:24:44.908: E/AndroidRuntime(25167): at android.content.ContentProviderProxy.query(ContentProviderNative.java:413)
12-26 21:24:44.908: E/AndroidRuntime(25167): at android.content.ContentResolver.query(ContentResolver.java:464)
12-26 21:24:44.908: E/AndroidRuntime(25167): at android.content.CursorLoader.loadInBackground(CursorLoader.java:65)
12-26 21:24:44.908: E/AndroidRuntime(25167): at android.content.CursorLoader.loadInBackground(CursorLoader.java:43)
12-26 21:24:44.908: E/AndroidRuntime(25167): at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:312)
12-26 21:24:44.908: E/AndroidRuntime(25167): at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:69)
12-26 21:24:44.908: E/AndroidRuntime(25167): at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:57)
12-26 21:24:44.908: E/AndroidRuntime(25167): at android.os.AsyncTask$2.call(AsyncTask.java:288)
12-26 21:24:44.908: E/AndroidRuntime(25167): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
12-26 21:24:44.908: E/AndroidRuntime(25167): ... 3 more
12-26 21:24:44.918: D/AbsListView(25167): unregisterIRListener() is called
12-26 21:24:45.008: D/AbsListView(25167): unregisterIRListener() is called
12-26 21:24:45.008: D/AbsListView(25167): unregisterIRListener() is called
12-26 21:24:45.148: D/AbsListView(25167): onDetachedFromWindow
12-26 21:24:45.158: D/AbsListView(25167): unregisterIRListener() is called
12-26 21:24:46.978: I/Process(25167): Sending signal. PID: 25167 SIG: 9
【问题讨论】:
问题似乎是您查询的这一部分 AND ((photo_thumb_uri=?display_name=?has_phone_number=?)) 您需要通过 OR/AND 运算符将其分开 好的,谢谢 Rajen。我只是不知道它们有什么问题,这些是我查询中的 3 个常量。我会再看一遍。你认为我可以在FROM
、PROJECTION
、FILTER
、PROJECTION
和SELECTION_ARGS
中使用它们吗?我想知道是不是重复次数太多了。
【参考方案1】:
ContactsContract.Contacts.DISPLAY_NAME
和 "ASC"
之间需要空格
改变这个
return new CursorLoader(getActivity(),
contentUri,
PROJECTION,
FILTER,
SELECTION_ARGS,
ContactsContract.Contacts.DISPLAY_NAME + "ASC");
进入
return new CursorLoader(getActivity(),
contentUri,
PROJECTION,
FILTER,
SELECTION_ARGS,
ContactsContract.Contacts.DISPLAY_NAME + " ASC");
【讨论】:
感谢 kalyan,我添加了一个空格,但仍然出现同样的错误。 好的,我在上面加了。以上是关于SQLite 异常错误,使用 CursorLoader 和 ContactContracts的主要内容,如果未能解决你的问题,请参考以下文章