18e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki/* 2654888562d75fe4758cb0500f73aaa11385e6f63Makoto Onuki * Copyright (C) 2011 The Android Open Source Project 38e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki * 48e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki * Licensed under the Apache License, Version 2.0 (the "License"); 58e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki * you may not use this file except in compliance with the License. 68e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki * You may obtain a copy of the License at 78e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki * 88e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki * http://www.apache.org/licenses/LICENSE-2.0 98e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki * 108e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki * Unless required by applicable law or agreed to in writing, software 118e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki * distributed under the License is distributed on an "AS IS" BASIS, 128e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki * See the License for the specific language governing permissions and 148e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki * limitations under the License. 158e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki */ 168e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki 178e34744e041e3db61aa3544b03594e5b379c946cMakoto Onukipackage com.android.contacts.tests; 188e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki 198e34744e041e3db61aa3544b03594e5b379c946cMakoto Onukiimport android.app.IntentService; 208e34744e041e3db61aa3544b03594e5b379c946cMakoto Onukiimport android.content.Intent; 218e34744e041e3db61aa3544b03594e5b379c946cMakoto Onukiimport android.database.Cursor; 228e34744e041e3db61aa3544b03594e5b379c946cMakoto Onukiimport android.net.Uri; 23953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onukiimport android.text.TextUtils; 248e34744e041e3db61aa3544b03594e5b379c946cMakoto Onukiimport android.util.Log; 258e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki 268e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki/** 278e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki * A service that executes a query specified by an intent and dump the result on logcat. Use the 288e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki * "am" command to launch it. 298e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki * 308e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki Usage: 318e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki adb shell am startservice -d URI \ 32953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki [-e p OPTIONAL PROJECTION] [-e s OPTIONAL SELECTION] [-e s OPTIONAL ORDER BY] \ 338e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki com.android.contacts.tests/.QueryService 348e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki 358e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki Example: 368e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki 378e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki adb shell am startservice -d content://com.android.contacts/directories \ 38953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki -e p accountName,accountType -e s 'accountName NOT NULL' -e o '_id' \ 398e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki com.android.contacts.tests/.QueryService 408e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki */ 418e34744e041e3db61aa3544b03594e5b379c946cMakoto Onukipublic class QueryService extends IntentService { 428e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki private static final String TAG = "contactsquery"; 438e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki 44953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki private static final String EXTRA_PROJECTION = "p"; 458e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki private static final String EXTRA_SELECTION = "s"; 468e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki private static final String EXTRA_ORDER = "o"; 478e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki private static final String NULL_STRING = "*null*"; 488e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki private static final String SEPARATOR = "|"; 498e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki 508e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki public QueryService() { 518e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki super("ContactsQueryService"); 528e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki } 538e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki 548e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki @Override 558e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki protected void onHandleIntent(Intent intent) { 568e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki final Uri uri = intent.getData(); 57953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki // Unfortunately "am" doesn't support string arrays... 58953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki final String projection = intent.getStringExtra(EXTRA_PROJECTION); 598e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki final String selection = intent.getStringExtra(EXTRA_SELECTION); 608e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki final String order = intent.getStringExtra(EXTRA_ORDER); 618e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki 628e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki Log.i(TAG, "URI: " + uri); 63953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki Log.i(TAG, "Projection: " + projection); 648e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki Log.i(TAG, "Selection: " + selection); 658e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki 668e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki try { 67953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki Cursor c = getContentResolver().query(uri, parseProjection(projection), selection, null, 68953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki order); 69953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki if (c == null) { 70953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki Log.i(TAG, "(no results)"); 71953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki return; 728e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki } 73953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki StringBuilder sb = new StringBuilder(); 74953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki try { 75953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki Log.i(TAG, "Result count: " + c.getCount()); 76953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki 77953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki final int columnCount = c.getColumnCount(); 788e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki 798e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki sb.setLength(0); 808e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki for (int i = 0; i < columnCount; i++) { 81953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki add(sb, c.getColumnName(i)); 828e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki } 838e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki Log.i(TAG, sb.toString()); 84953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki 85953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki c.moveToPosition(-1); 86953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki while (c.moveToNext()) { 87953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki sb.setLength(0); 88953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki for (int i = 0; i < columnCount; i++) { 89953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki add(sb, c.getString(i)); 90953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki } 91953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki Log.i(TAG, sb.toString()); 92953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki } 93953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki } finally { 94953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki c.close(); 958e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki } 96953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki } catch (Exception e) { 97953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki Log.e(TAG, "Exeption while executing query", e); 988e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki } 998e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki } 1008e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki 1018e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki private StringBuilder add(StringBuilder sb, String s) { 1028e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki if (sb.length() > 0) { 1038e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki sb.append(SEPARATOR); 1048e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki } 1058e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki sb.append(s == null ? NULL_STRING : s); 1068e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki return sb; 1078e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki } 108953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki 109953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki private static String[] parseProjection(String projectionString) { 110953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki if (TextUtils.isEmpty(projectionString)) { 111953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki return null; // all columns 112953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki } 113953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki final String[] columns = projectionString.split(","); 114953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki if (columns.length == 0) { 115953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki return null; // all columns 116953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki } 117953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki return columns; 118953dc0c8c95e0b7c3aabcaacea0b6e88d3174462Makoto Onuki } 1198e34744e041e3db61aa3544b03594e5b379c946cMakoto Onuki} 120