我有一个简单的应用程序从MainActivity开始,我的Content Provider在AndroidManifest.xml中正确定义,ContentProvider类看起来很好……这已经在运行4.3的nexus i9250和运行4.2.1的Asus Memo Pad上进行了测试当VDevices运行Jelly Bean时.应用程序在每个实例中运行并且不会崩溃,LogCat给我的唯一一件事就是“找不到de.somename.provider的提供程序信息”,其中我的一个片段试图查询Content Provider并获取游标.这里的代码:
AndroidManifest.xml中
<?xml version="1.0" encoding="utf-8"?>
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="de.somename.hvk3.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter></activity> <activity android:name="de.somename.hvk3.UserSettingActivity" android:label="@string/settings" ></activity> <provider android:authorities="de.somename.provider" android:enabled="true" android:multiprocess="true" android:name=".hvkContentProvider" android:exported="true" ></provider> </application>
hvkContentProvider.java
public class hvkContentProvider extends ContentProvider { private static final String DATABASE_NAME = "hvkDB"; private static final int DATABASE_VERSION = 1; public static final String Authority = "de.somename.provider"; public static final String ElementPath = "/hv_kontakte"; public static final Uri CONTENT_URI = Uri.parse("content://" + Authority + ElementPath); private static final int ALLROWS = 1; private static final int SINGLE_ROW = 2; private static final UriMatcher suriMatcher = new UriMatcher(UriMatcher.NO_MATCH); static{ suriMatcher.addURI("de.somename.provider",ElementPath,ALLROWS); suriMatcher.addURI("de.somename.provider",ElementPath + "/#",SINGLE_ROW); } public static final String KEY_ID = "_id"; public static final String KEY_TYPE = "type"; public static final String KEY_CLTYP = "cltyp"; public static final String KEY_MDT = "mdt"; public static final String KEY_OBJ = "obj"; public static final String KEY_VTR = "vtr"; public static final String KEY_FKZ = "fkz"; public static final String KEY_NAME = "name"; public static final String KEY_VNAME = "vname"; public static final String KEY_TEL = "tel"; public static final String KEY_FAX = "fax"; public static final String KEY_MOBIL = "mobil"; public static final String KEY_EMAIL = "email"; private MysqLiteOpenHelper myOpenHelper; @Override public boolean onCreate() { myOpenHelper = new MysqLiteOpenHelper(getContext(),DATABASE_NAME,null,DATABASE_VERSION); return true; } @Override public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder) { sqliteDatabase db = myOpenHelper.getReadableDatabase(); String groupBy = null; String having = null; sqliteQueryBuilder queryBuilder = new sqliteQueryBuilder(); queryBuilder.setTables(MysqLiteOpenHelper.DATABASE_TABLE); switch(suriMatcher.match(uri)){ case SINGLE_ROW: String rowID = uri.getPathSegments().get(1); queryBuilder.appendWhere(KEY_ID + "=" + rowID); default: break; } Cursor cursor = queryBuilder.query(db,projection,selection,selectionArgs,groupBy,having,sortOrder); return cursor; } @Override public int delete(Uri uri,String[] selectionArgs) { sqliteDatabase db = myOpenHelper.getWritableDatabase(); switch(suriMatcher.match(uri)){ case SINGLE_ROW: String rowID = uri.getPathSegments().get(1); selection = KEY_ID + "=" + rowID + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""); default: break; } //To return the number of deleted items you must specify a where clause. To delete all rows and return a value pass in "1" if (selection == null) selection = "1"; return db.delete(MysqLiteOpenHelper.DATABASE_TABLE,selectionArgs); } @Override public Uri insert(Uri uri,ContentValues values) { sqliteDatabase db = myOpenHelper.getWritableDatabase(); String nullColumnHack = null; long id = db.insert(MysqLiteOpenHelper.DATABASE_TABLE,nullColumnHack,values); if(id > -1){ Uri insertedId = ContentUris.withAppendedId(CONTENT_URI,id); getContext().getContentResolver().notifyChange(insertedId,null); return insertedId; } else return null; } @Override public int update(Uri uri,ContentValues values,String[] selectionArgs) { sqliteDatabase db = myOpenHelper.getWritableDatabase(); switch(suriMatcher.match(uri)){ case SINGLE_ROW: String rowID = uri.getPathSegments().get(1); selection = KEY_ID + "=" + rowID + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""); default: break; } return db.update(MysqLiteOpenHelper.DATABASE_TABLE,values,selectionArgs); } @Override public String getType(Uri uri) { switch(suriMatcher.match(uri)){ case ALLROWS: return "vnd.android.cursor.dir/vnd.somename.contacts"; case SINGLE_ROW: return "vnd.android.cursor.item/vnd.somename.contacts"; default: throw new IllegalArgumentException("Unsupported URI: " + uri); } } @Override public ParcelFileDescriptor openFile(Uri uri,String mode) throws FileNotFoundException { //Find the row ID and use it as a filename String rowID = uri.getPathSegments().get(1); //Create a file object in the applications external files directory String picsDir = Environment.DIRECTORY_PICTURES; File file = new File(getContext().getExternalFilesDir(picsDir),rowID); if(!file.exists()) { try{ file.createNewFile(); } catch (IOException e) { //Log.d(TAG,"File creation Failed: " + e.getMessage()); } } //Translate the mode parameter to the corresponding Parcel File Descriptor open mode int fileMode = 0; if(mode.contains("w")) fileMode |= ParcelFileDescriptor.MODE_WRITE_ONLY; if(mode.contains("r")) fileMode |= ParcelFileDescriptor.MODE_READ_ONLY; if(mode.contains("+")) fileMode |= ParcelFileDescriptor.MODE_APPEND; return ParcelFileDescriptor.open(file,fileMode); } private class MysqLiteOpenHelper extends sqliteOpenHelper { //used to be static public static final String DATABASE_TABLE = "hv_kontakte"; private static final String DATABASE_CREATE = "CREATE TABLE " + DATABASE_TABLE + "(" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + KEY_TYPE + " TEXT," + KEY_CLTYP + " TEXT," + KEY_MDT + " INTEGER," + KEY_OBJ + " INTEGER," + KEY_VTR + " INTEGER," + KEY_FKZ + " INTEGER," + KEY_NAME + " TEXT," + KEY_VNAME + " TEXT," + KEY_TEL + " TEXT," + KEY_FAX + " TEXT," + KEY_MOBIL + " TEXT," + KEY_EMAIL + " TEXT)"; public MysqLiteOpenHelper(Context context,String name,sqliteDatabase.CursorFactory factory,int version){ super(context,DATABASE_VERSION); } @Override public void onCreate(sqliteDatabase database) { database.execsql(DATABASE_CREATE); hvkContentProvider.this.insertSomeContacts(); } @Override public void onUpgrade(sqliteDatabase database,int oldVersion,int newVersion) { database.execsql("DROP TABLE IF EXISTS" + DATABASE_TABLE); onCreate(database); } }
}
HdwFragment.java
public class HdwFragment extends Fragment{ private SimpleCursorAdapter hdwDataAdapter; private ListView listview; public static final String ARG_SECTION_NUMBER = "section_number"; private static final String TAG = "HdwFragment"; public HdwFragment(){} @Override public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){ Context context = getActivity(); View rootView = inflater.inflate(R.layout.fragment_all,container,false); TextView dummyTextView = (TextView) rootView.findViewById(R.id.section_label); dummyTextView.setText("Dienstleister"); //android.support.v4.app.LoaderManager loaderManager = getLoaderManager(); Log.i(TAG,"Before getContentResolver"); ContentResolver cr = context.getContentResolver(); Log.i(TAG,"Before result_columns"); String[] result_columns = new String[] { hvkContentProvider.KEY_ID,hvkContentProvider.KEY_TYPE,hvkContentProvider.KEY_CLTYP,hvkContentProvider.KEY_NAME,hvkContentProvider.KEY_VNAME }; Log.i(TAG,"Before where,whereArgs and order"); String where = null; String whereArgs[] = null; String order = null; Log.i(TAG,"Before resultCursor action"); Log.i(TAG,"hvkContentProvider URI: " + hvkContentProvider.CONTENT_URI); Cursor resultCursor = cr.query(hvkContentProvider.CONTENT_URI,result_columns,where,whereArgs,order); Log.i(TAG,"resultCursor = " + resultCursor); Log.i(TAG,"Before fromColumns"); String[] fromColumns = new String[]{ hvkContentProvider.KEY_TYPE,hvkContentProvider.KEY_VNAME }; Log.i(TAG,"Before toViews"); int[] toViews = new int[]{ R.id.contactType,R.id.contactCltype,R.id.contactName,R.id.contactVname }; Log.i(TAG,"Before Adapter"); hdwDataAdapter = new SimpleCursorAdapter(getActivity(),R.layout.object_list_item,resultCursor,fromColumns,toViews,0); listview = (ListView) rootView.findViewById(R.id.list_all); listview.setAdapter(hdwDataAdapter); Log.i(TAG,"Before return Layout"); return (LinearLayout) rootView; } @Override public void onActivityCreated(Bundle savedInstanceState){ super.onActivityCreated(savedInstanceState); //Bundle args = null; //loaderManager.initLoader(LOADER_ID,args,loaderCallback); }
}
方法:insertSomeFunctions()我已经遗漏了,因为它在这里没有什么区别,会尽快给这个奖励.真的需要完成这件事.
解决方法
<provider android:authorities="de.somename.provider" android:enabled="true" android:multiprocess="true" android:name=".hvkContentProvider" android:exported="true" ></provider>
android:authorities: ……To avoid
conflicts,authority names should use a Java-style naming convention
(such as com.example.provider.cartoonprovider). Typically,it’s the
name of the ContentProvider subclass that implements the provider.
在您的情况下,android:authority应该具有值:de.somename.provider.hvkContentProvider.
android:name:…… The name of the class that implements the content
provider,a subclass of ContentProvider. This should be a fully
qualified class name (such as,
“com.example.project.TransportationProvider”). However,as a
shorthand,if the first character of the name is a period,it is
appended to the package name specified in the element.
因此,如果要在AndroidManifest.xml的清单标记中定义包,请确保hvkContentProvider在该包中.否则,将android:name =“.hvkContentProvider”更改为android:name =“de.somename.hvk3.hvkContentProvider”或your.package.name.hvkContentProvider