我实现了自己的ContentProvider并重载了openFile方法。这里是一个存储由姓氏和姓氏给出的一组人的例子。对于每个人,您可以存储图像/照片。
public class PersonTable {
public static final String TABLE_NAME = "persons";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_NAME = "name";
public static final String COLUMN_FIRSTNAME = "first_name";
private static final String SQL_CREATE = "CREATE TABLE IF NOT EXISTS "
+ TABLE_NAME + "( " + COLUMN_ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_NAME
+ " TEXT NOT NULL, " + COLUMN_FIRSTNAME + " COLUMN_FIRSTNAME)";
public static void onCreate(SQLiteDatabase database) {
database.execSQL(SQL_CREATE);
}
public static void onUpgrade(SQLiteDatabase database, int oldVersion,
int newVersion) {
database.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(database);
}
}
public class PersonDatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "person.db";
public static final int DATABASE_VERSION = 1;
public PersonDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
PersonTable.onCreate(db);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
PersonTable.onUpgrade(db, oldVersion, newVersion);
}
}
public class PersonContentProvider extends ContentProvider {
private static final int URI_TYPE_PERSONS = 1;
private static final int URI_TYPE_SINGLE_PERSON = 2;
private static final String AUTHORITY = "eu.level12.contentprovider";
private static final String BASE_PATH = "person";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/" + BASE_PATH);
private static final UriMatcher uriMatcher = new UriMatcher(
UriMatcher.NO_MATCH);
static {
uriMatcher.addURI(AUTHORITY, BASE_PATH, URI_TYPE_PERSONS);
uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", URI_TYPE_SINGLE_PERSON);
}
private PersonDatabaseHelper databaseHelper;
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int deletedRows = 0;
int uriType = uriMatcher.match(uri);
switch (uriType) {
case URI_TYPE_PERSONS:
// ToDo: delete all persons at once
break;
case URI_TYPE_SINGLE_PERSON:
String locationID = uri.getLastPathSegment();
SQLiteDatabase database = databaseHelper.getWritableDatabase();
final String where = PersonTable.COLUMN_ID + " = " + locationID;
deletedRows = database.delete(PersonTable.TABLE_NAME, where, null);
if (deletedRows > 0) {
deleteFile(uri);
getContext().getContentResolver().notifyChange(uri, null);
}
break;
}
return deletedRows;
}
@Override
public String getType(Uri arg0) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
int uriType = uriMatcher.match(uri);
Uri result = null;
switch (uriType) {
case URI_TYPE_PERSONS:
SQLiteDatabase database = databaseHelper.getWritableDatabase();
long id = database.insert(PersonTable.TABLE_NAME, null, values);
result = ContentUris.withAppendedId(uri, id);
getContext().getContentResolver().notifyChange(result, null);
break;
}
return result;
}
@Override
public boolean onCreate() {
databaseHelper = new PersonDatabaseHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
Cursor result = null;
int uriType = uriMatcher.match(uri);
switch (uriType) {
case URI_TYPE_PERSONS:
// ToDo: query all persons at once
break;
case URI_TYPE_SINGLE_PERSON:
String id = uri.getLastPathSegment();
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(PersonTable.TABLE_NAME);
String where = PersonTable.COLUMN_ID + " = " + id;
builder.appendWhere(where);
SQLiteDatabase database = databaseHelper.getWritableDatabase();
result = builder.query(database, projection, selection,
selectionArgs, null, null, sortOrder);
break;
}
if (result != null)
result.setNotificationUri(getContext().getContentResolver(), uri);
return result;
}
@Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
// TODO Auto-generated method stub
return 0;
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
ContextWrapper cw = new ContextWrapper(getContext());
// path to /data/data/yourapp/app_data/dir
File directory = cw.getDir(BASE_PATH, Context.MODE_MULTI_PROCESS);
directory.mkdirs();
long id = ContentUris.parseId(uri);
File path = new File(directory, String.valueOf(id));
int imode = 0;
if (mode.contains("w")) {
imode |= ParcelFileDescriptor.MODE_WRITE_ONLY;
if (!path.exists()) {
try {
path.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
if (mode.contains("r"))
imode |= ParcelFileDescriptor.MODE_READ_ONLY;
if (mode.contains("+"))
imode |= ParcelFileDescriptor.MODE_APPEND;
return ParcelFileDescriptor.open(path, imode);
}
private void deleteFile(Uri uri) {
ContextWrapper cw = new ContextWrapper(getContext());
// path to /data/data/yourapp/app_data/dir
File directory = cw.getDir(BASE_PATH, Context.MODE_MULTI_PROCESS);
String id = uri.getLastPathSegment();
File file = new File(directory, id);
if (file.exists())
file.delete();
}
}
现在,在一个Activity中,我创建了一个样本人和一个与该人相关联的图像。稍后,您可以删除此人,包括其图像。但是如何删除图像,而不删除人本身?
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ContentResolver cr = getContentResolver();
// create a sample person
ContentValues values = new ContentValues();
values.put(PersonTable.COLUMN_FIRSTNAME, "Max");
values.put(PersonTable.COLUMN_NAME, "Moritz");
// insert the sample person into DB
Uri uri = cr.insert(PersonContentProvider.CONTENT_URI, values);
// add an image for that person (image is stored on file system)
try {
OutputStream stream = cr.openOutputStream(uri);
Bitmap image = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
image.compress(Bitmap.CompressFormat.PNG, 100, stream);
stream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// Option 1: delete person --> will also delete image on file system
// (see PersonContentProvider.delete)
cr.delete(uri, null, null);
// Option 2: delete only the image, without deleting the person
// How ????????????
}
}
答案 0 :(得分:0)
我在所有ContentProvider实现中使用静态方法。 Uri是应删除的条目/行(例如:/ location / 1),base-path是ContentProvider本身之一。我在ContentProvider.delete(...)中调用该方法。
protected static boolean deleteFile(Uri uri, String basePath,
Context context, boolean notifyChange) {
if (uri == null || context == null)
return false;
ContextWrapper cw = new ContextWrapper(context);
// path to /data/data/yourapp/app_data/dir
File directory = cw.getDir(basePath, Context.MODE_MULTI_PROCESS);
String id = uri.getLastPathSegment();
File file = new File(directory, id);
if (file.exists()) {
boolean result = file.delete();
if (notifyChange && result)
context.getContentResolver().notifyChange(uri, null);
if (result)
Log.d(TAG, "Deleted file for " + uri.toString());
return result;
}
return false;
}