Android 找不到<;的提供程序信息;定制提供商>;

Android 找不到<;的提供程序信息;定制提供商>;,android,cursor,android-contentprovider,Android,Cursor,Android Contentprovider,我已经阅读了关于这个问题的所有内容,但没有超越这个问题 我有一个简单的应用程序,从main活动开始,我的内容提供者在AndroidManifest.xml中正确定义,ContentProvider类似乎是正确的……这已经在运行4.3的nexus i9250、运行4.2.1的Asus记事本以及运行Jelly Bean的VDevices上进行了测试。该应用程序在每个实例中都运行并且不会崩溃,LogCat给我的唯一信息是“在我的一个片段试图查询内容提供商并获取光标时,未能找到de.somename.p

我已经阅读了关于这个问题的所有内容,但没有超越这个问题

我有一个简单的应用程序,从
main活动开始
,我的
内容提供者
AndroidManifest.xml
中正确定义,
ContentProvider
类似乎是正确的……这已经在运行4.3的nexus i9250、运行4.2.1的Asus记事本以及运行Jelly Bean的VDevices上进行了测试。该应用程序在每个实例中都运行并且不会崩溃,
LogCat
给我的唯一信息是
“在我的一个片段试图查询
内容提供商
并获取光标时,未能找到de.somename.provider的提供商信息”
。代码如下:

AndroidManifest.xml

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

HdwFragment.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 selection, 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, selection, 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 selection,
        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, selection, 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_NAME, null, 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);
    }
}
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_CLTYP,
            hvkContentProvider.KEY_NAME,
            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()我省略了,因为它在这里没有什么区别,我会尽快给它一笔赏金。确实需要这样做。

尝试在
android:authorities
中使用完全限定路径,从而替换
de.somename.provider
使用中的
de.somename.provider.hvkContentProvider
,使其变为如下所示

<provider android:authorities="de.somename.provider.hvkContentProvider"
              android:enabled="true"
              android:multiprocess="true"
              android:name=".hvkContentProvider"
              android:exported="true" ></provider>

您可以


上的参考页:

安卓:权限:…以避免 冲突,权限名称应使用Java风格的命名约定 (例如com.example.provider.cartonprovider)。通常,它是 实现提供程序的ContentProvider子类的名称

在您的例子中,
android:authorities
应该具有以下值:
de.somename.provider.hvkContentProvider


安卓:名称:。。。。。。实现内容的类的名称 提供者,ContentProvider的子类。这应该是一个完整的 限定类名称(例如, “com.example.project.TransportationProvider”)。但是作为一个 简而言之,如果名称的第一个字符是句点,则为句点 附加到元素中指定的包名


因此,如果要在
AndroidManifest.xml
manifest
标记中定义
package
,请确保
hvkContentProvider
位于该包中。否则,将
android:name=“.hvkContentProvider”
更改为
android:name=“de.somename.hvk3.hvkContentProvider”
your.package.name.hvkContentProvider

您为我指明了正确的方向……谢谢。您的建议开始带来其他错误,最终导致我解决了内容提供商问题。不过,你确实让我又动了起来……比如说,为什么IDE会警告使用
android:exported=“true”
?当我将其设置为false时,当我选择共享多个文件时,某些应用程序会出现问题。。。
<provider android:authorities="de.somename.provider.hvkContentProvider"
              android:enabled="true"
              android:multiprocess="true"
              android:name=".hvkContentProvider"
              android:exported="true" ></provider>
<provider android:authorities="de.somename.provider"
    android:enabled="true"
    android:multiprocess="true"
    android:name=".hvkContentProvider"
    android:exported="true" ></provider>