无法使用ContentProvider将数据添加到数据库

时间:2018-03-04 11:49:02

标签: android sqlite android-contentprovider

我正在学习Android内容提供商和内容。我无法弄清楚为什么没有使用ProductProvider添加数据。 我查看了每个类,但数据从数据库插入或查询的方式有问题,但我无法弄清楚什么是坏的。

以下是代码文件

活动

HomePage.java

   package com.example.tanmay.shoppingapp;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.example.tanmay.shoppingapp.DataSet.ProductListContract.ProductEntry;

public class HomePage extends AppCompatActivity {

    TextView idBox;
    TextView nameBox;

    String TAG = "com.whatever.tag";

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.home_page, menu);

        return true;

    }

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


        //Adding custom toolbar
        android.support.v7.widget.Toolbar toolbar = findViewById(R.id.homePageToolBar);
        setSupportActionBar(toolbar);

        insertProduct();


        //Projection is just the name of the columns we would like to receive
        String[] projection = {

                ProductEntry._ID,
                ProductEntry.COLUMN_NAME_PRODUCT_NAME

        };


        Cursor cursorNew = getContentResolver().query(ProductEntry.CONTENT_URI, projection, null, null, null);
        cursorNew.moveToNext();
        int uweh = cursorNew.getInt(cursorNew.getColumnIndex(ProductEntry.COLUMN_NAME_PRODUCT_NAME));
        TextView coco = findViewById(R.id.e83957);
        coco.setText(uweh);

        ListView listView = findViewById(R.id.productList_homepage);
       listView.setAdapter(new productListAdapter(HomePage.this, cursorNew));


    }

    private void insertProduct() {


        ContentValues values = new ContentValues();

        //The values contains all the data to be entered into the table
        values.put(ProductEntry._ID, 67);
        values.put(ProductEntry.COLUMN_NAME_PRODUCT_NAME, R.string.product1Name);
        values.put(ProductEntry.COLUMN_NAME_PRODUCT_PRICE, R.integer.product1Price);
        values.put(ProductEntry.COLUMN_NAME_PRODUCT_THUMBNAIL, R.drawable.product1thumbnail);
        values.put(ProductEntry.COLUMN_NAME_PRODUCT_IMAGE, R.drawable.product1image);

        // values.put(ProductEntry.COLUMN_NAME_PRODUCT_NAME, R.string.product2Name);

        Uri newUri = getContentResolver().insert(ProductEntry.CONTENT_URI, values);


    }

    private class productListAdapter extends CursorAdapter {

        public productListAdapter(Context context, Cursor c) {
            super(context, c);
        }

        //Returns a new blank view
        @Override
        public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {

            return LayoutInflater.from(context).inflate(R.layout.dummy_item, viewGroup, false);

        }

        //Actually responsible for the data binding
        @Override
        public void bindView(View view, Context context, Cursor cursor) {


            idBox = (TextView) findViewById(R.id.dummy_item_id_box);
            nameBox = (TextView) findViewById(R.id.dummy_item_name_box);

            id.setText(cursor.getInt(cursor.getColumnIndexOrThrow(ProductEntry._ID)));
            name.setText(getResources().getString(cursor.getInt(cursor.getColumnIndexOrThrow(ProductEntry.COLUMN_NAME_PRODUCT_NAME))));


        }

    }

}

ProductDbHelper

package com.example.tanmay.shoppingapp.DataSet;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import static com.example.tanmay.shoppingapp.DataSet.ProductListContract.ProductEntry.COLUMN_NAME_PRODUCT_IMAGE;
import static com.example.tanmay.shoppingapp.DataSet.ProductListContract.ProductEntry.COLUMN_NAME_PRODUCT_NAME;
import static com.example.tanmay.shoppingapp.DataSet.ProductListContract.ProductEntry.COLUMN_NAME_PRODUCT_PRICE;
import static com.example.tanmay.shoppingapp.DataSet.ProductListContract.ProductEntry.COLUMN_NAME_PRODUCT_THUMBNAIL;
import static com.example.tanmay.shoppingapp.DataSet.ProductListContract.ProductEntry.TABLE_NAME;
import static com.example.tanmay.shoppingapp.DataSet.ProductListContract.ProductEntry._ID;

/**
 * Created by tanmay on 3/3/18.
 */

public class ProductDbHelper extends SQLiteOpenHelper {

    //Name of the database file
    public static final String DATABASE_NAME = "products.db";

    //Database version to be incremented on change in schema
    public static final int DATABASE_VERSION = 1;
    //  SQL command to create the table
    //  All columns contain integers because they don't contain the actual Strings and Images,
    //      instead they hold the integral resource identifiers (R.string.* / R.integer.* / R.drawable.*).
    public static final String SQL_CREATE_ENTRIES =
            "CREATE TABLE " + TABLE_NAME + " (" +
                    _ID + " INTEGER PRIMARY KEY, " +
                    COLUMN_NAME_PRODUCT_NAME + " INTEGER, " +
                    COLUMN_NAME_PRODUCT_PRICE + "INTEGER, " +
                    COLUMN_NAME_PRODUCT_THUMBNAIL + "INTEGER, " +
                    COLUMN_NAME_PRODUCT_IMAGE + "INTEGER)";
    //  Checks if a particular table already exists and then deletes it.
    private static final String SQL_DELETE_ENTRIES =
            "DROP TABLE IF EXISTS " + TABLE_NAME;

    //Default constructor
    public ProductDbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {

        //  Creates the database bu executing String as SQL command
        sqLiteDatabase.execSQL(ProductDbHelper.SQL_CREATE_ENTRIES);

    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

        //  Firsts deletes the old database then creates a new one
        sqLiteDatabase.execSQL(ProductDbHelper.SQL_DELETE_ENTRIES);
        onCreate(sqLiteDatabase);

    }

    @Override
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        onUpgrade(db, oldVersion, newVersion);

    }


}

ProductListContract

package com.example.tanmay.shoppingapp.DataSet;

import android.content.ContentResolver;
import android.net.Uri;
import android.provider.BaseColumns;

/**
 * Created by tanmay on 26/2/18.
 */

public class ProductListContract {

    //  Refers to this particular application
    public static final String CONTENT_AUTHORITY = "com.example.tanmay.shoppingapp";
    public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);

    //Empty constructor to prevent instantiation
    private ProductListContract() {
    }

    public static class ProductEntry implements BaseColumns {

        //  Name of the table
        public static final String TABLE_NAME = "productListPrimary";

        //  Uri pointing to this particular table
        public static final Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, ProductEntry.TABLE_NAME);


        //MIME type
        public static final String CONTENT_LIST_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + TABLE_NAME;
        public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + TABLE_NAME;

        //  Names of various columns
        public static final String COLUMN_NAME_PRODUCT_NAME = "name";
        public static final String _ID = BaseColumns._ID;
        public static final String COLUMN_NAME_PRODUCT_PRICE = "price";
        public static final String COLUMN_NAME_PRODUCT_THUMBNAIL = "thumbnail";
        public static final String COLUMN_NAME_PRODUCT_IMAGE = "image";


    }

}

ProductProvider.java

    package com.example.tanmay.shoppingapp.DataSet;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;

import com.example.tanmay.shoppingapp.DataSet.ProductListContract.ProductEntry;

/**
 * Created by tanmay on 28/2/18.
 */

public class ProductProvider extends ContentProvider {

    private static final int ProductListTable = 1;
    private static final int ProductListRow = 2;

    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    static {

        sUriMatcher.addURI(ProductListContract.CONTENT_AUTHORITY, ProductEntry.TABLE_NAME, ProductListTable);
        sUriMatcher.addURI(ProductListContract.CONTENT_AUTHORITY, ProductEntry.TABLE_NAME + "/#", ProductListRow);

    }

    private ProductDbHelper mDbHelper;

    @Override
    public boolean onCreate() {

        //Creates a new DbHelper object
        mDbHelper = new ProductDbHelper(getContext());

        return true;
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {

        //  Obtain a read-only copy of the database
        SQLiteDatabase sqLiteDatabase = mDbHelper.getReadableDatabase();

        //  This cursor holds the result from the query.
        Cursor cursor = null;

        //  Switch to perform specific kind of query based on type of Uri
        switch (sUriMatcher.match(uri)) {

            //  Uri demanding entire table with the criteria defined in the fundtion params
            case ProductListTable:

                //  All the argumnets are the ones passed
                cursor = sqLiteDatabase.query(ProductEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);

                break;

            //  Uri demanding a particular row item.
            case ProductListRow:

                //  "?" is a wildcard which gets replaced by any integer
                selection = ProductEntry._ID + "=?";
                selectionArgs = new String[]{String.valueOf((ContentUris.parseId(uri)))};

                cursor = sqLiteDatabase.query(ProductEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);

                break;

            default:
                throw new IllegalArgumentException("Cannot query unkown URI " + uri);

        }

        //Return the cursor containing query results
        return cursor;

    }

    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {

        final int match = sUriMatcher.match(uri);

        switch (match) {

            case ProductListTable:
                return ProductEntry.CONTENT_LIST_TYPE;

            case ProductListRow:
                return ProductEntry.CONTENT_ITEM_TYPE;

            default:
                throw new IllegalStateException("Unkown URI " + uri + " with match " + match);
        }
    }

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {

        final int match = sUriMatcher.match(uri);

        switch (match) {

            case ProductListTable:

                return insertProduct(uri, contentValues);

            default:
                throw new IllegalArgumentException("Insertion is not supported for " + uri);

        }

    }

    public Uri insertProduct(Uri uri, ContentValues contentValues) {

        SQLiteDatabase db = mDbHelper.getWritableDatabase();

        long id = db.insert(ProductEntry.TABLE_NAME, null, contentValues);

        if (id == -1) {

            Log.e("com.whatever.tag", "Failed to insert row for " + uri);

            return null;

        }

        return ContentUris.withAppendedId(uri, id);
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String s, @Nullable String[] strings) {
        return 0;
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) {
        return 0;
    }

}

LayoutFiles 主页活动布局文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    android:orientation="vertical" 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="com.example.tanmay.shoppingapp.HomePage">

    <android.support.v7.widget.Toolbar
        android:id="@+id/homePageToolBar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:elevation="4dp"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:title="@string/app_name">

    </android.support.v7.widget.Toolbar>

    <TextView
        android:id="@+id/e83957"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="wwt49832"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ListView
        android:layout_marginTop="?attr/actionBarSize"
        android:id="@+id/productList_homepage"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout>

一个ListView元素的布局 DummyItem,因为一旦一切正常,将应用不同的布局。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_margin="8dp"
        android:text="327"
        android:id="@+id/dummy_item_id_box"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_margin="8dp"
        android:text="placeholder"
        android:id="@+id/dummy_item_name_box"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

0 个答案:

没有答案