Android中未知的URL内容

问题描述 投票:0回答:1

我是Android新手。我想练习有关Content Provide的知识,但是我的应用程序以某种方式崩溃并告诉我有未知的URL内容。我尝试搜索解决方案,但仍然无法解决问题...

logcat消息:

 2020-05-25 20:10:24.547 15120-15120/com.example.punchinandout E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.example.punchinandout, PID: 15120
        java.lang.IllegalArgumentException: Unknown URL content://com.example.punchinandout.data/time
            at android.content.ContentResolver.insert(ContentResolver.java:1535)
            at com.example.punchinandout.MainActivity$1.onClick(MainActivity.java:65)
            at android.view.View.performClick(View.java:6256)
            at android.view.View$PerformClick.run(View.java:24701)
            at android.os.Handler.handleCallback(Handler.java:789)
            at android.os.Handler.dispatchMessage(Handler.java:98)
            at android.os.Looper.loop(Looper.java:164)
            at android.app.ActivityThread.main(ActivityThread.java:6541)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

我在Mainifest中的提供者:

<provider
            android:authorities="com.example.punchinandout"
            android:name=".data.TimeProvider"
            android:exported="false"/> 

我的内容提供商类:

package com.example.punchinandout.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;

import com.example.punchinandout.data.TimeContract.TimeEntry;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class TimeProvider extends ContentProvider {
    private static final String TAG = TimeProvider.class.toString();

    private static final int TIME = 100;
    private static final int TIME_ID = 101;

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

    //Determine which content URI we have.
    static{
        sUriMatcher.addURI(TimeContract.CONTENT_AUTHORITY, TimeContract.CONTENT_PATH, TIME);
        sUriMatcher.addURI(TimeContract.CONTENT_AUTHORITY, TimeContract.CONTENT_PATH, TIME_ID);
    }

    private TimeHelper mDbHelper;

    @Override
    public boolean onCreate() {
        mDbHelper = new TimeHelper(getContext());
        return true;
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        SQLiteDatabase database = mDbHelper.getReadableDatabase();
        Cursor cursor;
        int match = sUriMatcher.match(uri);

        switch (match){
            case TIME:
                cursor = database.query(TimeEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
                break;

            case TIME_ID:
                selection = TimeEntry._ID + "=?";
                selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
                cursor = database.query(TimeEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
                break;

            default:
                throw new IllegalArgumentException("Cannot query with unknown URI: " + uri);
        }
        cursor.setNotificationUri(getContext().getContentResolver(), uri); //Set notification URI on cursor, so that the cursor will update when the URI is updated.
        return cursor;
    }

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
        int match = sUriMatcher.match(uri);
        switch (match){
            case TIME:
                return insertTimeRecord(uri, values);

            default:
                throw new IllegalArgumentException("Insertion is no support for " + uri);
        }
    }

    private Uri insertTimeRecord(Uri uri, ContentValues values){
        //Sanity check
        if (values.containsKey(TimeEntry.COLUMN_RECORD)){
            String time_record = values.getAsString(TimeEntry.COLUMN_RECORD);
            if (time_record == null){
                throw new IllegalArgumentException("Time record cannot be empty.");
            }
        }

        //If there are no values to update, then don't try to update the database.
        if (values.size() == 0){
            return null;
        }

        SQLiteDatabase database = mDbHelper.getWritableDatabase();
        long newRowId = database.insert(TimeEntry.TABLE_NAME, null, values);

        //Check if the insertion is success.
        if (newRowId == -1){
            Log.e(TAG, "Insertion fail with " + uri);
            return null;
        }

        getContext().getContentResolver().notifyChange(uri, null); //Notify all listener the data has changed
        return ContentUris.withAppendedId(uri, newRowId);
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
        int match = sUriMatcher.match(uri);
        switch (match){
            case TIME:
                return updateTimeRecord(uri, values, selection, selectionArgs);

            case TIME_ID:
                selection = TimeEntry._ID + "=?";
                selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
                return updateTimeRecord(uri, values, selection, selectionArgs);

            default:
                throw new IllegalArgumentException("Update fail with " + uri);
        }
    }

    private int updateTimeRecord(Uri uri, ContentValues values, String selection, String[] selectionArgs){
        //Sanity check
        if (values.containsKey(TimeEntry.COLUMN_RECORD)){
            String time_record = values.getAsString(TimeEntry.COLUMN_RECORD);
            if (time_record == null){
                return 0; //If the data is not inputted, update nothing in database.
            }
        }

        //If there are no values to update, then don't try to update the database.
        if (values.size() == 0){
            return 0;
        }

        SQLiteDatabase database = mDbHelper.getWritableDatabase();
        int rowUpdated = database.update(TimeEntry.TABLE_NAME, values, selection, selectionArgs);

        if (rowUpdated != 0){
            getContext().getContentResolver().notifyChange(uri, null); //Notify all listener the data has changed
        }

        return rowUpdated;
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
        int match = sUriMatcher.match(uri);
        switch (match){
            case TIME:
                return deleteTimeRecord(uri, selection, selectionArgs);

            case TIME_ID:
                selection = TimeEntry._ID + "=?";
                selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
                return deleteTimeRecord(uri, selection, selectionArgs);

            default:
                throw new IllegalArgumentException("Delete fail with " + uri);
        }
    }

    private int deleteTimeRecord(Uri uri, String selection, String[] selectionArgs){
        SQLiteDatabase database = mDbHelper.getWritableDatabase();
        int rowDelected = database.delete(TimeEntry.TABLE_NAME, selection, selectionArgs);
        if (rowDelected != 0){
            getContext().getContentResolver().notifyChange(uri, null); //Notify all listener the data has changed
        }
        return rowDelected;
    }

    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        int match = sUriMatcher.match(uri);
        switch (match){
            case TIME:
                return TimeEntry.CONTENT_LIST_TYPE;

            case TIME_ID:
                return TimeEntry.CONTENT_ITEM_TYPE;

            default:
                throw new IllegalArgumentException("Unknown URI " + uri + " with match " + match);
        }
    }
}

我的合同类别:

package com.example.punchinandout.data;

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

public class TimeContract {

    private TimeContract(){};

    public static final String CONTENT_AUTHORITY = "com.example.punchinandout.data";
    public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
    public static final String CONTENT_PATH = "time";

    public static final class TimeEntry implements BaseColumns {
        public static final Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, CONTENT_PATH);

        //MIME type of all records.
        public static final String CONTENT_LIST_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + CONTENT_PATH;

        //MIME type of single record.
        public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + CONTENT_PATH;

        public static final String TABLE_NAME = "time";

        public static final String _ID = BaseColumns._ID;
        public static final String COLUMN_RECORD = "record";
    }
}

有人可以帮我吗? :(

android database android-sqlite android-contentprovider illegalargumentexception
1个回答
0
投票

我已经解决了问题!

我在Mainifest中的提供者是:

<provider
            android:authorities="com.example.punchinandout"
            android:name=".data.TimeProvider"
            android:exported="false"/> 

然后我变成:

<provider
            android:authorities="com.example.punchinandout.data"
            android:name=".data.TimeProvider"
            android:exported="false"/>

让权限与合同类中的权限相同,并且问题已解决!

很抱歉第一次没有将Mainifest放在问题中,因为我之前都不知道应用程序中的问题在哪里。

© www.soinside.com 2019 - 2024. All rights reserved.