我的Provider中的java.lang.IllegalStateException

时间:2016-09-25 11:02:07

标签: android sqlite android-contentprovider illegalstateexception

我有一个内容提供商存储一些数据(朋友的名字和他的生日日期)。我从here得到了这个例子。

然而,当我尝试添加这些数据时,我得到了这个例外!

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: theo.testing.friendsprovider, PID: 4363
              java.lang.IllegalStateException: Could not execute method for android:onClick
                  at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
                  at android.view.View.performClick(View.java:4780)
                  at android.view.View$PerformClick.run(View.java:19866)
                  at android.os.Handler.handleCallback(Handler.java:739)
                  at android.os.Handler.dispatchMessage(Handler.java:95)
                  at android.os.Looper.loop(Looper.java:135)
                  at android.app.ActivityThread.main(ActivityThread.java:5254)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at java.lang.reflect.Method.invoke(Method.java:372)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
               Caused by: java.lang.reflect.InvocationTargetException
                  at java.lang.reflect.Method.invoke(Native Method)
                  at java.lang.reflect.Method.invoke(Method.java:372)
                  at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
                  at android.view.View.performClick(View.java:4780) 
                  at android.view.View$PerformClick.run(View.java:19866) 
                  at android.os.Handler.handleCallback(Handler.java:739) 
                  at android.os.Handler.dispatchMessage(Handler.java:95) 
                  at android.os.Looper.loop(Looper.java:135) 
                  at android.app.ActivityThread.main(ActivityThread.java:5254) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at java.lang.reflect.Method.invoke(Method.java:372) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
               Caused by: java.lang.IllegalArgumentException: Unknown URL content://theo.testing.friendsprovider.BirthdayProv/friends
                  at android.content.ContentResolver.insert(ContentResolver.java:1203)
                  at theo.testing.friendsprovider.MainActivity.addBirthday(MainActivity.java:42)
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at java.lang.reflect.Method.invoke(Method.java:372) 
                  at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
                  at android.view.View.performClick(View.java:4780) 
                  at android.view.View$PerformClick.run(View.java:19866) 
                  at android.os.Handler.handleCallback(Handler.java:739) 
                  at android.os.Handler.dispatchMessage(Handler.java:95) 
                  at android.os.Looper.loop(Looper.java:135) 
                  at android.app.ActivityThread.main(ActivityThread.java:5254) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at java.lang.reflect.Method.invoke(Method.java:372) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 

由于某些原因,我的Uri值无效。这是我的代码。

public class FriendsProvider extends ContentProvider {
//Fields for the content provider
static final String PROVIDER_NAME = "theo.testing.friendsprovider";
static final String URL = "content://" + PROVIDER_NAME + "/friends";
static final Uri CONTENT_URI = Uri.parse(URL);

//Field for the database
static final String ID = "id";
static final String NAME = "name";
static final String BIRTHDAY = "birthday";

//integer values used in content URI
static final int FRIENDS = 1;
static final int FRIENDS_ID = 2;

DBHelper dbHelper;

//Projections map for a query
private static HashMap<String,String> FriendsMap;
//Filling out the Uri matcher
static final UriMatcher uriMatcher;


static{
    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    uriMatcher.addURI(PROVIDER_NAME,"friends",FRIENDS);
    uriMatcher.addURI(PROVIDER_NAME,"friends/#",FRIENDS_ID);
}

// database declarations
private SQLiteDatabase database;
static final String DATABASE_NAME = "BirthdayReminder";
static final String TABLE_NAME = "birthTable";
static final int DATABASE_VERSION = 1;
static final String CREATE_TABLE =
        " CREATE TABLE " + TABLE_NAME +
                " (id INTEGER PRIMARY KEY AUTOINCREMENT, " +
                " name TEXT NOT NULL, " +
                " birthday TEXT NOT NULL);";

public class DBHelper extends SQLiteOpenHelper {
    static final String CREATE_TABLE =
            " CREATE TABLE " + TABLE_NAME +
                    " (id INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    " name TEXT NOT NULL, " +
                    " birthday TEXT NOT NULL);";
    public DBHelper(Context context) {
        super(context, DATABASE_NAME, null,DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL(CREATE_TABLE);

    }

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

        sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " +TABLE_NAME);

    }
}

@Override
public boolean onCreate() {
    Context context = getContext();
    dbHelper = new DBHelper(context);
    //permissions to be writable
    database = dbHelper.getWritableDatabase();
    return false;
}

@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
    queryBuilder.setTables(TABLE_NAME);

    switch (uriMatcher.match(uri)){
        case FRIENDS:
            queryBuilder.setProjectionMap(FriendsMap);
            break;
        case FRIENDS_ID:
            queryBuilder.appendWhere(ID + "=" + uri.getLastPathSegment());
            break;
        default:
            throw new IllegalArgumentException("Unkown URI:"+uri);
    }
    //sort name by default
    if(sortOrder == null){
        sortOrder = NAME;
    }
    Cursor cursor = queryBuilder.query(database,projection,selection,selectionArgs,null,null,sortOrder);
    cursor.setNotificationUri(getContext().getContentResolver(),uri);
    return null;
}

@Nullable
@Override
public String getType(Uri uri) {
    switch (uriMatcher.match(uri)){

        // Get all friend-birthday records

        case FRIENDS:

            return "vnd.android.cursor.dir/vnd.example.friends";

        // Get a particular friend

        case FRIENDS_ID:

            return "vnd.android.cursor.item/vnd.example.friends";

        default:

            throw new IllegalArgumentException("Unsupported URI: " + uri);

    }

}

@Nullable
@Override
public Uri insert(Uri uri, ContentValues contentValues) {
   //Insertion of the table's data
   long row = database.insert(TABLE_NAME,null,contentValues);

    //If row was added successfully
    if(row > 0){
        Uri newUri = ContentUris.withAppendedId(CONTENT_URI,row);
        getContext().getContentResolver().notifyChange(newUri,null);
    }
    //Else throw an exception.
    throw new SQLException("Fail to add a new record into " + uri);
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
    // TODO Auto-generated method stub
    int count = 0;

    switch (uriMatcher.match(uri)){
        case FRIENDS:
            // delete all the records of the table
            count = database.delete(TABLE_NAME, selection, selectionArgs);
            break;
        case FRIENDS_ID:
            String id = uri.getLastPathSegment();   //gets the id
            count = database.delete( TABLE_NAME, ID +  " = " + id +
                    (!TextUtils.isEmpty(selection) ? " AND (" +
                            selection + ')' : ""), selectionArgs);
            break;
        default:
            throw new IllegalArgumentException("Unsupported URI " + uri);
    }

    getContext().getContentResolver().notifyChange(uri, null);
    return count;


}

@Override
public int update(Uri uri, ContentValues values, String selection,
                  String[] selectionArgs) {
    // TODO Auto-generated method stub
    int count = 0;

    switch (uriMatcher.match(uri)){
        case FRIENDS:
            count = database.update(TABLE_NAME, values, selection, selectionArgs);
            break;
        case FRIENDS_ID:
            count = database.update(TABLE_NAME, values, ID +
                    " = " + uri.getLastPathSegment() +
                    (!TextUtils.isEmpty(selection) ? " AND (" +
                            selection + ')' : ""), selectionArgs);
            break;
        default:
            throw new IllegalArgumentException("Unsupported URI " + uri );
    }
    getContext().getContentResolver().notifyChange(uri, null);
    return count;
}

}

MainActivity类

public class MainActivity extends AppCompatActivity {

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

public void deleteAllBirthdays(View view){
    String URL = "theo.testing.friendsprovider";
    Uri friends = Uri.parse(URL);

    int count = getContentResolver().delete(
            friends,null,null
    );

    String countNum = "My Friends: " + count + " records are deleted";

    Toast.makeText(getBaseContext(),count,Toast.LENGTH_SHORT).show();
}

public void addBirthday(View view){
    ContentValues values = new ContentValues();

    values.put(FriendsProvider.NAME,
            ((EditText)findViewById(R.id.name)).getText().toString());

    values.put(FriendsProvider.BIRTHDAY,
            ((EditText)findViewById(R.id.birthday)).getText().toString());

    Uri uri = getContentResolver().insert(FriendsProvider.CONTENT_URI,values);

    Toast.makeText(getBaseContext(),"My friend: " +uri.toString() + " inserted",Toast.LENGTH_SHORT).show();
}

public void showAllBirthdays(View view){
    String URL = "theo.testing.friendsprovider";
    Uri friends = Uri.parse(URL);

    Cursor c = getContentResolver().query(friends,null,null,null,"name");
    String results = "My friends:";

    if (!c.moveToFirst()) {
        Toast.makeText(this, results+" no content yet!", Toast.LENGTH_LONG).show();
    }else{
        do{
            results = results + "\n" + c.getString(c.getColumnIndex(FriendsProvider.NAME)) +
                    " with id " +  c.getString(c.getColumnIndex(FriendsProvider.ID)) +
                    " has birthday: " + c.getString(c.getColumnIndex(FriendsProvider.BIRTHDAY));
        } while (c.moveToNext());
        Toast.makeText(this, results, Toast.LENGTH_LONG).show();
    }
   }
}

这一行引发了我的异常。

Uri uri = getContentResolver().insert(FriendsProvider.CONTENT_URI,values);

最后这是我的 manifest.xml 文件。

<?xml version="1.0" encoding="utf-8"?>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>
<provider
    android:name=".FriendProvider"
    android:authorities="theo.testing.friendsprovider"
    >
</provider>

如您所见,提供商已注册了权限及其名称。另外,我有所有陈述的变量。

static final String PROVIDER_NAME = "theo.testing.friendsprovider";
static final String URL = "content://" + PROVIDER_NAME + "/friends";
static final Uri CONTENT_URI = Uri.parse(URL);

有什么想法吗?

提前致谢,

西奥

1 个答案:

答案 0 :(得分:2)

在应用标记

中添加提供者标记
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
<provider
    android:name=".FriendProvider"
    android:authorities="theo.testing.friendsprovider"
    >
</provider>

</application>