我正在尝试创建一个应用程序,我可以使用sqlite存储和查看我的日常讲座。在我开始使用内容提供商之前,一切正常。每当我尝试从数据库进行查询时,它都会返回一个空游标。
此外,我甚至无法在数据库中添加新的讲座。好像我的ContentProvider
课程不能正常工作。但我完全不知道它有什么不对。我在下面添加了源代码。
我被困在这里很长时间了。所以任何帮助都非常感谢!
StudentProvider.java
package com.example.utkarsh_pc.tester_app.data;
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.util.Log;
public class StudentProvider extends ContentProvider {
private final String LOG_TAG = StudentProvider.class.getSimpleName();
/** URI matcher code for the content URI for the lectures table */
private static final int LECTURES = 100;
/** URI matcher code for the content URI for a single lecture in the lectures table */
private static final int LECTURES_ID = 101;
/**
* UriMatcher object to match a content URI to a corresponding code.
* The input passed into the constructor represents the code to return for the root URI.
* It's common to use NO_MATCH as the input for this case.
*/
private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// Static initializer. This is run the first time anything is called from this class.
static {
// The calls to addURI() go here, for all of the content URI patterns that the provider
// should recognize. All paths added to the UriMatcher have a corresponding code to return
// when a match is found.
// The content URI of the form "content://com.example.utkarsh_pc.tester_app/lectures" will map to the
// integer code {@link #LECTURES}. This URI is used to provide access to MULTIPLE rows
// of the pets table.
sUriMatcher.addURI(StudentContract.CONTENT_AUTHORITY, StudentContract.PATH_LECTURES, LECTURES);
// The content URI of the form "content://com.example.utkarsh_pc.tester_app/lectures/#" will map to the
// integer code {@link #LECTURES_ID}. This URI is used to provide access to ONE single row
// of the lectures table.
//
// In this case, the "#" wildcard is used where "#" can be substituted for an integer.
// For example, "content://com.example.utkarsh_pc.tester_app/lectures/3" matches, but
// "content://com.example.utkarsh_pc.tester_app/lectures" (without a number at the end) doesn't match.
sUriMatcher.addURI(StudentContract.CONTENT_AUTHORITY, StudentContract.PATH_LECTURES + "/#", LECTURES_ID);
}
/** Database helper object */
private StudentDbHelper mDbHelper;
@Override
public boolean onCreate() {
mDbHelper = new StudentDbHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
// Get readable database
SQLiteDatabase database = mDbHelper.getReadableDatabase();
// This cursor will hold the result of the query
Cursor cursor;
// Figure out if the URI matcher can match the URI to a specific code
switch (sUriMatcher.match(uri)) {
case LECTURES:
// For the LECTURES code, query the lectures table directly with the given
// projection, selection, selection arguments, and sort order. The cursor
// could contain multiple rows of the lectures table.
cursor = database.query(StudentContract.LectureEntry.TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder);
break;
case LECTURES_ID:
// For the LECTURES_ID code, extract out the ID from the URI.
// For an example URI such as "content://com.example.utkarsh_pc.tester_app/lectures/3",
// the selection will be "_id=?" and the selection argument will be a
// String array containing the actual ID of 3 in this case.
//
// For every "?" in the selection, we need to have an element in the selection
// arguments that will fill in the "?". Since we have 1 question mark in the
// selection, we have 1 String in the selection arguments' String array.
selection = StudentContract.LectureEntry._ID + "=?";
selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
// This will perform a query on the lectures table where the _id equals 3 to return a
// Cursor containing that row of the table.
cursor = database.query(StudentContract.LectureEntry.TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder);
break;
default:
throw new IllegalArgumentException("Cannot query unknown URI " + uri);
}
return cursor;
}
@Override
public Uri insert(Uri uri, ContentValues contentValues) {
final int match = sUriMatcher.match(uri);
switch (match) {
case LECTURES:
return insertLecture(uri, contentValues);
default:
throw new IllegalArgumentException("Insertion is not supported for " + uri);
}
}
/**
* Insert a lecture into the database with the given content values. Return the new content URI
* for that specific row in the database.
*/
private Uri insertLecture(Uri uri, ContentValues values) {
// Check that the name is not null
String name = values.getAsString(StudentContract.LectureEntry.COLUMN_LECTURE_NAME);
if (name == null) {
throw new IllegalArgumentException("Lecture requires a name");
}
// Check that the day is valid
Integer day = values.getAsInteger(StudentContract.LectureEntry.COLUMN_LECTURE_DAY);
if (day == null || !StudentContract.LectureEntry.isValidDay(day)) {
throw new IllegalArgumentException("Lecture requires valid day");
}
// No need to check the start_time or end_time, any time is valid (including null).
// Get writeable database
SQLiteDatabase database = mDbHelper.getWritableDatabase();
// Insert the new lecture with the given values
long id = database.insert(StudentContract.LectureEntry.TABLE_NAME, null, values);
if (id == -1) {
return null;
}
// Return the new URI with the ID (of the newly inserted row) appended at the end
return ContentUris.withAppendedId(uri, id);
}
@Override
public int update(Uri uri, ContentValues contentValues, String selection,
String[] selectionArgs) {
final int match = sUriMatcher.match(uri);
switch (match) {
case LECTURES:
return updateLecture(uri, contentValues, selection, selectionArgs);
case LECTURES_ID:
// For the LECTURES_ID code, extract out the ID from the URI,
// so we know which row to update. Selection will be "_id=?" and selection
// arguments will be a String array containing the actual ID.
selection = StudentContract.LectureEntry._ID + "=?";
selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };
return updateLecture(uri, contentValues, selection, selectionArgs);
default:
throw new IllegalArgumentException("Update is not supported for " + uri);
}
}
/**
* Update lectures in the database with the given content values. Apply the changes to the rows
* specified in the selection and selection arguments (which could be 0 or 1 or more lectures).
* Return the number of rows that were successfully updated.
*/
private int updateLecture(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
// If the {@link LectureEntry#COLUMN_LECTURE_NAME} key is present,
// check that the name value is not null.
if (values.containsKey(StudentContract.LectureEntry.COLUMN_LECTURE_NAME)) {
String name = values.getAsString(StudentContract.LectureEntry.COLUMN_LECTURE_NAME);
if (name == null) {
throw new IllegalArgumentException("Lecture requires a name");
}
}
// If the {@link LectureEntry#COLUMN_LECTURE_DAY} key is present,
// check that the day value is valid.
if (values.containsKey(StudentContract.LectureEntry.COLUMN_LECTURE_DAY)) {
Integer day = values.getAsInteger(StudentContract.LectureEntry.COLUMN_LECTURE_DAY);
if (day == null || !StudentContract.LectureEntry.isValidDay(day)) {
throw new IllegalArgumentException("Lecture requires valid day");
}
}
// If the {@link LectureEntry#COLUMN_LECTURE_DAY} key is present,
// check that the day value is valid.
if (values.containsKey(StudentContract.LectureEntry.COLUMN_LECTURE_DAY)) {
Integer day = values.getAsInteger(StudentContract.LectureEntry.COLUMN_LECTURE_DAY);
}
// No need to check the start_time and end_time, any value is valid (including null).
// If there are no values to update, then don't try to update the database
if (values.size() == 0) {
return 0;
}
// Otherwise, get writeable database to update the data
SQLiteDatabase database = mDbHelper.getWritableDatabase();
// Returns the number of database rows affected by the update statement
return database.update(StudentContract.LectureEntry.TABLE_NAME, values, selection, selectionArgs);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Get writeable database
SQLiteDatabase database = mDbHelper.getWritableDatabase();
final int match = sUriMatcher.match(uri);
switch (match) {
case LECTURES:
// Delete all rows that match the selection and selection args
return database.delete(StudentContract.LectureEntry.TABLE_NAME, selection, selectionArgs);
case LECTURES_ID:
// Delete a single row given by the ID in the URI
selection = StudentContract.LectureEntry._ID + "=?";
selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };
return database.delete(StudentContract.LectureEntry.TABLE_NAME, selection, selectionArgs);
default:
throw new IllegalArgumentException("Deletion is not supported for " + uri);
}
}
@Override
public String getType(Uri uri) {
final int match = sUriMatcher.match(uri);
switch (match) {
case LECTURES:
return StudentContract.LectureEntry.CONTENT_LIST_TYPE;
case LECTURES_ID:
return StudentContract.LectureEntry.CONTENT_ITEM_TYPE;
default:
throw new IllegalStateException("Unknown URI " + uri + " with match " + match);
}
}
}
StudentDbHelper.java
package com.example.utkarsh_pc.tester_app.data;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class StudentDbHelper extends SQLiteOpenHelper {
public static final String LOG_TAG = StudentDbHelper.class.getSimpleName();
private static final String DATABASE_NAME = "student.db";
private static final int DATABASE_VERSION = 1;
public StudentDbHelper(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db){
String SQL_CREATE_TABLE = "CREATE TABLE " + StudentContract.LectureEntry.TABLE_NAME + " ("
+ StudentContract.LectureEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ StudentContract.LectureEntry.COLUMN_LECTURE_NAME + " TEXT NOT NULL, "
+ StudentContract.LectureEntry.COLUMN_LECTURE_TEACHER + " TEXT, "
+ StudentContract.LectureEntry.COLUMN_LECTURE_STARTTIME + " TEXT, "
+ StudentContract.LectureEntry.COLUMN_LECTURE_ENDTIME + " TEXT, "
+ StudentContract.LectureEntry.COLUMN_LECTURE_DAY + " INTEGER NOT NULL);";
db.execSQL(SQL_CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){}
}
StudentContract.java
package com.example.utkarsh_pc.tester_app.data;
import android.content.ContentResolver;
import android.net.Uri;
import android.provider.BaseColumns;
public final class StudentContract {
private StudentContract() {
}
public static final String CONTENT_AUTHORITY = "com.example.utkarsh_pc.tester_app";
public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
public static final String PATH_LECTURES = "lectures";
public static final class LectureEntry implements BaseColumns {
public static final Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, PATH_LECTURES);
public static final String CONTENT_LIST_TYPE =
ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_LECTURES;
public static final String CONTENT_ITEM_TYPE =
ContentResolver.CURSOR_ITEM_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_LECTURES;
public static final String TABLE_NAME = "lectures";
public static final String _ID = BaseColumns._ID;
public static final String COLUMN_LECTURE_NAME = "name";
public static final String COLUMN_LECTURE_TEACHER = "teacher";
public static final String COLUMN_LECTURE_STARTTIME = "start_time";
public static final String COLUMN_LECTURE_ENDTIME = "end_time";
public static final String COLUMN_LECTURE_DAY = "day";
/**
* Possible values for the day of the lecture.
*/
public static final int DAY_MONDAY = 0;
public static final int DAY_TUESDAY = 1;
public static final int DAY_WEDNESDAY = 2;
public static final int DAY_THURSDAY = 3;
public static final int DAY_FRIDAY = 4;
public static final int DAY_SATURDAY = 5;
public static final int DAY_SUNDAY = 6;
/**
* Returns whether or not the given day is {@link #DAY_MONDAY}, {@link #DAY_TUESDAY},
* {@link #DAY_WEDNESDAY},{@link #DAY_THURSDAY},{@link #DAY_FRIDAY},{@link #DAY_SATURDAY}
* or {@link #DAY_SUNDAY}.
*/
public static boolean isValidDay(int day) {
if (day == DAY_MONDAY || day == DAY_TUESDAY || day == DAY_WEDNESDAY || day == DAY_THURSDAY || day == DAY_FRIDAY || day == DAY_SATURDAY || day == DAY_SUNDAY) {
return true;
} else {
return false;
}
}
}
}
MondayActivity.java
package com.example.utkarsh_pc.tester_app;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.example.utkarsh_pc.tester_app.data.StudentContract;
import com.example.utkarsh_pc.tester_app.data.StudentDbHelper;
import com.example.utkarsh_pc.tester_app.data.StudentProvider;
import java.util.Objects;
public class MondayActivity extends AppCompatActivity {
ListView listView_mon;
String[] sub_mon = new String[]{"Sub1", "Sub2", "Sub3"};
FloatingActionButton fab;
private final String TAG = MondayActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_monday);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar1);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Monday");
fab = (FloatingActionButton) findViewById(R.id.fab1);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MondayActivity.this, AddSubject1Activity.class);
startActivity(intent);
}
});
}
@Override
protected void onStart(){
super.onStart();
displayLectureInfo();
}
private void displayLectureInfo() {
String[] projections = new String[]{StudentContract.LectureEntry._ID,
StudentContract.LectureEntry.COLUMN_LECTURE_NAME,
StudentContract.LectureEntry.COLUMN_LECTURE_STARTTIME,
StudentContract.LectureEntry.COLUMN_LECTURE_ENDTIME,
StudentContract.LectureEntry.COLUMN_LECTURE_TEACHER,
StudentContract.LectureEntry.COLUMN_LECTURE_DAY};
Cursor cursor;
cursor = getContentResolver().query(
StudentContract.LectureEntry.CONTENT_URI, // The content URI of the words table
projections, // The columns to return for each row
null, // Selection criteria
null, // Selection criteria
null); // The sort order for the returned rows
TextView displayView = (TextView) findViewById(R.id.sample_view_1);
try {
displayView.setText("The lecture table contains " + cursor.getCount() + " lectures.\n\n");
displayView.append(StudentContract.LectureEntry._ID + " - " +
StudentContract.LectureEntry.COLUMN_LECTURE_NAME + " - " +
StudentContract.LectureEntry.COLUMN_LECTURE_STARTTIME + " - " +
StudentContract.LectureEntry.COLUMN_LECTURE_ENDTIME + " - " +
StudentContract.LectureEntry.COLUMN_LECTURE_TEACHER + " - " +
StudentContract.LectureEntry.COLUMN_LECTURE_DAY + "\n");
// Figure out the index of each column
int idColumnIndex = cursor.getColumnIndex(StudentContract.LectureEntry._ID);
int nameColumnIndex = cursor.getColumnIndex(StudentContract.LectureEntry.COLUMN_LECTURE_NAME);
int starttimeColumnIndex = cursor.getColumnIndex(StudentContract.LectureEntry.COLUMN_LECTURE_STARTTIME);
int endtimeColumnIndex = cursor.getColumnIndex(StudentContract.LectureEntry.COLUMN_LECTURE_ENDTIME);
int teacherColumnIndex = cursor.getColumnIndex(StudentContract.LectureEntry.COLUMN_LECTURE_TEACHER);
int dayColumnIndex = cursor.getColumnIndex(StudentContract.LectureEntry.COLUMN_LECTURE_DAY);
// Iterate through all the returned rows in the cursor
while (cursor.moveToNext() || cursor.isFirst()) {
// Use that index to extract the String or Int value of the word
// at the current row the cursor is on.
int currentID = cursor.getInt(idColumnIndex);
String currentName = cursor.getString(nameColumnIndex);
String currentStartttime = cursor.getString(starttimeColumnIndex);
String currentEndtime = cursor.getString(endtimeColumnIndex);
String currentTeacher = cursor.getString(teacherColumnIndex);
int currentDay = cursor.getInt(dayColumnIndex);
// Display the values from each column of the current row in the cursor in the TextView
displayView.append(("\n" + currentID + " - " +
currentName + " - " +
currentStartttime + " - " +
currentEndtime + " - " +
currentEndtime + " - " +
currentTeacher + " - " +
currentDay));
}
} finally {
cursor.close();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.timetable_menu1, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.back:
Intent intent = new Intent(MondayActivity.this, MainActivity.class);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
答案 0 :(得分:0)
您是否在Manifest中添加了ContentProvider?
SELECT [qryBatchByPO-LI].Batch, [qryBatchByPO-LI].[PO LI],
tblBatches.[Short text], tblWIP.[Date]
FROM [qryBatchByPO-LI]
INNER JOIN tblEDSS_WIP ON [qryBatchByPO-LI].[PO LI] = tblEDSS_WIP.[PO-LI];
如果您的应用只能访问ContentProvider ,则android:exported为false