增加功能实现
在联系人项目的基础上做如下修改:
增加PersonProvider
public class PersonProvider extends ContentProvider {
@Override
public boolean onCreate() {
return false;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] strings, @Nullable String s, @Nullable String[] strings1, @Nullable String s1) {
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
DBOpenHelper dbOpenHelper = new DBOpenHelper(getContext());
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
String nullColumnHack = "_id";
long id = db.insert("users",nullColumnHack,contentValues);
//释放资源
db.close();
db = null;
return null;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String s, @Nullable String[] strings) {
return 0;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) {
return 0;
}
}
AndroidManifest
<provider
android:authorities="hello_world"
android:name=".provider.PersonProvider"
android:exported="true"/>
运行程序,让PersonProvider运行在模拟机上,我们顺便看一下数据有哪些
然后新建一个项目MyApplication2
MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//测试增加数据
testInsert();
}
private void testInsert() {
//准备ContentResolver
ContentResolver cr = getContentResolver();
//相当于网址
Uri uri = Uri.parse("content://hello_world");
//向数据库中增加的数据的值
ContentValues values = new ContentValues();
values.put("_name","Susan");
values.put("_age",44);
values.put("_phone","14444444444");
values.put("_email","[email protected]");
//执行增加
cr.insert(uri,values);
}
}
运行程序,然后再打开第一个项目看下数据
扫描二维码关注公众号,回复:
1493776 查看本文章
已经增加成功了
查询数据的功能实现
如下:
PersonProvider
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] strings, @Nullable String s, @Nullable String[] strings1, @Nullable String s1) {
//声明返回值
List<Person> persons = new ArrayList<Person>();
//获取SQLiteDatabase对象
DBOpenHelper dbOpenHelper = new DBOpenHelper(getContext());
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
//执行业务:查询数据
String table = "users";
Cursor c = db.query("users", strings, s, strings1, null, null, s1);
return c;
}
第二个项目中的MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//测试增加数据
//testInsert();
//测试查询数据
testQuery();
}
private void testQuery() {
ContentResolver cr = getContentResolver();
Uri uri = Uri.parse("content://hello_world");
//执行查询
Cursor c = cr.query(uri, null, null, null, null);
for(c.moveToFirst();!c.isAfterLast();c.moveToNext()){
int id = c.getInt(c.getColumnIndex("_id"));
String name = c.getString(c.getColumnIndex("_name"));
int age = c.getInt(c.getColumnIndex("_age"));
String phone = c.getString(c.getColumnIndex("_phone"));
String email = c.getString(c.getColumnIndex("_email"));
Log.d("CONTENT_PROVIDER","id:"+id+";name:"+name+";age:"+age+":phone:"+phone+";email:"+email);
}
}
......
}
运行第二个项目,查看日志如下
我们打开Device File Explorer,我们会发现有很多包含providers的文件夹,这些是安卓内置的使用ContentProvider共享数据的程序
打开com.android.providers.media中databases,导出internal.db
我们打开audio表,可以看到歌曲相关信息
同样打开external.db,可以看到我们音乐播放器3项目中的歌曲
改进音乐播放器3
新增MediaStoreMusicDao
public class MediaStoreMusicDao implements IDao<Music> {
private Context content;
public MediaStoreMusicDao(Context content) {
this.content = content;
}
@Override
public List<Music> getData() {
//声明返回值
List<Music> musics = new ArrayList<>();
//准备ContentResolver
ContentResolver cr = content.getContentResolver();
//准备Uri
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
//读数据,获取Cursor对象
String[] projection = {
"_id",//0
"_data",//1->path
"title",//2
"duration",//3
"album",//4
"artist",//5
"album_artist"//
};//读取的字段
String selection = null;
String[] selectionArgs = null;
String sortOrder = null;
Cursor c = cr.query(uri,projection,selection,selectionArgs,sortOrder);
//遍历Cursor,向返回值中添加数据
for(c.moveToFirst();!c.isAfterLast();c.moveToNext()){
Music music = new Music();
music.setId(c.getLong(0));
music.setPath(c.getString(1));
music.setTitle(c.getString(2));
music.setDuration(c.getInt(3));
music.setAlbum(c.getString(4));
music.setArtist(c.getString(5));
music.setAlbumArtist(c.getString(6));
musics.add(music);
}
//释放资源
c.close();
c = null;
return musics;
}
}
修改MusicDaoFactory
public class MusicDaoFactory {
//如果是单例,就用getInstance();
public static IDao<Music> newInstance(Context context){
return new MediaStoreMusicDao(context);
}
}
修改Music类,我们要存储更多的数据
public class Music {
private long id;
private String title;
private String path;
private int duration;
private String album;
private String artist;
private String albumArtist;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
public String getAlbum() {
return album;
}
public void setAlbum(String album) {
this.album = album;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getAlbumArtist() {
return albumArtist;
}
public void setAlbumArtist(String albumArtist) {
this.albumArtist = albumArtist;
}
}
我们之前的音乐播放器只显示了标题和路径,我们可以调整界面,显示更多的内容了
item_music
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<TextView
android:id="@+id/tv_music_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="title"
android:textColor="#222222"
android:textSize="15dp"
/>
<TextView
android:id="@+id/tv_music_duration"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="00:00"
android:textColor="#222222"
android:textSize="15dp"
android:layout_alignParentRight="true"
android:layout_marginLeft="10dp"
/>
<TextView
android:id="@+id/tv_music_album"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:maxLines="1"
android:layout_below="@+id/tv_music_title"
android:text="path......"
android:textColor="#999999"
android:textSize="15dp"
/>
<TextView
android:id="@+id/tv_music_artist"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:maxLines="1"
android:layout_below="@+id/tv_music_title"
android:text="path......"
android:textColor="#999999"
android:textSize="15dp"
android:layout_toRightOf="@+id/tv_music_album"
android:layout_marginLeft="10dp"
/>
</RelativeLayout>
修改MusicAdapter
public class MusicAdapter extends BaseAdapter<Music> {
public MusicAdapter(Context context, List data) {
super(context, data);
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
Music music = getData().get(i);
ViewHolder holder;
if(view == null){
view = getInflater().inflate(R.layout.item_music,null);
holder = new ViewHolder();
holder.title = view.findViewById(R.id.tv_music_title);
holder.duration = view.findViewById(R.id.tv_music_duration);
holder.album = view.findViewById(R.id.tv_music_album);
holder.artist = view.findViewById(R.id.tv_music_artist);
view.setTag(holder);
}else{
holder = (ViewHolder) view.getTag();
}
holder.title.setText(music.getTitle());
holder.duration.setText(CommonUtils.getFormattedTime(music.getDuration()));
holder.album.setText(music.getAlbum());
holder.artist.setText(music.getArtist());
return view;
}
class ViewHolder{
TextView title;
TextView duration;
TextView album;
TextView artist;
}
}
同时之前通过MediaPlayer获得时长的代码
player.getDuration()
可以全部替换成
musics.get(currentMusicIndex).getDuration()
可以通过数据库读取了
因为自带的模拟器对中文的支持不是很好,如果出现???是无解题,最终显示效果可以参看模拟器自带的Music应用显示效果