简体   繁体   English

Android ContentProvider Uri问题(未知的URL内容)

[英]Android ContentProvider Uri Issue ( Unknown URL content )

Haloa ^^ I have the following issue : 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)

As you can see , Android Studio fail to find the provider. 如您所见,Android Studio无法找到提供程序。

Here is my manifest : 这是我的清单:

<?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>

And here is my provider class : 这是我的提供程序类:

    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();
        }
    }

}

The main activity code : 主要活动代码:

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);
    }
}

I tried a lot of composition with Lower and Upper cases but still nothing :( 我用大写和小写尝试了很多组合,但还是没有:(

Can you guys please help ? 你们能帮忙吗?

I'm using android studio Here is my project structure : 我正在使用android studio这是我的项目结构:

java 1com.tutos.android.content.provider 2AndroidProvider 2ContentProviderExempleActivity java 1com.tutos.android.content.provider 2AndroidProvider 2ContentProviderExempleActivity

Thanks in advance ! 提前致谢 ! ^^ ^^

There is a small correction in the code shared by you- 您共享的代码中有一个小更正-

The declaration below 下面的声明

public static final Uri CONTENT_URI =   Uri.parse("content://com.tutos.android.content.provider.androidprovider");

should be changed to 应该更改为

public static final Uri CONTENT_URI = Uri.parse("content://com.tutos.android.content.provider/androidprovider");

This is the actual reason for the exception. 这是出现异常的实际原因。

I have resolved the issue by changing : 我已经通过更改解决了该问题:

//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);
        }

To

            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)"+");";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM