Android Studio:已创建数据库,但没有表

时间:2018-07-16 20:52:34

标签: database android-studio sqlite

我是编程的新手,所以请多多包涵(我正在学习在线课程)。

在本课的某个时刻,我们应该在Java类中创建一个数据库,然后将在主要活动(称为CatalogActivity)的onCreate方法中创建一个名为“ pets”的表。

这时,我已经按照应有的格式下载了应用程序(以确保我之前没有在代码中犯错),但是当我在模拟器上运行该应用程序时,没有表已创建。

这个想法是,当我运行该应用程序时,应该创建一个名为housing.db的数据库,并在其中创建一个名为“ pets”的表。该表在PetDbHelper.java类中定义。

在Android Studio终端中进行搜索时,在housing.db中看不到任何表。因此,我将housing.db下载到我的PC上,并使用SQL浏览器打开它-仍然没有“ pets”表。看起来由于某种原因,无法创建表:(

我不知道为什么要遵循所有指示。 请问有人建议如何解决此问题吗?

以下是代码的链接:https://github.com/soralka/PetsApp_error

谢谢!

Soralka

当我使用CommonSQLiteUtilities类时,这里是日志:

07-18 19:37:44.344 15867-15867/? I/le.android.pet: Not late-enabling -Xcheck:jni (already on)
07-18 19:37:44.416 15867-15867/? W/le.android.pet: Unexpected CPU variant for X86 using defaults: x86
07-18 19:37:44.662 15867-15867/com.example.android.pets I/le.android.pet: The ClassLoaderContext is a special shared library.
07-18 19:37:45.027 15867-15867/com.example.android.pets W/le.android.pet: JIT profile information will not be recorded: profile file does not exits.
07-18 19:37:45.051 15867-15867/com.example.android.pets I/chatty: uid=10083(com.example.android.pets) identical 10 lines
07-18 19:37:45.051 15867-15867/com.example.android.pets W/le.android.pet: JIT profile information will not be recorded: profile file does not exits.
07-18 19:37:45.137 15867-15867/com.example.android.pets I/InstantRun: starting instant run server: is main process
07-18 19:37:45.840 15867-15867/com.example.android.pets W/le.android.pet: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
07-18 19:37:45.850 15867-15867/com.example.android.pets W/le.android.pet: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
07-18 19:37:46.066 15867-15867/com.example.android.pets D/SQLITE_CSU: DatabaseList Row 1 Name=main File=/data/user/0/com.example.android.pets/databases/shelter.db
07-18 19:37:46.068 15867-15867/com.example.android.pets D/SQLITE_CSU: Database Version = 1
07-18 19:37:46.071 15867-15867/com.example.android.pets D/SQLITE_CSU: Table Name = android_metadata Created Using = CREATE TABLE android_metadata (locale TEXT)
07-18 19:37:46.073 15867-15867/com.example.android.pets D/SQLITE_CSU: Table = android_metadata ColumnName = locale ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
07-18 19:37:46.074 15867-15867/com.example.android.pets D/SQLITE_CSU: Table Name = pets Created Using = CREATE TABLE pets (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, breed TEXT, gender INTEGER NOT NULL, weight INTEGER NOT NULL DEFAULT 0)
07-18 19:37:46.077 15867-15867/com.example.android.pets D/SQLITE_CSU: Table = pets ColumnName = _id ColumnType = INTEGER Default Value = null PRIMARY KEY SEQUENCE = 1
07-18 19:37:46.078 15867-15867/com.example.android.pets D/SQLITE_CSU: Table = pets ColumnName = name ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
07-18 19:37:46.079 15867-15867/com.example.android.pets D/SQLITE_CSU: Table = pets ColumnName = breed ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = pets ColumnName = gender ColumnType = INTEGER Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = pets ColumnName = weight ColumnType = INTEGER Default Value = 0 PRIMARY KEY SEQUENCE = 0
07-18 19:37:46.080 15867-15867/com.example.android.pets D/SQLITE_CSU: Table Name = sqlite_sequence Created Using = CREATE TABLE sqlite_sequence(name,seq)
07-18 19:37:46.082 15867-15867/com.example.android.pets D/SQLITE_CSU: Table = sqlite_sequence ColumnName = name ColumnType =  Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = sqlite_sequence ColumnName = seq ColumnType =  Default Value = null PRIMARY KEY SEQUENCE = 0
07-18 19:37:46.134 15867-15867/com.example.android.pets D/OpenGLRenderer: Skia GL Pipeline
07-18 19:37:46.260 15867-15886/com.example.android.pets I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
07-18 19:37:46.262 15867-15886/com.example.android.pets I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
07-18 19:37:46.262 15867-15886/com.example.android.pets I/OpenGLRenderer: Initialized EGL, version 1.4
07-18 19:37:46.262 15867-15886/com.example.android.pets D/OpenGLRenderer: Swap behavior 1
07-18 19:37:46.262 15867-15886/com.example.android.pets W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
07-18 19:37:46.263 15867-15886/com.example.android.pets D/OpenGLRenderer: Swap behavior 0
07-18 19:37:46.284 15867-15886/com.example.android.pets D/EGL_emulation: eglCreateContext: 0xe4fbebc0: maj 3 min 0 rcv 3
07-18 19:37:46.347 15867-15886/com.example.android.pets D/EGL_emulation: eglMakeCurrent: 0xe4fbebc0: ver 3 0 (tinfo 0xe79c7930)
07-18 19:37:46.534 15867-15886/com.example.android.pets D/EGL_emulation: eglMakeCurrent: 0xe4fbebc0: ver 3 0 (tinfo 0xe79c7930)

2 个答案:

答案 0 :(得分:0)

根据您的代码,我看不到任何问题。

  • 您可能希望尝试删除该应用程序的数据,或卸载该应用程序,并在下面添加代码行(或添加CommonSQLiteUtilities类,并添加下面为测试而添加的两行代码),然后重新运行该应用程序(这样做可以克服所有问题)可能导致创建数据库但未创建任何表的问题,在这种情况下,onCreate方法将无法运行,因此可能未应用任何更正更改(如果有)。

通过添加以下行来修改CatalogActivity:-

displayDatabaseInfo();

结果将按预期更新EditText(在pets数据库中显示0行)。

如果基础表不存在,那么如果您添加了上面的行,您将在:-

的行中遇到异常
07-17 01:28:51.001 1321-1321/pets.pets E/AndroidRuntime: FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{pets.pets/pets.pets.CatalogActivity}: android.database.sqlite.SQLiteException: no such table: notatable (code 1): , while compiling: SELECT * FROM notatable
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
        at android.app.ActivityThread.access$600(ActivityThread.java:130)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
     Caused by: android.database.sqlite.SQLiteException: no such table: notatable (code 1): , while compiling: SELECT * FROM notatable
        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:882)
        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:493)
        at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
        at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
        at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
        at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
        at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
        at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253)
        at pets.pets.CatalogActivity.displayDatabaseInfo(CatalogActivity.java:40)
        at pets.pets.CatalogActivity.onCreate(CatalogActivity.java:22)
        at android.app.Activity.performCreate(Activity.java:5008)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 
        at android.app.ActivityThread.access$600(ActivityThread.java:130) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:137) 
        at android.app.ActivityThread.main(ActivityThread.java:4745) 
        at java.lang.reflect.Method.invokeNative(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:511) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
        at dalvik.system.NativeStart.main(Native Method) 
  • 通过将表名更改为 notatable

    来强制注释
    Cursor cursor = db.rawQuery("SELECT * FROM " + "notatable", null);
    

Are there any methods that assist with resolving common SQLite issues?

添加 CommonSQLiteUtilities

,然后添加以下行:-

    CommonSQLiteUtilities.logDatabaseInfo(mDbHelper.getWritableDatabase());

结果包含:-

07-17 01:36:51.191 1399-1399/? D/SQLITE_CSU: DatabaseList Row 1 Name=main File=/data/data/pets.pets/databases/shelter.db
    Database Version = 1
    Table Name = android_metadata Created Using = CREATE TABLE android_metadata (locale TEXT)
    Table = android_metadata ColumnName = locale ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table Name = pets Created Using = CREATE TABLE pets (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, breed TEXT, gender INTEGER NOT NULL, weight INTEGER NOT NULL DEFAULT 0)
    Table = pets ColumnName = _id ColumnType = INTEGER Default Value = null PRIMARY KEY SEQUENCE = 1
    Table = pets ColumnName = name ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = pets ColumnName = breed ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = pets ColumnName = gender ColumnType = INTEGER Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = pets ColumnName = weight ColumnType = INTEGER Default Value = 0 PRIMARY KEY SEQUENCE = 0
    Table Name = sqlite_sequence Created Using = CREATE TABLE sqlite_sequence(name,seq)
    Table = sqlite_sequence ColumnName = name ColumnType =  Default Value = null PRIMARY KEY SEQUENCE = 0
    Table = sqlite_sequence ColumnName = seq ColumnType =  Default Value = null PRIMARY KEY SEQUENCE = 0

进一步确认该表已创建。

上面的测试是使用以下代码完成的:-

CatalogActivity.java

public class CatalogActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_catalog);


        //displayDatabaseInfo();

        PetDbHelper mDbHelper = new PetDbHelper(this);
        SQLiteDatabase db = mDbHelper.getReadableDatabase();
        displayDatabaseInfo();
        CommonSQLiteUtilities.logDatabaseInfo(mDbHelper.getWritableDatabase());
    }

    /**
     * Temporary helper method to display information in the onscreen TextView about the state of
     * the pets database.
     */
    private void displayDatabaseInfo() {
        // To access our database, we instantiate our subclass of SQLiteOpenHelper
        // and pass the context, which is the current activity.
        PetDbHelper mDbHelper = new PetDbHelper(this);

        // Create and/or open a database to read from it
        SQLiteDatabase db = mDbHelper.getReadableDatabase();

        // Perform this raw SQL query "SELECT * FROM pets"
        // to get a Cursor that contains all rows from the pets table.
        Cursor cursor = db.rawQuery("SELECT * FROM " + PetContract.PetEntry.TABLE_NAME, null);
        try {
            // Display the number of rows in the Cursor (which reflects the number of rows in the
            // pets table in the database).
            TextView displayView = (TextView) findViewById(R.id.text_view_pet);
            displayView.setText("Number of rows in pets database table: " + cursor.getCount());
        } finally {
            // Always close the cursor when you're done reading from it. This releases all its
            // resources and makes it invalid.
            cursor.close();
        }
    }
}

PetDbHelper.java

public class PetDbHelper extends SQLiteOpenHelper {

    public static final String LOG_TAG = PetDbHelper.class.getSimpleName();

    /**
     * Name of the database file
     */
    private static final String DATABASE_NAME = "shelter.db";

    /**
     * Database version. If you change the database schema, you must increment the database version.
     */
    private static final int DATABASE_VERSION = 1;

    /**
     * Constructs a new instance of {@link PetDbHelper}.
     *
     * @param context of the app
     */
    public PetDbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    /**
     * This is called when the database is created for the first time.
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        // Create a String that contains the SQL statement to create the pets table
        String SQL_CREATE_PETS_TABLE = "CREATE TABLE " + PetContract.PetEntry.TABLE_NAME + " ("
                + PetContract.PetEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + PetContract.PetEntry.COLUMN_PET_NAME + " TEXT NOT NULL, "
                + PetContract.PetEntry.COLUMN_PET_BREED + " TEXT, "
                + PetContract.PetEntry.COLUMN_PET_GENDER + " INTEGER NOT NULL, "
                + PetContract.PetEntry.COLUMN_PET_WEIGHT + " INTEGER NOT NULL DEFAULT 0);";
        // Execute the SQL statement
        db.execSQL(SQL_CREATE_PETS_TABLE);
    }

    /**
     * This is called when the database needs to be upgraded.
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // The database is still at version 1, so there's nothing to do be done here.
    }
}

PetContract.java

public final class PetContract {

    private PetContract() {}

    public static final class PetEntry implements BaseColumns {

        public static final String TABLE_NAME = "pets";
        public static final String _ID = BaseColumns._ID;
        public static final String COLUMN_PET_NAME = "name";
        public static final String COLUMN_PET_BREED = "breed";
        public static final String COLUMN_PET_GENDER = "gender";
        public static final String COLUMN_PET_WEIGHT = "weight";

        /* Possible values for gender. */
        public static final int GENDER_UNKNOWN = 0;
        public static final int GENDER_MALE = 1;
        public static final int GENDER_FEMALE = 2;
    }
}

CommonSQLiteUtilities.java

public class CommonSQLiteUtilities {

    public static final boolean ERROR_CHECKING_ON = true;
    public static final boolean ERROR_CHECKING_OFF = false;

    // SQLite MASTER TABLE definitions
    static final String SQLITE_MASTER = "sqlite_master";
    static final String SM_TABLE_TYPE_COLUMN = "type";
    static final String SM_NAME_COLUMN = "name";
    static final String SM_TABLENAME_COLUMN = "tbl_name";
    static final String SM_ROOTPAGE_COLUMN = "rootpage";
    static final String SM_SQL_COLUMN = "sql";
    static final String SM_TYPE_TABLE = "table";
    static final String SM_TYPE_INDEX = "index";

    static final String PRAGMA_STATEMENT = "PRAGMA ";
    static final String PRAGMA_DATABASELIST = "database_list";
    static final String PRAGMA_USERVERSION = "user_version";
    static final String PRAGMA_ENCODING = "encoding";
    static final String PRAGMA_FOREIGNKEYLIST = "foreign_key_list";
    static final String PRAGMA_INDEXINFO = "index_info";
    static final String PRAGMA_INDEXLIST = "index_list";
    static final String PRAGMA_TABLEINFO = "table_info";

    static final String PRAGMA_DBLIST_SEQ_COL = "seq";
    static final String PRAGMA_DBLIST_NAME_COL = "name";
    static final String PRAGMA_DBLIST_FILE_COL = "file";
    static final String PRAGMA_TABLEINFO_CID_COL = "cid";
    static final String PRAGMA_TABLEINFO_NAME_COl = "name";
    static final String PRAGMA_TABLEINFO_TYPE_COL = "type";
    static final String PRAGMA_TABLEINFO_NOTNULL_COL = "notnull";
    static final String PRAGMA_TABLEINFO_DEFAULTVALUE_COL = "dflt_value";
    static final String PRAGMA_TABLEINFO_PRIMARYKEY_COL = "pk";





    static final String CSU_TAG = "SQLITE_CSU";

    private CommonSQLiteUtilities() {}

    /**
     * Write Database information to the log;
     * Information wrttien is:
     * the database path, (will/should show connected databases)
     * the version number (note! user version i.e. version coded in DBHelper),
     * the tables in the database (includes android_metadata but not sqlite_master),
     * the columns of the tables
     * @param db    The SQLite database to be interrogated
     */
    public static void logDatabaseInfo(SQLiteDatabase db) {

        // Issue PRAGMA database_list commnand
        Cursor dblcsr = db.rawQuery(PRAGMA_STATEMENT + PRAGMA_DATABASELIST,null);
        // Write databases to the log
        while (dblcsr.moveToNext()) {
            Log.d(CSU_TAG,"DatabaseList Row " + Integer.toString(dblcsr.getPosition() + 1) +
                    " Name=" + dblcsr.getString(dblcsr.getColumnIndex(PRAGMA_DBLIST_NAME_COL)) +
                    " File=" + dblcsr.getString(dblcsr.getColumnIndex(PRAGMA_DBLIST_FILE_COL))
            );
        }
        dblcsr.close();
        // Issue PRAGMA user_version to get the version and write to the log
        //Note! to set user_version use execSQL not rawQuery
        Cursor uvcsr = db.rawQuery(PRAGMA_STATEMENT + PRAGMA_USERVERSION,null);
        while (uvcsr.moveToNext()) {
            Log.d(CSU_TAG,"Database Version = " +
                    Integer.toString(uvcsr.getInt(uvcsr.getColumnIndex(PRAGMA_USERVERSION))));
        }
        uvcsr.close();
        // Select all table entry rows from sqlite_master
        Cursor tlcsr = db.rawQuery("SELECT * FROM " +
                        SQLITE_MASTER + " WHERE " +
                        SM_TABLE_TYPE_COLUMN + "='" + SM_TYPE_TABLE + "'"
                ,null);
        // For each table write table information to the log
        // (inner loop gets column info per table)
        while (tlcsr.moveToNext()) {
            String current_table = tlcsr.getString(tlcsr.getColumnIndex(SM_TABLENAME_COLUMN));
            Log.d(CSU_TAG,
                    "Table Name = " + current_table +
                            " Created Using = " + tlcsr.getString(tlcsr.getColumnIndex(SM_SQL_COLUMN)),
                    null
            );
            // Issue PRAGMA tabel_info for the current table
            Cursor ticsr = db.rawQuery(PRAGMA_STATEMENT + PRAGMA_TABLEINFO +
                            "(" + current_table + ")",
                    null
            );
            // Write column info (see headings below) to the log
            while (ticsr.moveToNext()) {
                Log.d(CSU_TAG,"Table = " +
                                current_table +
                                " ColumnName = " +
                                ticsr.getString(ticsr.getColumnIndex(PRAGMA_TABLEINFO_NAME_COl)) +
                                " ColumnType = " +
                                ticsr.getString(ticsr.getColumnIndex(PRAGMA_TABLEINFO_TYPE_COL)) +
                                " Default Value = " +
                                ticsr.getString(ticsr.getColumnIndex(PRAGMA_TABLEINFO_DEFAULTVALUE_COL)) +
                                " PRIMARY KEY SEQUENCE = " + Integer.toString(
                        ticsr.getInt(ticsr.getColumnIndex(PRAGMA_TABLEINFO_PRIMARYKEY_COL))
                        )
                );
            }
            ticsr.close();
        }
        tlcsr.close();
    }

    /**
     * Generic get all rows from an SQlite table,
     * allowing the existence of the table to be checked and also
     * allowing the ROWID to be added AS a supplied string
     *
     * @param db                    The SQLiteDatabase
     * @param tablename             The name of the table from which the
     *                              returned cursor will be created from;
     *                              Note!
     * @param use_error_checking    Whether ot not to try to detect errors
     *                              currently just table doesn't exist,
     *                              true to turn on, false to turn off
     *                              ERROR_CHECKING_ON = true
     *                              ERROR_CHECKING_OFF = false
     * @param forceRowidAs          If length of string passed is 1 or greater
     *                              then a column, as an alias of ROWID, will be
     *                              added to the cursor
     * @return                      the extracted cursor, or in the case of the
     *                              underlying table not existing an empty cursor
     *                              with no columns
     */
    public static Cursor getAllRowsFromTable(SQLiteDatabase db,
                                             String tablename,
                                             boolean use_error_checking,
                                             String forceRowidAs) {
        String[] columns = null;

        // Tablename must be at least 1 character in length
        if (tablename.length() < 1) {
            Log.d(CSU_TAG,new Object(){}.getClass().getEnclosingMethod().getName() +
                    " is finishing as the provided tablename is less than 1 character in length"
            );
            return new MatrixCursor(new String[]{});
        }

        // If use_error_checking is true then check that the table exists
        // in the sqlite_master table
        if (use_error_checking) {
            Cursor chkcsr = db.query(SQLITE_MASTER,null,
                    SM_TABLE_TYPE_COLUMN + "=? AND "
                            + SM_TABLENAME_COLUMN + "=?",
                    new String[]{SM_TYPE_TABLE,tablename},
                    null,null,null
            );

            // Ooops table is not in the Database so return an empty
            // column-less cursor
            if (chkcsr.getCount() < 1) {
                Log.d(CSU_TAG,"Table " + tablename +
                        " was not located in the SQLite Database Master Table."
                );
                // return empty cursor with no columns
                return new MatrixCursor(new String[]{});

            }
            chkcsr.close();
        }

        // If forcing an alias of ROWID then user ROWID AS ???, *
        if(forceRowidAs != null && forceRowidAs.length() > 0) {
            columns = new String[]{"rowid AS " +forceRowidAs,"*"};
        }

        // Finally return the Cursor but trap any exceptions
        try {
            return db.query(tablename, columns, null, null, null, null, null);
        } catch (Exception e) {
            Log.d(CSU_TAG,"Exception encountered but trapped when querying table " + tablename +
                    " Message was: \n" + e.getMessage());
            Log.d(CSU_TAG,"Stacktrace was:");
            e.printStackTrace();
            return new MatrixCursor(new String[]{});
        }
    }

    /**
     * Create and return a Cursor devoid of any rows and columns
     * Not used, prehaps of very little use.
     * @param db    The Sqlite database in which the cursor is to be created
     * @return      The empty Cursor
     */
    private static Cursor getEmptyColumnLessCursor(SQLiteDatabase db) {
        return new MatrixCursor(new String[]{});
    }

    /**
     * Write column names in the passed Cursor to the log
     * @param csr   The Cursor to be inspected.
     */
    public static void logCursorColumns(Cursor csr) {
        Log.d(CSU_TAG,
                new Object(){}.getClass().getEnclosingMethod().getName() +
                        " invoked. Cursor has the following " +
                        Integer.toString(csr.getColumnCount())+
                        " columns.");
        int position = 0;
        for (String column: csr.getColumnNames()) {
            position++;
            Log.d(CSU_TAG,"Column Name " +
                    Integer.toString(position) +
                    " is "
                    + column
            );
        }
    }

    /**
     * Write the contents of the Cursor to the log
     * @param csr   The Cursor that is to be displayed in the log
     */
    public static void logCursorData(Cursor csr) {
        int columncount = csr.getColumnCount();
        int rowcount = csr.getCount();
        int csrpos = csr.getPosition(); //<<< added 20171016
        Log.d(CSU_TAG,
                new Object(){}.getClass().getEnclosingMethod().getName() +
                        " Cursor has " +
                        Integer.toString(rowcount) +
                        " rows with " +
                        Integer.toString(columncount) + " columns."
        );
        csr.moveToPosition(-1);     //Ensure that all rows are retrieved <<< added 20171016
        while (csr.moveToNext()) {
            String unobtainable = "unobtainable!";
            String logstr = "Information for row " + Integer.toString(csr.getPosition() + 1) + " offset=" + Integer.toString(csr.getPosition());
            for (int i=0; i < columncount;i++) {
                logstr = logstr + "\n\tFor Column " + csr.getColumnName(i);
                switch (csr.getType(i)) {
                    case Cursor.FIELD_TYPE_NULL:
                        logstr = logstr + " Type is NULL";
                        break;
                    case Cursor.FIELD_TYPE_FLOAT:
                        logstr = logstr + "Type is FLOAT";
                        break;
                    case Cursor.FIELD_TYPE_INTEGER:
                        logstr = logstr + " Type is INTEGER";
                        break;
                    case Cursor.FIELD_TYPE_STRING:
                        logstr = logstr + " Type is STRING";
                        break;
                    case Cursor.FIELD_TYPE_BLOB:
                        logstr = logstr + " Type is BLOB";
                        break;
                }
                String strval_log = " value as String is ";
                String lngval_log = " value as long is ";
                String dblval_log = " value as double is ";
                String blbval_log = "";
                try {
                    strval_log = strval_log + csr.getString(i);
                    lngval_log = lngval_log + csr.getLong(i);
                    dblval_log = dblval_log +  csr.getDouble(i);
                } catch (Exception e) {
                    strval_log = strval_log + unobtainable;
                    lngval_log = lngval_log + unobtainable;
                    dblval_log = dblval_log + unobtainable;
                    try {
                        blbval_log = " value as blob is " +
                                getBytedata(csr.getBlob(i),24);
                    } catch (Exception e2) {
                        e2.printStackTrace();
                    }

                }
                logstr = logstr + strval_log + lngval_log + dblval_log + blbval_log;
            }
            Log.d(CSU_TAG,logstr);
        }
        csr.moveToPosition(csrpos); // restore cursor position <<< added 20171016
    }

    /**
     * Return a hex string of the given byte array
     * @param bytes     The byte array to be converted to a hexadecimal string
     * @param limit     the maximum number of bytes;
     *                  note returned string will be up to twice as long
     * @return          The byte array represented as a hexadecimal string
     */
    private static String getBytedata(byte[] bytes, int limit) {
        if (bytes.length < limit) {
            return convertBytesToHex(bytes);
        } else {
            byte[] subset = new byte[limit];
            System.arraycopy(bytes,0,subset,0,limit);
            return convertBytesToHex(subset);
        }
    }

    // HEX characters as a char array for use by convertBytesToHex
    private final static char[] hexarray = "0123456789ABCDEF".toCharArray();

    /**
     * Return a hexadecimal string representation of the passed byte array
     * @param bytes     The byte array to be represented.
     * @return          The string representing the byte array as hexadecimal
     */
    private static String convertBytesToHex(byte[] bytes) {
        char[] hexstr = new char[bytes.length * 2];
        for (int i=0; i < bytes.length; i++) {
            int h = bytes[i] & 0xFF;
            hexstr[i * 2] = hexarray[h >>> 4];
            hexstr[i * 2 + 1] = hexarray[h & 0xF];
        }
        return new String(hexstr);
    }
}

activity_catalog.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CatalogActivity">

    <TextView
        android:id="@+id/text_view_pet"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

答案 1 :(得分:0)

我发现主要问题是什么:我正在使用具有API 28的仿真器。显然,尝试访问数据库时,高于API 23的问题都是一个问题。

所以我做了一个新的模拟器API 23,现在我在权限等方面没有任何问题。

@MikeT-这似乎就是为什么我一直在努力获取权限的原因。