Haloa ^^我有以下问题:
02-16 21:08:13.550 2350-2350/com.tutos.android.content.provider E/ActivityThread﹕ Failed to find provider info for com.tutos.android.content.provider.androidprovider
02-16 21:08:13.550 2350-2350/com.tutos.android.content.provider D/AndroidRuntime﹕ Shutting down VM
02-16 21:08:13.550 2350-2350/com.tutos.android.content.provider E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.tutos.android.content.provider, PID: 2350
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tutos.android.content.provider/com.tutos.android.content.provider.ContentProviderExempleActivity}: java.lang.IllegalArgumentException: Unknown URL content://com.tutos.android.content.provider.androidprovider
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
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:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.IllegalArgumentException: Unknown URL content://com.tutos.android.content.provider.androidprovider
at android.content.ContentResolver.insert(ContentResolver.java:1203)
at com.tutos.android.content.provider.ContentProviderExempleActivity.insertRecords(ContentProviderExempleActivity.java:53)
at com.tutos.android.content.provider.ContentProviderExempleActivity.onCreate(ContentProviderExempleActivity.java:21)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
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:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
如您所见,Android Studio无法找到提供商。
这是我的清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tutos.android.content.provider" >
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".ContentProviderExempleActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="com.tutos.android.content.provider.AndroidProvider"
android:authorities="com.tutos.android.content.provider.androidprovider" />
</application>
</manifest>
这是我的提供者类:
package com.tutos.android.content.provider;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQuery;
import android.net.Uri;
import com.tutos.android.content.provider.SharedInformation.*;
/**
* Created by Omar on 16/02/2015.
*/
public class AndroidProvider extends ContentProvider{
//URI de notre content provider, elle sera utilisé pour accéder au ContentProvider
//Composed of de "content://"+package.(someString)
public static final Uri CONTENT_URI = Uri.parse("content://com.tutos.android.content.provider.androidprovider");
//Déclaration du nom de la base de données
public static final String CONTENT_PROVIDER_DB_NAME = "tutosandroid.db";
//Déclaration de la version de la base de données
public static final int CONTENT_PROVIDER_DB_VERSION = 1;
//Déclaration Nom de la table de notre base
public static final String CONTENT_PROVIDER_TABLE_NAME = "cours";
//Déclaration du MIME de notre content provider / La premiere partie est toujours identique
public static final String CONTENT_PROVIDER_MIME = "vnd.android.cursor.item/vnd.tutos.android.content.provider.cours";
//Notre Database Helper
public static class DatabaseHelper extends SQLiteOpenHelper{
//Notre constructeur à partir du contect / database name / db version
public DatabaseHelper(Context context) {
super(context, AndroidProvider.CONTENT_PROVIDER_DB_NAME, null, AndroidProvider.CONTENT_PROVIDER_DB_VERSION);
}
//Creation de la table
@Override
public void onCreate(SQLiteDatabase db) {
//requet de création
String ReqCrea = "CREATE TABLE "+AndroidProvider.CONTENT_PROVIDER_DB_NAME+" ("+Cours.COURS_ID+" INTEGER PRIMARY KEY AUTOINCREMENT,"
+Cours.COURS_NAME+ " VARCHAR(255),"+Cours.COURS_DESC+" VARCHAR(255)"+");";
//Execution de la requete avec le param db
db.execSQL(ReqCrea);
}
//OnUpgrade gere la montée de version de notre db
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//suppresion de la db
db.execSQL("DROP TABLE IF EXISTS "+AndroidProvider.CONTENT_PROVIDER_TABLE_NAME);
//recrea de la db
onCreate(db);
}
}
//Création d'un attribut de type DatabaseHelper
private DatabaseHelper dbHelper;
@Override
public boolean onCreate() {
//Création avec constructeur et get context pour avoir le context
dbHelper = new DatabaseHelper(getContext());
return true;
}
@Override
public String getType(Uri uri) {
return AndroidProvider.CONTENT_PROVIDER_MIME;
}
//get id , retourne l'id de l'uri qui est le dernier fragement (lastPathSegment)
//content://com.tutos.android.content.provider/cours/22 <-- ID
public long getID(Uri uri){
//get last segment from the URI entred
String lastPathSegment = uri.getLastPathSegment();
if (lastPathSegment!=null){
try {
return Long.parseLong(lastPathSegment);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
return -1;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
//get id pour voir si on a une ligne à select
long id = getID(uri);
//on get une instance readable only since on fait un select
SQLiteDatabase db = dbHelper.getReadableDatabase();
try {
if (id<0){
return db.query(AndroidProvider.CONTENT_PROVIDER_TABLE_NAME,projection,selection,selectionArgs,null,null,sortOrder);
}
else {
return db.query(AndroidProvider.CONTENT_PROVIDER_TABLE_NAME,projection,Cours.COURS_ID+" = "+id,null,null,null,null);
}
} finally {
db.close();
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
//recuparation d'une instance de la db en mode ecriture
SQLiteDatabase db = dbHelper.getWritableDatabase();
//on insert les données dans la table de la db
long id = db.insertOrThrow(AndroidProvider.CONTENT_PROVIDER_TABLE_NAME,null,values);
// sir rien ne s'insert et qu'on un retour de -1 on throw une exception
try {
if(id==-1){
throw new RuntimeException(String.format("%s : failed to insert [%s] for unknown reason.","AndroidProvider",values,uri));
}
else{
//a new URI with the given ID appended to the end of the path
//content://com.tutos.android.content.provider/cours/ID <--- ID
return ContentUris.withAppendedId(uri,id);
}
} finally {
//cloturation de la db
db.close();
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// on fait appel à getID pour avoir l'id de l'uri passé cad la ligne à modifier
long id = getID(uri);
//création d'une instance de notre db en mode écriture
SQLiteDatabase db = dbHelper.getWritableDatabase();
try {
//si on a pas un id on delete normalement en utlisant les param selection
if(id<0){
return db.delete(AndroidProvider.CONTENT_PROVIDER_TABLE_NAME,selection,selectionArgs);
}
//si on a un id on delete where notre cours id = l'id de notre URI
else {
return db.delete(AndroidProvider.CONTENT_PROVIDER_TABLE_NAME,Cours.COURS_ID+" = "+id,null);
}
} finally {
//on clot la db peut importe la sortie
db.close();
}
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
// on fait appel à getID pour avoir l'id de l'uri passé cad la ligne à modifier
long id = getID(uri);
//création d'une instance de notre db en mode écriture
SQLiteDatabase db = dbHelper.getWritableDatabase();
try {
//si on a pas un id on update normalement en utlisant les param selection
if (id<0){
return db.update(AndroidProvider.CONTENT_PROVIDER_TABLE_NAME,values,selection,selectionArgs);
}
//si on a un id on update where notre cours id = l'id de notre URI
else{
return db.update(AndroidProvider.CONTENT_PROVIDER_TABLE_NAME,values,Cours.COURS_ID+" = "+id,null);
}
} finally {
//on clot la db peut importe la sortie
db.close();
}
}
}
主要活动代码:
package com.tutos.android.content.provider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.tutos.android.content.provider.SharedInformation.*;
public class ContentProviderExempleActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content_provider_exemple);
insertRecords();
displayContentProvider();
}
private void displayContentProvider() {
String Columns[] = new String[]{Cours.COURS_ID,Cours.COURS_NAME,Cours.COURS_DESC};
Uri mContact = AndroidProvider.CONTENT_URI;
Cursor cur = getContentResolver().query(mContact, Columns, null, null, null);
Toast.makeText(this,cur.getCount()+"",Toast.LENGTH_LONG).show();
if(cur.moveToFirst()){
String name=null;
do {
name = cur.getString(cur.getColumnIndex(Cours.COURS_ID))+" "
+ cur.getString(cur.getColumnIndex(Cours.COURS_NAME))+" "
+ cur.getString(cur.getColumnIndex(Cours.COURS_DESC));
Toast.makeText(this,name+" ",Toast.LENGTH_LONG);
}while (cur.moveToNext());
}
}
private void insertRecords() {
//On crée un ContentValue, puis on appelle la méthode getContentResolver pour récupérer
//une instance de ContentProvider, puis on appelle la méthode insert avec l’uri et les valeurs à insérer.
ContentValues contact = new ContentValues();
contact.put(Cours.COURS_NAME,"Android");
contact.put(Cours.COURS_DESC,"Introduction à la programmation sous Android");
getContentResolver().insert(AndroidProvider.CONTENT_URI,contact);
//on vide le contentValue avant de réinserrer
contact.clear();
contact.put(Cours.COURS_ID,"Java");
contact.put(Cours.COURS_DESC,"Introduction à la programmation Java");
getContentResolver().insert(AndroidProvider.CONTENT_URI,contact);
contact.clear();
contact.put(Cours.COURS_NAME, "Iphone");
contact.put(Cours.COURS_DESC, "Introduction à l'objectif C");
getContentResolver().insert(AndroidProvider.CONTENT_URI, contact);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_content_provider_exemple, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
我尝试了大量的组合,包括Lower和Upper,但仍然没有:(
你能帮忙吗?
我正在使用android studio 这是我的项目结构:
的java 1com.tutos.android.content.provider 2AndroidProvider 2ContentProviderExempleActivity
提前致谢! ^^
答案 0 :(得分:2)
您共享的代码中有一个小的更正 -
以下声明
public static final Uri CONTENT_URI = Uri.parse("content://com.tutos.android.content.provider.androidprovider");
应改为
public static final Uri CONTENT_URI = Uri.parse("content://com.tutos.android.content.provider/androidprovider");
这是例外的实际原因。
答案 1 :(得分:1)
我通过更改:
解决了这个问题//Creation de la table
@Override
public void onCreate(SQLiteDatabase db) {
//requet de création
String ReqCrea = "CREATE TABLE "+AndroidProvider.CONTENT_PROVIDER_DB_NAME+" ("+Cours.COURS_ID+" INTEGER PRIMARY KEY AUTOINCREMENT,"
+Cours.COURS_NAME+ " VARCHAR(255),"+Cours.COURS_DESC+" VARCHAR(255)"+");";
//Execution de la requete avec le param db
db.execSQL(ReqCrea);
}
要
String ReqCrea = "CREATE TABLE "+AndroidProvider.CONTENT_PROVIDER_TABLE_NAME+" ("+Cours.COURS_ID+" INTEGER PRIMARY KEY AUTOINCREMENT,"
+Cours.COURS_NAME+ " VARCHAR(255),"+Cours.COURS_DESC+" VARCHAR(255)"+");";