ContentProvider openFile - 如何删除文件

时间:2014-05-27 14:34:55

标签: android android-contentprovider

我实现了自己的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 ????????????
    }
}

1 个答案:

答案 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;
}