Android四大组件之ContentProvider(内容提供者)01

2/22/2017来源:ASP.NET技巧人气:2987

                            前几次说到了Android四大组件的服务和广播,这次我们来聊聊内容提供者吧,内容提供者这个名字从表面上来看就是用来提供内容的,实际意义上,它也是如此

                            他有三个要素:1、要有内容提供给别人,这里的内容也就是我们说的数据,并且是数据库里面的数据 2、要有一个唯一的名字  3、要有允许访问的权限,这就好比一个图书馆,第一它要有书,第二每个书店的名字都是唯一的,第三店面需是对外开放的

                             针对以上内容,我们来写写代码,更深入的来了解了解内容提供者

                             今天我们主要来研究研究内容提供者的两个方面:1、ContentPRovider内容提供者 存在:数据库      2、ContentResolver内容访问者

                             首先我们来新建一个Module(我用的开发工具是AndroidStudio),专门用来从数据库里面取出我们想要的数据

                             在main路径里面新建一个文件夹,取名为db,里面再新建一个class写dbhelper,让它继承SQLiteOpenHelper,并重写里面的两个方法

                            

public class DbHelper extends SQLiteOpenHelper {
    /**
     *
     * @param context  上下文
     * @param name    名字(数据库名),文件名
     * @param factory 游标工厂,多数情况:null
     * @param version 数据库版本
     */
    public DbHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        Log.i("test","构造");
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        //操作:创建表的操作
        Log.i("test","创建表");

        sqLiteDatabase.execSQL("create table person(_id integer primary key autoincrement,name,age)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        Log.i("test","数据库版本,低--->高");
    }

}
                      接下来,我们在main.xml里面写上我们要用到的几个控件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.zking.g150831_android16_sqlite.MainActivity">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_main_id"
        android:hint="ID:"
        />
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_main_name"
        android:hint="Name:"
        />
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_main_age"
        android:hint="age:"
        />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="保存"
        android:onClick="save"
        />

    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@android:id/list"
        ></ListView>


</LinearLayout>

                  listview是用来展示我们所取到的数据,在这里我进行了一个分页查询,只显示两条数据,第三条和第四条,因此,我们还要新建一个xlm

    

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:id="@+id/tv_item_list_id"
        />
    <TextView
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:id="@+id/tv_item_list_name"
        />
    <TextView
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:id="@+id/tv_item_list_age"
        />



</LinearLayout>

                  接着,我们在main.activity里面取数据:

public class MainActivity extends ListActivity {

    private EditText et_main_id;
    private EditText et_main_name;
    private EditText et_main_age;
    private SQLiteDatabase database;
    private ListView listview;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_main_id = (EditText) findViewById(R.id.et_main_id);
        et_main_name = (EditText) findViewById(R.id.et_main_name);
        et_main_age = (EditText) findViewById(R.id.et_main_age);
        listview = getListView();

        //GO
        //java
        //php
        DbHelper dbHelper=new DbHelper(this,"G150831.db",null,2);
        database = dbHelper.getReadableDatabase();
        //Hibernate  session


        //查询数据
        //cursor  游标
       Cursor cursor=database.query(false,"person",null,null,null,null,null,null,"2,2");
        //List<Person>
        //循环游标,---。List<Map<Styring,?>>
        //BaseAdapter  SimpleAdater
        SimpleCursorAdapter simpleCursorAdapter=new SimpleCursorAdapter(this,R.layout.item_listview,cursor,new String[]{"_id","name","age"},new int[]{R.id.tv_item_list_id,R.id.tv_item_list_name,R.id.tv_item_list_age});
        listview.setAdapter(simpleCursorAdapter);
//        database.rawQuery()
    }

    public void save(View view){
        String name=et_main_name.getText().toString();
        String age=et_main_age.getText().toString();

        //存到数据库
//        ContentValues values=new ContentValues();//Map
//        values.put("name",name);
//        values.put("age",age);
//        values.putNull("_id");
//        database.insert("person","name",values);

        //HQL QBC 纯(原)
        for (int i = 0; i <100 ; i++) {
            database.execSQL("insert into person values(null,?,?)",new String[]{name+i,age});
        }
        Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_SHORT).show();
    }
}              这样我们就能从数据库里面取出我们想要的数据了,截图如下:

                   取出数据之后,我们再来新建一个文件夹,取名为provider,里面新建一个class,取名为MyProvider,让它继承ContentProvider,这就是我们的内容提供者啦

public class MyProvider extends ContentProvider{

    private SQLiteDatabase sqLiteDatabase;
    private UriMatcher uriMatcher;

    private static final int PERSONS=1;
    private static final int PERSON=2;

    @Override
    public boolean onCreate() {
        Log.i("test","onCreate");
        DbHelper dbHelper=new DbHelper(getContext(),"G150831.db",null,2);
        sqLiteDatabase = dbHelper.getReadableDatabase();
        //实例化URI匹配器
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        //添加匹配规则
        uriMatcher.addURI("com.zking.g150831_android16_sqlite.person","persons",MyProvider.PERSONS);
        uriMatcher.addURI("com.zking.g150831_android16_sqlite.person","persons/#",MyProvider.PERSON);
        return false;
    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        Log.i("test","query");
        //查询所有的数据
        int code=uriMatcher.match(uri);
        switch (code){
            case MyProvider.PERSONS:
                Log.i("test","query所有");
                //查询所有数据
                return sqLiteDatabase.query(true,"person",projection,selection,selectionArgs,null,null,sortOrder,null);

            case MyProvider.PERSON:
                Log.i("test","query单个");
                //获取#的值
                long id=ContentUris.parseId(uri);
                return sqLiteDatabase.rawQuery("select * from person where _id=?",new String[]{id+""});

        }

        return null;
    }

    @Nullable
    @Override
    public String getType(Uri uri) {
        Log.i("test","getType");
        return null;
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        Log.i("test","insert");
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        Log.i("test","delete");
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        Log.i("test","update");
        return 0;
    }
}                  最后,不要忘了在manifests里面配置

 <!--配置内容提供者-->
        <provider
            android:authorities="com.android16_sqlite.person"
            android:name="com.provider.MyProvider"
            android:exported="true"
            >

        </provider>                  内容提供者写完之后,我们来写内容访问者,再新建一个Module,这个里面我们专门来访问上面的那一个Module里面的数据

                 XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.zking.android_24_contentresolver.MainActivity">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_main_id"
        />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获取数据"
        android:onClick="getData"
        />
</LinearLayout>

               mainactivity:(我们既可以查询单个,又可以查询所有))

public class MainActivity extends AppCompatActivity {

    private ContentResolver cr;
    private Uri uri;
    private EditText et_main_id;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //获取内容访问者
        cr = getContentResolver();
        et_main_id = (EditText) findViewById(R.id.et_main_id);

    }

    public void getData(View view) {
        if(TextUtils.isEmpty(et_main_id.getText())){
            //查询所有
            //
            uri = Uri.parse("content://com.zking.g150831_android16_sqlite.person/persons");
        }else{
            //查询单个
            String id=et_main_id.getText().toString();
            uri = Uri.parse("content://com.zking.g150831_android16_sqlite.person/persons/"+id);
        }
//        uri = Uri.parse("content://com.zking.g150831_android16_sqlite.person" );
        Cursor cursor = cr.query(uri, null, null, null, null);

        //查询单个(URI匹配器)


        while(cursor.moveToNext()){
            int id=cursor.getInt(cursor.getColumnIndex("_id"));
            String name=cursor.getString(cursor.getColumnIndex("name"));
            int age=cursor.getInt(cursor.getColumnIndex("age"));
            Log.i("test",id+age+name);
        }
    }
}