Android: متميز ومجموعة في ContentResolver
-
22-09-2019 - |
سؤال
ماذا سيكون طريقة معقولة للإضافة DISTINCT
و/أو GROUPBY
إلى ContentResolver
- الاستفسارات القائمة. الآن لا بد لي من إنشاء URI مخصص لكل حالة خاصة. هل هناك طريقة أفضل؟ (ما زلت برنامجًا لـ 1.5 كأدنى قاسم مشترك)
المحلول 2
بما أنه لم يأت أحد للإجابة ، فسأخبرني كيف حللت هذا. في الأساس ، سأقوم بإنشاء URI مخصص لكل حالة ونقل المعايير في selection
معامل. ثم في الداخل ContentProvider#query
أود تحديد الحالة وبناء الاستعلام الخام بناءً على اسم الجدول ومعلمة التحديد.
إليك مثال سريع:
switch (URI_MATCHER.match(uri)) {
case TYPES:
table = TYPES_TABLE;
break;
case TYPES_DISTINCT:
return db.rawQuery("SELECT DISTINCT type FROM types", null);
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
return db.query(table, null, selection, selectionArgs, null, null, null);
نصائح أخرى
يمكنك القيام بالاختراق الجميل عند الاستعلام عن contentResolver ، استخدم:
String selection = Models.SOMETHING + "=" + something + ") GROUP BY (" + Models.TYPE;
إذا كنت ترغب في استخدام متميز مع SELECT أكثر من عمود واحد ، فأنت بحاجة إلى استخدام Group بواسطة.
Mini Hack عبر contentResolver.query لاستخدام هذا:
Uri uri = Uri.parse("content://sms/inbox");
Cursor c = getContentResolver().query(uri,
new String[]{"DISTINCT address","body"}, //DISTINCT
"address IS NOT NULL) GROUP BY (address", //GROUP BY
null, null);
if(c.moveToFirst()){
do{
Log.v("from", "\""+c.getString(c.getColumnIndex("address"))+"\"");
Log.v("text", "\""+c.getString(c.getColumnIndex("body"))+"\"");
} while(c.moveToNext());
}
حدد هذا الرمز الرسائل القصيرة الأخيرة لكل من المرسلين من صندوق الوارد.
ملاحظة: قبل المجموعة ، نحتاج دائمًا إلى كتابة حالة واحدة على الأقل. النتيجة SQL Query String داخل contentResolver.query طريقة:
SELECT DISTINCT address, body FROM sms WHERE (type=1) AND (address IS NOT NULL) GROUP BY (address)
في تجاوزك ContentProvider
طريقة الاستعلام لديها رسم خرائط URI محدد لاستخدام متميز.
ثم استخدام SQLiteQueryBuilder
ودعا setDistinct(boolean)
طريقة.
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder)
{
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
boolean useDistinct = false;
switch (sUriMatcher.match(uri))
{
case YOUR_URI_DISTINCT:
useDistinct = true;
case YOUR_URI:
qb.setTables(YOUR_TABLE_NAME);
qb.setProjectionMap(sYourProjectionMap);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
// If no sort order is specified use the default
String orderBy;
if (TextUtils.isEmpty(sortOrder))
{
orderBy = DEFAULT_SORT_ORDER;
}
else
{
orderBy = sortOrder;
}
// Get the database and run the query
SQLiteDatabase db = mDBHelper.getReadableDatabase();
// THIS IS THE IMPORTANT PART!
qb.setDistinct(useDistinct);
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
if (c != null)
{
// Tell the cursor what uri to watch, so it knows when its source data changes
c.setNotificationUri(getContext().getContentResolver(), uri);
}
return c;
}
على الرغم من أنني لم أستخدم مجموعة من, ، لقد استخدمت مميز في استعلام حل المحتوى.
Cursor cursor = contentResolver
.query(YOUR_URI,
new String[] {"Distinct "+ YOUR_COLUMN_NAME},
null,
null, null);
في بعض الحالات ، يمكننا استخدام "Distore (column_name)" كتحديد ، ويعمل بشكل مثالي. ولكن في حالة ما ، سوف يسبب استثناء.
عندما تسبب استثناء ، سأستخدم مجموعة التجزئة لتخزين قيم العمود ....
// getting sender list from messages into spinner View
Spinner phoneListView = (Spinner) findViewById(R.id.phone_list);
Uri uri = Uri.parse("content://sms/inbox");
Cursor c = getContentResolver().query(uri, new String[]{"Distinct address"}, null, null, null);
List <String> list;
list= new ArrayList<String>();
list.clear();
int msgCount=c.getCount();
if(c.moveToFirst()) {
for(int ii=0; ii < msgCount; ii++) {
list.add(c.getString(c.getColumnIndexOrThrow("address")).toString());
c.moveToNext();
}
}
phoneListView.setAdapter(new ArrayAdapter<String>(BankActivity.this, android.R.layout.simple_dropdown_item_1line, list));
إضافة الكلمة الرئيسية المتميزة في الإسقاط عملت بالنسبة لي أيضًا ، ومع ذلك ، فقد نجحت فقط عندما كانت الكلمة الرئيسية المتميزة هي الوسيطة الأولى:
String[] projection = new String[]{"DISTINCT " + DBConstants.COLUMN_UUID, ... };
ربما يكون من السهل الحصول على قيم متميزة ، حاول إضافة الكلمة المتميزة قبل اسم العمود الذي تريده في جدول الإسقاط
String[] projection = new String[]{
BaseColumns._ID,
"DISTINCT "+ Mediastore.anything.you.want
};
واستخدامه كوسيطة للاستعلام عن محدد المحتوى!
آمل أن أساعدك ، لأن لدي نفس السؤال قبل بعض الأيام