android基础巩固之内容提供者(Content Provider)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/syusikoku/article/details/86604871

内容提供者的基本使用

本文的场景MusicServer提供数据库及内容提供者给其它应用使用,及观察数据库变化,好刷新自身应用的列表,ALiCocoMusicPlayer为第三方应用,其作用是为了使用ContentResolover对MusicServer中数据库中的表进行操作。

MusicServer

db,dao,测试类代码

db

public class MusicDBHelper extends BaseSqliteDbHelper {
    public MusicDBHelper(Context context) {
        super(context, MusicAppConst.KEYSETS.MUSIC_DB_NAME, MusicAppConst.KEYSETS
                .MUSIC_DB_VERSION);
    }

    @Override
    protected String getDbCreateSql() {
        StringBuilder sqlSb = new StringBuilder();

        sqlSb.append("create table IF NOT EXISTS ").append(MusicTabinfo.TABLE_NAME).append(" (");
        sqlSb.append(MusicTabinfo.COLOUMN_NAME_ID).append(" integer primary key autoincrement , ");
        sqlSb.append(MusicTabinfo.COLOUMN_NAME_MUSIC_NAME).append(" varchar(20) , ");
        sqlSb.append(MusicTabinfo.COLOUMN_NAME_AUTHOR).append(" varchar(20) , ");
        sqlSb.append(MusicTabinfo.COLOUMN_NAME_PUBLISH_NAME).append(" varchar(30) ,");
        sqlSb.append(MusicTabinfo.COLOUMN_NAME_DESC).append(" text");
        sqlSb.append(" )");

        return sqlSb.toString();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

dao

public class MusicDBDAO extends BaseDAO<MusicTabinfo> {
    private static MusicDBDAO INSTANCE = null;

    private MusicDBDAO() {
        mSqliteDbHelper = new MusicDBHelper(BaseApp.getAppInstance());
    }

    public static MusicDBDAO getInstance() {
        if (INSTANCE == null) {
            synchronized (MusicDBDAO.class) {
                if (INSTANCE == null) {
                    INSTANCE = new MusicDBDAO();
                }
            }
        }
        return INSTANCE;
    }

    @Override
    public int add(MusicTabinfo musicTabinfo) {
        LoggerUtils.loge("add");
        if (musicTabinfo == null)
            return -1;

        sqlBuilder.setLength(0);
        sqlBuilder.append("insert into ").append(MusicTabinfo.TABLE_NAME).append(" ( ");
        sqlBuilder.append(MusicTabinfo.COLOUMN_NAME_MUSIC_NAME).append(" , ");
        sqlBuilder.append(MusicTabinfo.COLOUMN_NAME_AUTHOR).append(" , ");
        sqlBuilder.append(MusicTabinfo.COLOUMN_NAME_PUBLISH_NAME).append(" , ");
        sqlBuilder.append(MusicTabinfo.COLOUMN_NAME_DESC).append(" ) values ( ");
        sqlBuilder.append("?,?,?,? ) ");

        printLog();
        try {
            getWriteDb().execSQL(sqlBuilder.toString(), new String[]{
                    musicTabinfo.getMusicName(), musicTabinfo.getAuthor(), musicTabinfo
                    .getPublishTime(), musicTabinfo.getDesc()});
            return 0;
        } catch (SQLException e) {
            e.printStackTrace();
            return -1;
        }
    }


    @Override
    public int addAll(List<MusicTabinfo> list) {
        LoggerUtils.loge("addAll");
        int errorNum = 0;
        for (MusicTabinfo tabinfo : list) {
            try {
                add(tabinfo);
            } catch (Exception e) {
                e.printStackTrace();
                errorNum++;
            }
        }
        // 有出错则返回-1
        return (errorNum == 0 ? 0 : -1);
    }

    @Override
    public int delete(MusicTabinfo musicTabinfo) {
        LoggerUtils.loge("delete");
        sqlBuilder.setLength(0);

        sqlBuilder.append("delete from ").append(MusicTabinfo.TABLE_NAME);
        sqlBuilder.append(" where ").append(MusicTabinfo.COLOUMN_NAME_MUSIC_NAME).append(" = ? ");
        sqlBuilder.append(" & ").append(MusicTabinfo.COLOUMN_NAME_ID).append(" = ? ");
        printLog();

        try {
            getWriteDb().execSQL(sqlBuilder.toString(), new String[]{musicTabinfo.getMusicName(),
                    musicTabinfo.getMusicId() + ""});
            return 0;
        } catch (SQLException e) {
            e.printStackTrace();
            return -1;
        }
    }

    @Override
    public int deleteById(int id) {
        LoggerUtils.loge("deleteById");
        sqlBuilder.setLength(0);

        sqlBuilder.append("delete from ").append(MusicTabinfo.TABLE_NAME);
        sqlBuilder.append(" where ").append(MusicTabinfo.COLOUMN_NAME_ID).append(" = ? ");
        printLog();

        try {
            getWriteDb().execSQL(sqlBuilder.toString(), new String[]{id + ""});
            return 0;
        } catch (SQLException e) {
            e.printStackTrace();
            return -1;
        }
    }


    @Override
    public int update(MusicTabinfo musicTabinfo) {
        LoggerUtils.loge("update");
        if (musicTabinfo == null)
            return -1;
        sqlBuilder.setLength(0);


        // 先查询再更新避免没有设置的数据被清除掉了
        sqlBuilder.append("update ").append(MusicTabinfo.TABLE_NAME);
        sqlBuilder.append(" set ");
        sqlBuilder.append(MusicTabinfo.COLOUMN_NAME_AUTHOR).append(" = ? , ");
        sqlBuilder.append(MusicTabinfo.COLOUMN_NAME_PUBLISH_NAME).append(" = ? ,");
        sqlBuilder.append(MusicTabinfo.COLOUMN_NAME_DESC).append(" = ? ");
        sqlBuilder.append(" where ").append(MusicTabinfo.COLOUMN_NAME_MUSIC_NAME).append(" = ? ");

        try {
            printLog();
            getWriteDb().execSQL(sqlBuilder.toString(), new String[]{musicTabinfo.getAuthor(),
                    musicTabinfo.getPublishTime(), musicTabinfo.getDesc(), musicTabinfo
                    .getMusicName()});
            return 0;
        } catch (SQLException e) {
            e.printStackTrace();
            return -1;
        }
    }

    @Override
    public int updateById(int id, Map<String, Object> params) {
        LoggerUtils.loge("updateById");
        if (id == -1 || id == 0 || params == null || params.size() == 0)
            return -1;

        // 先查询在数据库中是否存在
        MusicTabinfo dbInfo = queryById(id);

        Set<String> keySet = params.keySet();
        if (dbInfo != null) {
            // 存在就更新
            fillTabData(params, dbInfo, keySet);

            sqlBuilder.setLength(0);
            sqlBuilder.append("update ").append(MusicTabinfo.TABLE_NAME);
            sqlBuilder.append(" set ");
            sqlBuilder.append(MusicTabinfo.COLOUMN_NAME_AUTHOR).append(" = ? , ");
            sqlBuilder.append(MusicTabinfo.COLOUMN_NAME_PUBLISH_NAME).append(" = ? , ");
            sqlBuilder.append(MusicTabinfo.COLOUMN_NAME_DESC).append(" = ? , ");
            sqlBuilder.append(MusicTabinfo.COLOUMN_NAME_MUSIC_NAME).append(" = ? ");
            sqlBuilder.append(" where ").append(MusicTabinfo.COLOUMN_NAME_ID).append(" = ?");
            printLog();
            try {
                getWriteDb().execSQL(sqlBuilder.toString(), new String[]{dbInfo.getAuthor(),
                        dbInfo.getPublishTime(), dbInfo.getDesc(), dbInfo.getMusicName(),
                        id + ""});
                return 0;
            } catch (SQLException e) {
                e.printStackTrace();
                return -1;
            }
        } else {
            // 不存在就创建,并插入数据库
            dbInfo = new MusicTabinfo();
            fillTabData(params, dbInfo, keySet);
            return add(dbInfo);
        }
    }

    private void fillTabData(Map<String, Object> params, MusicTabinfo dbInfo, Set<String> keySet) {
        // 数据库中不存在就添加到数据库中
        if (keySet.contains(MusicTabinfo.COLOUMN_NAME_AUTHOR)) {
            dbInfo.setAuthor((String) params.get(MusicTabinfo.COLOUMN_NAME_AUTHOR));
        }

        if (keySet.contains(MusicTabinfo.COLOUMN_NAME_PUBLISH_NAME)) {
            dbInfo.setPublishTime((String) params.get(MusicTabinfo.COLOUMN_NAME_PUBLISH_NAME));
        }

        if (keySet.contains(MusicTabinfo.COLOUMN_NAME_DESC)) {
            dbInfo.setDesc((String) params.get(MusicTabinfo.COLOUMN_NAME_DESC));
        }

        if (keySet.contains(MusicTabinfo.COLOUMN_NAME_MUSIC_NAME)) {
            dbInfo.setMusicName((String) params.get(MusicTabinfo.COLOUMN_NAME_MUSIC_NAME));
        }
    }


    @Override
    public MusicTabinfo queryById(int id) {
        LoggerUtils.loge("queryById");
        MusicTabinfo tabinfo = new MusicTabinfo();
        sqlBuilder.setLength(0);

        sqlBuilder.append("select * from ").append(MusicTabinfo.TABLE_NAME);
        sqlBuilder.append(" where ").append(MusicTabinfo.COLOUMN_NAME_ID).append(" = ?");

        Cursor cursor = null;
        try {
            cursor = getReadDb().rawQuery(sqlBuilder.toString(), new String[]{id + ""});
            cursor.moveToFirst();
            int _id = cursor.getInt(cursor.getColumnIndex(MusicTabinfo.COLOUMN_NAME_ID));
            String _name = cursor.getString(cursor.getColumnIndex(MusicTabinfo
                    .COLOUMN_NAME_MUSIC_NAME));
            String _author = cursor.getString(cursor.getColumnIndex(MusicTabinfo
                    .COLOUMN_NAME_AUTHOR));
            String _publish_time = cursor.getString(cursor.getColumnIndex(MusicTabinfo
                    .COLOUMN_NAME_PUBLISH_NAME));
            String _desc = cursor.getString(cursor.getColumnIndex(MusicTabinfo.COLOUMN_NAME_DESC));
            tabinfo = new MusicTabinfo(_id, _name, _publish_time, _author, _desc);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null)
                cursor.close();
        }

        return tabinfo;
    }

    @Override
    public List<MusicTabinfo> queryAll() {
        LoggerUtils.loge("queryAll");
        Cursor cursor = getReadDb().rawQuery("select * from " + MusicTabinfo.TABLE_NAME, null);
        List<MusicTabinfo> list = new ArrayList<>();
        MusicTabinfo tabinfo = null;
        while (cursor.moveToNext()) {
            int _id = cursor.getInt(cursor.getColumnIndex(MusicTabinfo.COLOUMN_NAME_ID));
            String _name = cursor.getString(cursor.getColumnIndex(MusicTabinfo
                    .COLOUMN_NAME_MUSIC_NAME));
            String _author = cursor.getString(cursor.getColumnIndex(MusicTabinfo
                    .COLOUMN_NAME_AUTHOR));
            String _publish_time = cursor.getString(cursor.getColumnIndex(MusicTabinfo
                    .COLOUMN_NAME_PUBLISH_NAME));
            String _desc = cursor.getString(cursor.getColumnIndex(MusicTabinfo.COLOUMN_NAME_DESC));
            tabinfo = new MusicTabinfo(_id, _name, _publish_time, _author, _desc);
            list.add(tabinfo);
        }
        cursor.close();
        return list;
    }
}

测试类

@RunWith(AndroidJUnit4.class)
public class MusicDBDAOTest {

    private MusicDBDAO mDbdao;

    @Before
    public void setUp() throws Exception {
        mDbdao = MusicDBDAO.getInstance();
    }

    @Test
    public void add() {
        MusicTabinfo tabinfo = new MusicTabinfo();
        tabinfo.setMusicName("光辉岁月");
        tabinfo.setAuthor("boyone");
        tabinfo.setPublishTime("1983-12-31");
        tabinfo.setDesc("激情,青春,有活力");
        mDbdao.add(tabinfo);
    }

    @Test
    public void addAll() {
        List<MusicTabinfo> list = new ArrayList<>();
        MusicTabinfo tabinfo = new MusicTabinfo();
        tabinfo.setMusicName("光辉岁月");
        tabinfo.setAuthor("boyone");
        tabinfo.setPublishTime("1983-12-31");
        tabinfo.setDesc("激情,青春,有活力");
        list.add(tabinfo);

        tabinfo = new MusicTabinfo();
        tabinfo.setMusicName("追梦赤子心");
        tabinfo.setAuthor("gala");
        tabinfo.setPublishTime("1983-11-31");
        tabinfo.setDesc("奔放,激情");
        list.add(tabinfo);

        tabinfo = new MusicTabinfo();
        tabinfo.setMusicName("海阔天空");
        tabinfo.setAuthor("boyone");
        tabinfo.setPublishTime("1984-12-31");
        tabinfo.setDesc("用心向往");
        list.add(tabinfo);

        tabinfo = new MusicTabinfo();
        tabinfo.setMusicName("the mass");
        tabinfo.setAuthor("era");
        tabinfo.setPublishTime("1986-12-31");
        tabinfo.setDesc("暴力,突破");
        list.add(tabinfo);

        tabinfo = new MusicTabinfo();
        tabinfo.setMusicName("reborn");
        tabinfo.setAuthor("era");
        tabinfo.setPublishTime("1989-12-31");
        tabinfo.setDesc("重生,向往");
        list.add(tabinfo);

        mDbdao.addAll(list);
    }

    @Test
    public void delete() {
    }

    @Test
    public void deleteById() {
        mDbdao.deleteById(3);
    }

    @Test
    public void update() {
        MusicTabinfo tabinfo = new MusicTabinfo();
        tabinfo.setMusicName("光辉岁月2");
        tabinfo.setAuthor("boyone223");
        tabinfo.setPublishTime("1982-11-1");
        mDbdao.update(tabinfo);
    }

    @Test
    public void updateById() {
        Map<String, Object> param = new HashMap<>();
        param.put(MusicTabinfo.COLOUMN_NAME_MUSIC_NAME, "光辉岁月431");
        param.put(MusicTabinfo.COLOUMN_NAME_AUTHOR, "boyone155");
        param.put(MusicTabinfo.COLOUMN_NAME_PUBLISH_NAME, "1980-1-1");
        mDbdao.updateById(4, param);
    }

    @Test
    public void queryById() {
        MusicTabinfo tabinfo = mDbdao.queryById(2);
        LoggerUtils.loge(tabinfo.toString());
    }

    @Test
    public void queryAll() {
        List<MusicTabinfo> list = mDbdao.queryAll();
        if (list != null && list.size() > 0) {
            for (MusicTabinfo tabinfo : list) {
                LoggerUtils.loge(tabinfo.toString());
            }
        }
    }
}

content provider配置及源代码

public class MusicContentProvider extends ContentProvider {
    /**
     * URI匹配器
     */
    private static final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
    private static final int INSERT = 0;
    private static final int DELETE = 1;
    private static final int UPDATE = 2;
    private static final int SELECT = 3;
    private static final int SELECT_ONE = 4;
    private static String tabName = MusicTabinfo.TABLE_NAME;

    static {
        /**
         * 添加匹配规则
         */
        matcher.addURI(MusicAppConst.AUTHORIES_SERVER_CP, tabName + "/insert", INSERT);
        matcher.addURI(MusicAppConst.AUTHORIES_SERVER_CP, tabName + "/delete", DELETE);
        matcher.addURI(MusicAppConst.AUTHORIES_SERVER_CP, tabName + "/update", UPDATE);
        matcher.addURI(MusicAppConst.AUTHORIES_SERVER_CP, tabName + "/select", SELECT);
        // 允许携带参数:select * from _music where id = ?
        // query/# 后面就是匹配这个id
        matcher.addURI(MusicAppConst.AUTHORIES_SERVER_CP, tabName + "/query/#", SELECT_ONE);
    }

    private final String LOG_TAG = getClass().getSimpleName();
    private MusicDBHelper mDbHelper;

    /**
     * 被创建的时候做一些初始化的操作
     */
    @Override
    public boolean onCreate() {
        log("onCreate");
        mDbHelper = new MusicDBHelper(MusicServerApp.getAppInstance());
        return true;
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String
            selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        log("query");

        int match = matchUri(uri);
        if (match == SELECT) {
            SQLiteDatabase database = mDbHelper.getReadableDatabase();
            // 由别人控制要查询哪些,这就是不用dao的原因,行为由用户自己控制
            Cursor cursor = database.query(tabName, projection, selection, selectionArgs, null,
                    null, sortOrder);
            // cursor不能关闭,由调用者关闭,要不然会把其它地方给坑死的
            return cursor;
        } else if (match == SELECT_ONE) {
            // 这里是根据id进行查询
            long id = ContentUris.parseId(uri);
            SQLiteDatabase database = mDbHelper.getReadableDatabase();
            // 由别人控制要查询哪些,这就是不用dao的原因,行为由用户自己控制
            Cursor cursor = database.query(tabName, projection, "music_id = ?", new String[]{id +
                    ""}, null, null, sortOrder);
            // cursor不能关闭,由调用者关闭,要不然会把其它地方给坑死的
            return cursor;
        } else {
            printErrorUri();
        }
        return null;
    }

    private int matchUri(@NonNull Uri uri) {
        return matcher.match(uri);
    }

    private void printErrorUri() {
        log("请求的uri不匹配");
    }

    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        log("getType");
        //The returned MIME type should start with vnd.android.cursor.item for a single record,
        // or vnd.android.cursor.dir/ for multiple items
        int matchUri = matchUri(uri);
        if (matchUri == SELECT) {
            // 多条数据
            return "vnd.android.cursor.dir/" + tabName;
        } else if (matchUri == SELECT_ONE) {
            // 单条数据
            return "vnd.android.cursor.item/" + tabName;
        } else {
            printErrorUri();
        }
        return null;
    }

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
        log("insert");
        int matchUri = matchUri(uri);
        if (matchUri == INSERT) {
            SQLiteDatabase database = mDbHelper.getWritableDatabase();
            database.insert(tabName, null, values);
            database.close();
        } else {
            printErrorUri();
        }
        return null;
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[]
            selectionArgs) {
        log("delete");
        int matchUri = matchUri(uri);
        if (matchUri == DELETE) {
            SQLiteDatabase database = mDbHelper.getWritableDatabase();
            database.delete(tabName, selection, selectionArgs);
            database.close();
        } else {
            printErrorUri();
        }
        return 0;
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String
            selection, @Nullable String[] selectionArgs) {
        log("update");
        int matchUri = matchUri(uri);
        if (matchUri == UPDATE) {
            SQLiteDatabase database = mDbHelper.getWritableDatabase();
            database.update(tabName, values, selection, selectionArgs);
            database.close();
        } else {
            printErrorUri();
        }
        return 0;
    }

    private void log(String str) {
        LoggerUtils.loge(LOG_TAG + " " + str);
    }
}

public class MusicAppConst {
    /**
     * 内容提供者的验证
     */
    public static final String AUTHORIES_SERVER_CP = "com.cokuq.t_music";


    public class KEYSETS {
        /**
         * 数据库名称
         */
        public static final String MUSIC_DB_NAME = "music.db";
        
        /**
         * 数据库版本
         */
        public static final int MUSIC_DB_VERSION = 1;
    }
}

第三方应用在调用的时候,query,insert中的db可能会空,需要重新初始化,这里是一个坑,明明在onCreate中定义了,但是调用的时候,对象均为空,原因暂时未找到,这里做了容错,不影响使用

xml中的配置

<provider
        android:authorities="com.cokuq.t_music"
        android:name=".provider.MusicContentProvider"
        android:exported="true"
        />

ALiCocoMusicPlayer客户端代码

public class MainActivity extends BaseSampleActivity {

    private ContentResolver mContentResolver;

    @Override
    public void initData() {
        mContentResolver = getContentResolver();
    }

    @OnClick({
           R.id.btn_add_all
    })
    public void onViewClick(View view) {
        Uri uri = null;
        switch (view.getId()) {
              case R.id.btn_query_all:
                uri = Uri.parse(ALCooConst.KEY_RSCP_AU_PIREFIX + "select");
                printUri(uri);
                Cursor cursor = mContentResolver.query(uri, null, null, null, "desc");
                List<MusicTabinfo> list = new ArrayList<>();
                MusicTabinfo tabinfo = null;
                while (cursor != null && cursor.moveToNext()) {
                    int _id = cursor.getInt(cursor.getColumnIndex(MusicTabinfo.COLOUMN_NAME_ID));
                    String _name = cursor.getString(cursor.getColumnIndex(MusicTabinfo
                            .COLOUMN_NAME_MUSIC_NAME));
                    String _author = cursor.getString(cursor.getColumnIndex(MusicTabinfo
                            .COLOUMN_NAME_AUTHOR));
                    String _publish_time = cursor.getString(cursor.getColumnIndex(MusicTabinfo
                            .COLOUMN_NAME_PUBLISH_NAME));
                    String _desc = cursor.getString(cursor.getColumnIndex(MusicTabinfo
                            .COLOUMN_NAME_DESC));
                    tabinfo = new MusicTabinfo(_id, _name, _publish_time, _author, _desc);
                    list.add(tabinfo);
                }

                if (list.size() > 0) {
                    for (MusicTabinfo musicTabinfo : list) {
                        LoggerUtils.loge(musicTabinfo.toString());
                    }
                }
                break;
        }
    }

    private void printUri(Uri uri) {
        LoggerUtils.loge(uri.toString());
    }
}

public class ALCooConst {
    // content://content provider authories/tablename
    public static final String KEY_RSCP_AU_PIREFIX = "content://com.cokuq.t_music/t_music/";
}

猜你喜欢

转载自blog.csdn.net/syusikoku/article/details/86604871