1

我需要在不同的手机上获取呼叫提供商的内部结构(这主要是因为三星设备会导致问题,即底层数据库架构)。这是我的代码:

public class MainActivity extends Activity {


    @Override
    public void onCreate(Bundle savedInstanceState) {
        ............................

        dumpProvider();
    }

    private void dumpProvider() {

        Cursor cursor = getCallsCursor();
        try {
            BufferedWriter writer = getWriter();
            dumpColumnNames(cursor, writer);

            cursor.moveToFirst();
            do {
                dumpRecord(cursor, writer);
            } while (cursor.moveToNext());
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            cursor.close();
        }

    }

    private void dumpRecord(Cursor cursor, BufferedWriter writer) throws IOException {
        String recordStr = "";
        int columnCount = cursor.getColumnCount();
        for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
            recordStr += cursor.getString(columnIndex) + " ";
        }
        writer.append(recordStr);
        writer.newLine();
    }

    private void dumpColumnNames(Cursor cursor, BufferedWriter writer) throws IOException {
        String[] columnNames = cursor.getColumnNames();
        String columnNamesStr = "";
        for (String columnStr : columnNames) {
            columnNamesStr += columnStr + " ";
        }
        writer.append(columnNamesStr);
        writer.newLine();
    }

    private Cursor getCallsCursor() {
        ContentResolver cr = getContentResolver();
        Cursor cursor = cr.query(CallLog.Calls.CONTENT_URI, null, null, null, null);

        return cursor;
    }

    private BufferedWriter getWriter() throws IOException {
        ......................
    }

}

在我的 LG 上运行良好,但在三星 S2 上运行时出现异常

08-20 09:16:15.860: E/AndroidRuntime(19565): FATAL EXCEPTION: main
08-20 09:16:15.860: E/AndroidRuntime(19565): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.databasestrucutecollector/com.example.databasestrucutecollector.MainActivity}: android.database.sqlite.SQLiteException: no such column: sdn_alpha_id: , while compiling: SELECT sns_receiver_count, numberlabel, service_type, matched_number, type, contactid, lookup_uri, mime_type, sdn_alpha_id, sp_type, messageid, fname, simnum, lname, sns_pkey, account_id, formatted_number, call_out_duration, number, geocoded_location, account_name, is_read, raw_contact_id, source_data, cdnip_number, state, m_subject, date, real_phone_number, source_package, _id, sns_tid, name, normalized_number, name_reversed, _data, photo_id, logtype, reject_flag, has_content, m_content, country_code, frequent, cityid, bname, countryiso, numbertype, new, duration, cnap_name, address, e164_number, voicemail_uri FROM logs WHERE (logs.logtype=100 OR logs.logtype=110 OR logs.logtype=500 OR logs.logtype=800 OR logs.logtype=900 OR logs.logtype=1000 OR (logs.logtype=200 AND number NOT IN (SELECT number FROM logs WHERE number LIKE '%@%')) OR logs.logtype=300) AND ((((type != '4')))) ORDER BY date DESC
08-20 09:16:15.860: E/AndroidRuntime(19565):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1967)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at android.app.ActivityThread.access$600(ActivityThread.java:127)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at android.os.Looper.loop(Looper.java:137)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at android.app.ActivityThread.main(ActivityThread.java:4511)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at java.lang.reflect.Method.invokeNative(Native Method)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at java.lang.reflect.Method.invoke(Method.java:511)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at dalvik.system.NativeStart.main(Native Method)
08-20 09:16:15.860: E/AndroidRuntime(19565): Caused by: android.database.sqlite.SQLiteException: no such column: sdn_alpha_id: , while compiling: SELECT sns_receiver_count, numberlabel, service_type, matched_number, type, contactid, lookup_uri, mime_type, sdn_alpha_id, sp_type, messageid, fname, simnum, lname, sns_pkey, account_id, formatted_number, call_out_duration, number, geocoded_location, account_name, is_read, raw_contact_id, source_data, cdnip_number, state, m_subject, date, real_phone_number, source_package, _id, sns_tid, name, normalized_number, name_reversed, _data, photo_id, logtype, reject_flag, has_content, m_content, country_code, frequent, cityid, bname, countryiso, numbertype, new, duration, cnap_name, address, e164_number, voicemail_uri FROM logs WHERE (logs.logtype=100 OR logs.logtype=110 OR logs.logtype=500 OR logs.logtype=800 OR logs.logtype=900 OR logs.logtype=1000 OR (logs.logtype=200 AND number NOT IN (SELECT number FROM logs WHERE number LIKE '%@%')) OR logs.logtype=300) AND ((((type != '4')))) ORDER BY date DESC
08-20 09:16:15.860: E/AndroidRuntime(19565):    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:180)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:136)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at android.content.ContentProviderProxy.query(ContentProviderNative.java:358)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at android.content.ContentResolver.query(ContentResolver.java:317)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at com.example.databasestrucutecollector.MainActivity.getContactsCursor(MainActivity.java:71)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at com.example.databasestrucutecollector.MainActivity.dumpProvider(MainActivity.java:31)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at com.example.databasestrucutecollector.MainActivity.onCreate(MainActivity.java:26)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at android.app.Activity.performCreate(Activity.java:4470)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
08-20 09:16:15.860: E/AndroidRuntime(19565):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)

有什么提示吗?

4

2 回答 2

1

正如这个答案中已经提出的那样,如果您知道需要查询的列,则可以指定一个选择:

String[] projection = new String[] {CallLog.Calls._ID, CallLog.Calls.CACHED_NAME, CallLog.Calls.DATE, CallLog.Calls.DURATION, CallLog.Calls.NUMBER, CallLog.Calls.TYPE };
Cursor cursor = context.getContentResolver().query( android.provider.CallLog.Calls.CONTENT_URI, projection, null, null, null );

但是,我仍在寻找一种无需选择即可查询所有列的解决方案...

这似乎是 S2 设备上的错误?有没有人在其他设备上也体验过?

于 2012-08-22T20:34:03.393 回答
0

我不确定为什么你的代码崩溃了,对我来说似乎很好,

我写了一个方法来转储任何 ContentProvider uri 的所有数据,也许它会为你工作:

    cur = resolver.query(uri, null, null, null, sort);
        if (cur != null) {

            // BASIC STUFF
            Log.v(TAG, "count = " + cur.getCount());
            int columnCount = cur.getColumnCount();
            Log.v(TAG, "cols = " + columnCount);

            // PRINT ALL COLUMN NAMES
            cur.moveToFirst();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < columnCount; i++) {
                sb.append(i).append(": ").append(cur.getColumnName(i)).append(", ");
            }
            Log.v(TAG, "COLUMNS: " + sb.toString());

            // PRINT ALL DATA
            do {
                sb = new StringBuilder();
                for (int i = 0; i < columnCount; i++) {
                    String value = cur.getString(i);
                    String name = cur.getColumnName(i);
                    sb.append(i).append(": ").append(value).append(". \t");
                }
                Log.v(TAG, sb.toString());
            } while (cur.moveToNext());
        }
于 2012-09-13T14:06:23.397 回答