无法获得内容提供者

问题描述:

我刚刚接触Android并通过书籍学习它。请帮助我发现我的小练习计划中可能出现的错误。我可以成功创建数据库,但是我无法使用我的查询函数浏览SQLite数据库的结果,因为有一个异常“无法找到com.latrobe.database的提供程序信息”。无法获得内容提供者

Exception:06-10 01:13:55.510 25546-25546/com.latrobe.database E/ActivityThread: Failed to find provider info for com.latrobe.database 
06-10 01:13:55.962 25546-25655/com.latrobe.database E/Surface: getSlotFromBufferLocked: unknown buffer: 0x7f2949cda5c0 
06-10 01:14:00.401 25546-25546/com.latrobe.database E/ActivityThread: Failed to find provider info for com.latrobe.database 

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.latrobe.database"> 

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

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

package com.latrobe.database; 

import android.content.Context; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteOpenHelper; 
import android.widget.Toast; 

/** 
* Created by hexinhao on 16/5/30. 
*/ 
public class MyDatabaseHelper extends SQLiteOpenHelper { 
    public static final String CREATE_BOOK = "create table book (" 
      + "id integer primary key autoincrement, " 
      + "author text, " 
      + "price real, " 
      + "pages integer, " 
      + "name text)"; 
    public static final String CREATE_CATEGORY = "create table Category (" + "id integer primary key autoincrement, " 
      + "category_name text, " 
      + "category_code integer)"; 

    private Context mContext; 

    public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { 
     super(context, name, factory, version); 
     mContext = context; 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.execSQL(CREATE_BOOK); 
     db.execSQL(CREATE_CATEGORY); 
     Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     db.execSQL("drop table if exists Book"); 
     db.execSQL("drop table if exists Category"); 
     onCreate(db); 
    } 
} 

package com.latrobe.database; 

import android.content.ContentProvider; 
import android.content.ContentValues; 
import android.content.UriMatcher; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.net.Uri; 
import android.support.annotation.Nullable; 

public class DatabaseProvider extends ContentProvider { 
    public static final int BOOK_DIR = 0; 
    public static final int BOOK_ITEM = 1; 
    public static final int CATEGORY_DIR = 2; 
    public static final int CATEGORY_ITEM = 3; 
    public static final String AUTHORITY = "com.latrobe.database"; 
    private static UriMatcher uriMatcher; 
    private MyDatabaseHelper dbHelper; 

    static { 
     uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 
     uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR); 
     uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM); 
     uriMatcher.addURI(AUTHORITY, "category", CATEGORY_DIR); 
     uriMatcher.addURI(AUTHORITY, "category/#", CATEGORY_ITEM); 
    } 


    @Override 
    public boolean onCreate() { 
     MyDatabaseHelper dbHelper = new MyDatabaseHelper(getContext(),"BookStore.db",null,2); 
     return true; 
    } 

    @Nullable 
    @Override 
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 
     SQLiteDatabase db = dbHelper.getReadableDatabase(); 
     Cursor cursor = null; 
     switch (uriMatcher.match(uri)){ 
      case BOOK_DIR: 
       cursor = db.query("Book",null, null, null, null, null, null); 
       break; 
      case BOOK_ITEM: 
       String bookId = uri.getPathSegments().get(1); 
       cursor = db.query("Book",null,"id=?",new String[]{bookId},null,null,null); 
       break; 
      case CATEGORY_DIR: 
       cursor = db.query("Category",null,null,null,null,null,null,null); 
       break; 
      case CATEGORY_ITEM: 
       String categoryId = uri.getPathSegments().get(1); 
       cursor = db.query("Category",null,"id=?",new String[]{categoryId},null,null,null); 
       break; 
      default: 
       break; 

     } 


     return cursor; 
    } 

    @Nullable 
    @Override 
    public String getType(Uri uri) { 
     switch (uriMatcher.match(uri)) { 
      case BOOK_DIR: 
       return "vnd.android.cursor.dir/vnd.com.latrobe.database.book"; 
      case BOOK_ITEM: 
       return "vnd.android.cursor.dir/vnd.com.latrobe.database.book"; 
      case CATEGORY_DIR: 
       return "vnd.android.cursor.dir/vnd.com.latrobe.database.Category"; 
      case CATEGORY_ITEM: 
       return "vnd.android.cursor.dir/vnd.com.latrobe.database.Category"; 
     } 


     return null; 
    } 

    @Nullable 
    @Override 
    public Uri insert(Uri uri, ContentValues values) { 
     SQLiteDatabase db = dbHelper.getWritableDatabase(); 
     Uri uriReturn = null; 
     switch (uriMatcher.match(uri)){ 
      case BOOK_DIR: 
       break; 
      case BOOK_ITEM: 
       long newBookId = db.insert("Book",null,values); 
       uriReturn = Uri.parse("Content://"+AUTHORITY+"/book/"+newBookId); 
       break; 
      case CATEGORY_DIR: 
       break; 
      case CATEGORY_ITEM: 
       long newCategoryId = db.insert("Category",null,values); 
       uriReturn = Uri.parse("Content://"+AUTHORITY+"/category/"+newCategoryId); 
       break; 
      default: 
       break; 
     } 




     return uriReturn; 
    } 

    @Override 
    public int delete(Uri uri, String selection, String[] selectionArgs) { 
// 删除数据 
     SQLiteDatabase db = dbHelper.getWritableDatabase(); 
     int deletedRows = 0; 
     switch (uriMatcher.match(uri)) { 
      case BOOK_DIR: 
       deletedRows = db.delete("Book", selection, selectionArgs); 
       break; 
      case BOOK_ITEM: 
       String bookId = uri.getPathSegments().get(1); 
       deletedRows = db.delete("Book", "id = ?", new String[] { bookId }); break; 
      case CATEGORY_DIR: 
       deletedRows = db.delete("Category", selection, selectionArgs); break; 
      case CATEGORY_ITEM: 
       String categoryId = uri.getPathSegments().get(1); 
       deletedRows = db.delete("Category", "id = ?", new String[] 
         { categoryId }); 
       break; 
      default: 
       break; 
     } 
     return deletedRows; 
    } 




    @Override 
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 
     SQLiteDatabase db = dbHelper.getWritableDatabase(); 
     int updatedRows = 0; 
     switch (uriMatcher.match(uri)){ 
      case BOOK_DIR: 
       updatedRows = db.update("Book",values,null,null); 
       break; 
      case BOOK_ITEM: 
       String bookId = uri.getPathSegments().get(1); 
       updatedRows=db.update("Book",values,"id=?",new String[]{bookId}); 
       break; 
      case CATEGORY_DIR: 
       updatedRows = db.update("Category",values,null,null); 
       break; 
      case CATEGORY_ITEM: 
       String categoryId = uri.getPathSegments().get(1); 
       updatedRows=db.update("Category",values,"id=?",new String[]{categoryId}); 
       break; 
      default: 
       break; 
     } 



     return updatedRows; 
    } 


} 

package com.latrobe.database; 

import android.app.Activity; 
import android.content.ContentValues; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.net.Uri; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 

public class MainActivity extends Activity { 
    private MyDatabaseHelper dbHelper; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 2); 
     Button createDatabase = (Button) findViewById(R.id.create_database); 
     createDatabase.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       dbHelper.getWritableDatabase(); 
      } 
     }); 
     Button addData = (Button) findViewById(R.id.add_data); 
     addData.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       SQLiteDatabase db = dbHelper.getWritableDatabase(); 
       ContentValues values = new ContentValues(); 
       values.put("name", "The Da Vinci Code"); 
       values.put("author", "Dan Brown"); 
       values.put("pages", 454); 
       values.put("price", 16.96); 
       db.insert("Book", null, values); 
       values.clear(); 
       values.put("name", "The Lost Symbol"); 
       values.put("author", "Dan Brown"); 
       values.put("pages", 510); 
       values.put("price", 19.95); 
       db.insert("Book", null, values); 
      } 
     }); 
     Button updateData = (Button) findViewById(R.id.update_data); 
     updateData.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       SQLiteDatabase db = dbHelper.getWritableDatabase(); 
       ContentValues values = new ContentValues(); 
       values.put("price", 10.99); 
       db.update("Book", values, "name = ?", 
         new String[] { "The Da Vinci Code" }); 
      } 
     }); 
     Button deleteButton = (Button) findViewById(R.id.delete_data); 
     deleteButton.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       SQLiteDatabase db = dbHelper.getWritableDatabase(); 
       db.delete("Book", "pages > ?", new String[] { "500" }); 
      } 
     }); 
     Button queryButton = (Button) findViewById(R.id.query_data); 
     queryButton.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Uri uri = Uri.parse("content://com.latrobe.database/book"); 
       Cursor cursor = getContentResolver().query(uri, null, null, 
         null, null); 
       if (cursor != null) { 
        while (cursor.moveToNext()) { 
         String name = cursor.getString(cursor 
           .getColumnIndex("name")); 
         String author = cursor.getString(cursor 
           .getColumnIndex("author")); 
         int pages = cursor.getInt(cursor 
           .getColumnIndex("pages")); 
         double price = cursor.getDouble(cursor 
           .getColumnIndex("price")); 
         Log.d("MainActivity", "book name is " + name); 
         Log.d("MainActivity", "book author is " + author); 
         Log.d("MainActivity", "book pages is " + pages); 
         Log.d("MainActivity", "book price is " + price); 
        } 
        cursor.close(); 
       } 
      } 
     }); 
     Button replaceData = (Button) findViewById(R.id.replace_data); 
     replaceData.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       SQLiteDatabase db = dbHelper.getWritableDatabase(); 
       db.beginTransaction(); 
       try { 
        db.delete("Book", null, null); 
        // if (true) { 
        // throw new NullPointerException(); 
        // } 
        ContentValues values = new ContentValues(); 
        values.put("name", "Game of Thrones"); 
        values.put("author", "George Martin"); 
        values.put("pages", 720); 
        values.put("price", 20.85); 
        db.insert("Book", null, values); 
        db.setTransactionSuccessful(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } finally { 
        db.endTransaction(); 
       } 
      } 
     }); 
    } 

} 

您在清单和亲*vider不匹配。

此外您的活动似乎直接访问数据库,而不是与提供者交谈。这是正确的代码吗?

+0

是的,我忘了粘贴另一个程序的代码,它要求内容提供者访问其他应用程序的数据库。但是现在,我解决了这个问题,我没有清楚地理解提供程序中名称和权限的含义,但是我只是将其修改为正确的,所以现在可以在自己的程序中使用contentProvider,但也可以通过其他程序访问。感谢您的回复。 –