Android开发-数据存储

目录

12.1、SharedPreference

12.2、File I/O

12.3、sqlite3

1、在Android Shell中操作SQLite

2、APP使用SQLite

12.4、ContentProvider


Android系统提供了四种存储数据方式:SharedPreference,SQLite,Content Provider,File I/O

安卓系统中,数据基本都是私有的,存放于/data/data程序包下,若要在应用之间共享数据,可以使用Content Provider组件。

SQLite是安卓系统提供的轻量级数据库,支持基本的SQL语法

SharedPreference是一个格式化数据文件,采用XML的标记方法,常用于设置参数的存储

文件I/O是对各操作系统模块最基本常见的操作

12.1、SharedPreference

SharedPreferences是Android平台上一个轻量级的存储类,用来保存应用的一些常用配置.

比如Activity状态,Activity暂停时,将此activity的状态保存到SharedPereferences中;当Activity重载,系统回调方法onSaveInstanceState时,再从SharedPreferences中将值取出。

其中的原理是通过Android系统生成一个xml文件保到:/data/data/包名/shared_prefs目录下,类似键值对的方式来存储数据。

Sharedpreferences提供了常规的数据类型保存接口比如:int、long、boolean、String、Float、Set和Map这些数据类型。

 public abstract SharedPreferences getSharedPreferences (String name, 
                 int mode)
参数
nameString: 所需的首选项文件
modeint: 操作模式. Value is either 0 or a combination of MODE_PRIVATE, MODE_WORLD_READABLE, MODE_WORLD_WRITEABLE, and MODE_MULTI_PROCESS

参数有两个

第一个表示Share文件的名称,不同的名称对应这不同的Share文件,其中的内容也是不同.

第二个参数表示操作模式,操作模式有四种:MODE_WORLD_READABLE,MODE_WORLD_WRITEABLE,MODE_PRIVATE、MODE_MULTI_PROCESS.

 MODE_PRIVATE //默认操作模式(0),只有当前的应用程序才可以对当前这个SharedPreferences文件进行读写。
 MODE_MULTI_PROCESS //用于多个进程共同操作一个SharedPreferences文件。
 MODE_WORLD_WRITEABLE //数据能被其他应用程序读和写.
 MODE_WORLD_READABLE //数据能被其他应用程序读,但不能写.
 SharedPreferences sp=this.getSharedPreferences("myth",MODE_PRIVATE);//1.
 if(sp!=null){
    String stmp;
    Toast.makeText(this,stmp=sp.getString("testmsg","no value"),Toast.LENGTH_SHORT).show();
    if(stmp.equals("no value")){
       SharedPreferences.Editor editor=sp.edit();
       editor.putString("testmsg","SharedPreferences!!");//2.3.
       editor.commit();
    }
 }
 else {
    sp.getString("testmsg","");
 }

步骤:

  1. 获取Editor对象,这个对象用于写入

  2. Editor对象有几个方法需要注入:clear(),commit(),putXXX(),

    clear()为清空Share文件中的内容,commit()为提交,

    editor在put值以后,需要调用commit方法才能被真正写入到Share文件中.

  3. 当要取回数据时,先获取对应的Share

  4. 根据key取出对应的值,其中第二个参数为默认值,即当从Share中取不到时,返回这个值,这里会返回一个空串。

Android会在文件资源的/data/data目录下,创建一个本工程名的目录,我们所编写的“myth”文件就在此

 <map>
     <string name="testmsg">SharedPreferences!!</string>
 </map>

12.2、File I/O

Android自带的文件输入输出流:

 public FileOutputStream openFileOutput(String name, int mode) throws FileNotFoundException {
     throw new RuntimeException("Stub!");
 }
 public FileInputStream openFileInput(String name) throws FileNotFoundException {
     throw new RuntimeException("Stub!");
 }

变量定义:

EditText file_name,file_content;
 FileOutputStream fos;
 FileInputStream fis;
 Button bt_copy;
 String fname;
 int flag=1;
 file_name=(EditText) findViewById(R.id.exer_filename);
 file_content=(EditText) findViewById(R.id.exer_filecontent);
 bt_copy=(Button)findViewById(R.id.exer_copyfile);
 bt_copy.setEnabled(false);

对于文件存储:

case R.id.exer_savefile:{
     try {
         fname=file_name.getText()==null?"":file_name.getText().toString();//判断取值
         if(!fname.equals("")) {
             fos = openFileOutput(fname + ".txt", MODE_PRIVATE);
         }
         else fos=openFileOutput("defaultname.txt",MODE_PRIVATE);
         //如果文件名文本框为空,则自动创建一个defaultname.txt文件
         String content=file_content.getText().toString();
         fos.write(content.getBytes());//字节流输入
         if(fos!=null)//设置赋值按钮可用
         {
             bt_copy.setEnabled(true);
         }
     } catch (FileNotFoundException e) {
         e.printStackTrace();
     } catch (IOException e) {
         e.printStackTrace();
     }finally {
         try {
             if(fos!=null) {
                 fos.flush();
                 fos.close();
             }
         }catch (IOException e){
             e.printStackTrace();
         }
     }
     file_name.setText("");//清空内容
     file_content.setText("");//清空内容
     break;
 }

对于文件复制:

case R.id.exer_copyfile:{
     try {
         fis=openFileInput(fname+".txt");
         int n=0;
         StringBuffer stringBuffer=new StringBuffer();//用于存放读取的字节流
        do{
             n=fis.read();
             if(n!=-1)
                 stringBuffer.append((char)n);
         }while (n!=-1);
         fos = openFileOutput(fname + "("+flag+")"+".txt", MODE_PRIVATE);//flag用于多次复制
         fos.write(stringBuffer.toString().getBytes());
     } catch (FileNotFoundException e) {
         e.printStackTrace();
     } catch (IOException e) {
         e.printStackTrace();
     }finally {
             try {
                 if(fis!=null)
                     fis.close();
                 if(fos!=null)
                 {
                     fos.flush();
                     fos.close();
                 }
             } catch (IOException e) {
                 e.printStackTrace();
             }
 ​
     }
     flag++;
     break;
 }

12.3、sqlite3

1、在Android Shell中操作SQLite

通过命令提示符定位到adb.exe所在路径:

使用shell命令即可运行,执行sqlite3即可进入sqlite数据库

注:运行adb时只能有一个设备连接,否则会出现错误

注意:在连接自己手机时,需要root权限才能查看data数据 

2、APP使用SQLite

准备数据库有关的基本信息

 private static final String DB_NAME = "people.db";
 private static final int DB_VERSION = 1;
 private static final String TB_NAME1 = "peopleinfo";
 ​
 public static final String KEY_ID = "_id";
 public static final String KEY_NAME = "name";
 public static final String KEY_AGE = "age";
 public static final String KEY_HEIGHT = "height";

创建数据库对象

 public class DBHelper extends SQLiteOpenHelper {
     Context context;//供Toast使用
     public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
         super(context, name, factory, version);
         this.context=context;
     }
     @Override
     public void onCreate(SQLiteDatabase sqLiteDatabase) {
 ​
     }
 ​
     @Override
     public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
 ​
     }
     //oncreate,一般进行数据表的创建;
     //该函数的形参,为帮助器成功连接数据库后连接到的数据库对象的引用
     //onupgrade,一般销毁或更新数据表
 }

继承SQLiteOpenHelper类,调用其构造方法岂可创建一个数据库对象

参数:
contextContext: 依附的安卓组件,用于定位数据库的路径,可为空
nameString: 数据库文件名
factorySQLiteDatabase.CursorFactory: 用于创建游标对象,默认为null
versionint: 数据库标号(从1开始)如果数据库较旧,则使用onUpgrade(sqlitedatdatabase, int, int)来升级数据库;如果数据库较新,则使用onDowngrade(SQLiteDatabase, int, int)来降级数据库

布局文件:

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical" >
     <Button android:id="@+id/exer_createdb"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="exer创建/连接数据库" />
     <TextView android:id="@+id/exer_content"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:text="数据库内容为:"/>
 ​
     <TextView android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:text="操作数据库:" />
     <LinearLayout android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal">
         <TextView android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="姓名:"/>
         <EditText
         android:id="@+id/exer_name"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:inputType="text"/>
     </LinearLayout>
     <LinearLayout android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal">
         <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="年龄: "/>
         <EditText
         android:id="@+id/exer_age"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:inputType="number"/>
     </LinearLayout>
     <LinearLayout android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal">
         <TextView android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="身高: "/>
         <EditText
         android:id="@+id/exer_height"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:inputType="number"/>
     </LinearLayout>
     <Button android:id="@+id/exer_insert"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="插入记录"/>
     <LinearLayout android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal">
         <TextView android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="当ID为: "/>
         <EditText
         android:id="@+id/exer_id"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:inputType="number"/>
         <Button android:id="@+id/exer_query"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="查询记录"/>
         <Button android:id="@+id/exer_delete"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="删除记录"/>
     </LinearLayout>
     <TextView android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:id="@+id/exer_result"
         android:text="操作结果为:"/>
     
     <!-- space -->
     <Space android:layout_width="match_parent"
         android:layout_height="16dip"/>
     
     <!-- hori bar --> 
     <View android:layout_width="match_parent"
         android:layout_height="2dip"
         android:background="#9b9b9b"/> 
         
     <Button
         android:id="@+id/exer_queryall"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="查询所有"/>
     <TextView
         android:id="@+id/exer_info"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:text="info:"/>
 </LinearLayout>

连接数据库

case R.id.exer_createdb:{
     if(helper!=null){
         Log.i("mytag","helper not null");
         try {
             //调用构造函数来建立数据库对象
             //回调oncreate函数
             db=helper.getWritableDatabase();
         }catch (Exception e){
             Toast.makeText(DBTest.this,"数据库创建失败",Toast.LENGTH_SHORT).show();
         }
     }
     else{
         Log.i("mytag","helper is null");
     }
     break;
 }
 @Override
 public void onCreate(SQLiteDatabase sqLiteDatabase) {
     if (sqLiteDatabase != null) {
         //执行数据库语句创建数据表
         sqLiteDatabase.execSQL("create table " + TB_NAME1 + "(" +
                 KEY_ID + " integer primary key autoincrement, " +
                 KEY_NAME + " text not null, " +
                 KEY_AGE + " integer, " +
                 KEY_HEIGHT + " double" +
                 ");");
     }
 }
 @Override
 public void onUpgrade(SQLiteDatabase db, int i, int i1) {
     if(db != null) {
         db.execSQL("drop table if exists " + TB_NAME1);
         onCreate(db);
     }
 }

我们所有的CRUD操作都放在Helper类中编写

查询所有数据

 public String queryall(SQLiteDatabase sqLiteDatabase) {
     Cursor cursor = null;
     String str = "";
     if (sqLiteDatabase != null) 
         cursor = sqLiteDatabase.query(TB_NAME1, null, null, null, null, null, null);
         if (cursor != null) {
             cursor.moveToFirst();
             do{
                 str += "id:" + cursor.getInt(0) +
                         "name:" + cursor.getString(1) +
                         "age" + cursor.getInt(2) +
                         "height" + cursor.getDouble(3) + "\n";
             }while (cursor.moveToNext());
         }
         else {
             Toast.makeText(this.context,"查询失败",Toast.LENGTH_SHORT).show();
         }
         if(str.equals("")||str.hashCode()==0)
             return "null";
         else
             return str;
 }
 //构造方法
 public Cursor query (String table, 
                 String[] columns, 
                 String selection, 
                 String[] selectionArgs, 
                 String groupBy, 
                 String having, 
                 String orderBy)
Parameters
tableString: 要编译查询的表名
columnsString: 要返回的列的列表。传递null将返回所有列。
selectionString:声明要返回哪些行的过滤器,格式化为SQL WHERE子句(不包括WHERE本身)。传递null将返回给定表的所有行。
selectionArgsString: 您可以在selection中包含'?',它们将被来自selectionArgs的值替换,以便它们出现在选择中。这些值将被绑定为string
groupByString: 一个过滤器,声明如何将格式化为SQL group BY子句的行分组(不包括group BY本身)。传递null将导致行不分组。
havingString: 如果使用行分组,则过滤器声明将哪些行组包含在游标中,格式化为SQL HAVING子句(不包括HAVING本身)。传递null将导致包含所有行组,当不使用行分组时需要此参数。
orderByString: 如何对格式化为SQL order BY子句的行进行排序(不包括order BY本身)。传递null将使用默认的排序顺序,这可能是无序的。

Cursor游标:

Query函数会返回一个游标

Returns
CursorCursor : 它位于第一个条目之前。注意游标不是同步的,

通过id查询

 String arg[]={id};
 cursor=sqLiteDatabase.query(TB_NAME1,null,KEY_ID+"=?",arg,null,null,null);
 //通过selection指明的where来进行判断

插入一条记录

 public long insert(String name,String age,String height,SQLiteDatabase sqLiteDatabase){
     Log.i("mytag","insert");
     long row=0;
         ContentValues contentValues=new ContentValues();
         contentValues.put(KEY_HEIGHT,height);
         contentValues.put(KEY_AGE,age);
         contentValues.put(KEY_NAME,name);
 ​
     if(sqLiteDatabase!=null)
     {
         row=sqLiteDatabase.insert(TB_NAME1,KEY_NAME,contentValues);
         Log.i("mytag","row:"+row);
     }
     return row;
 }
//构造方法
 public long insert (String table, 
                 String nullColumnHack, 
                 ContentValues values)
Parameters
tableString: 要插入的表名
nullColumnHackString: 可选的;可能是null。SQL不允许在没有命名至少一个列名的情况下插入一个完全空的行。如果提供的值为空,则没有已知的列名,不能插入空行。如果不设置为空,nullColumnHack参数提供可空列名的名称,以便在值为空的情况下显式插入null。
valuesContentValues:此映射包含该行的初始列值。键应该是列名,值应该是列值

删除一条数据

 public int deletebyid(String id,SQLiteDatabase sqLiteDatabase){
     int row=0;
     String arg[]={id};
     if(sqLiteDatabase!=null)
         row=sqLiteDatabase.delete(TB_NAME1,KEY_ID+"=?",arg);
     return row;
 }
 //构造函数
 public int delete (String table, 
                 String whereClause, 
                 String[] whereArgs)
Parameters
tableString:要操作的表名
whereClauseString:在删除时应用可选的WHERE子句。传递null将删除所有行。
whereArgsString:可以在where子句中包含'?',该子句将被来自whereArgs的值替换。这些值将被绑定为string。

12.4、ContentProvider

ContentProvider(内容提供者)是Android中的四大组件之一。

主要用于对外共享数据,也就是通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对指定应用中的数据进行操作。

ContentProvider分为系统的和自定义的,系统的也就是例如联系人,图片等数据。

Android提供了一些主要数据类型的ContentProvider,比如音频、视频、图片和私人通讯录等。可在android.provider包下面找到一些Android提供的ContentProvider。通过获得这些ContentProvider可以查询它们包含的数据,当然前提是已获得适当的读取权限。

步骤:

1.自定义类继承ContentProvider,并重写6个函数

public class cp extends ContentProvider {
     DBHelper helper;//数据库
     SQLiteDatabase database;
 /*oncreate:
     获取数据库指针
     将数据库连接封装到helper中的自定义类opendb
     主程序只需要调用方法即可拿到db对象
 */
     @Override
     public boolean onCreate() {
         helper=new DBHelper(TESTCP.this.getContext());
         database=helper.opendb();
         return true;
     }
 //oncreate()函数在创建cp对象后回调,一般在oncreate中建立cp与数据源的连接
 //需要根据数据源的初始化情况,手动返回bool
    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        database=helper.opendb();
        Cursor cursor=null;
        if(uri.toString().equals(uri_str+multi_path1))
            cursor=helper.Queryall(database);
        else if(uri.toString().equals(uri_str+Single_path1))
            cursor=helper.QueryByID(database,selectionArgs);
        return cursor;
    }
 ​
 /*getType:
     定义数据源的MIME类型
     格式:type/subtype
     在安卓中自定义mime类型   vnd.android.cursor.dir/  vnd.android.cursor.item/
     以上两种cp的mime类型使用了安卓规定的主类型,子类型可以自定义
     .dir/ 对应数据集(表或多行记录)
     .item/ 对应单个数据(单条记录)
     
     安卓中,自定义cp的uri时,要注意其对应的mime类型
     content://com.mo.cp/testcp/#
     "content://com.mo.cp/" 定位到数据源
     "testcp"定位到数据表
     "/#" 定位到表中某条记录
     uri协议如果配合content使用则协议必须使用content
 */
    String uri_str="content://com.mo.cp",multi_path1="/testcp",Single_path1="/testcp/#";
    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        if(uri.toString().equals(uri_str+multi_path1))
            return "vnd.android.cursor.dir/mytestcp";
        else if(uri.toString().equals(uri_str+Single_path1))
            return "vnd.android.cursor.item/mytestcp";
        else
            return null;
    }
     //getType()函数主要用来根据uri来返回对应的mime类型
 ​
     @Nullable
     @Override
     public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
         long res=-1;
         if(uri.toString().equals(uri_str+multi_path1))
             if(helper!=null)
                 res=helper.insertdb(database,contentValues);
         if (res!=-1) {
             helper.closedb(database);
             return Uri.parse(uri_str + multi_path1 + "/" + res);
         }
         else {
             helper.closedb(database);
             return null;
         }
         //插入成功后,要手动返回新的uri值
     }
 ​
     @Override
     public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
         int res=0;
         if (uri.toString().equals(uri_str+Single_path1)){
             res=helper.delete(database,s,strings);
         }
         return res;
     }
 ​
     @Override
     public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
         return 0;
     }
 }

2.编写DBHelper函数建立与数据库的连接

 public class DBHelper extends SQLiteOpenHelper {
     Context context;
     private static final String DB_NAME = "people.db";
     private static final int DB_VERSION = 1;
     private static final String TB_NAME1 = "userinfo";
 ​
     public static final String KEY_ID = "_id";
     public static final String KEY_NAME = "name";
     public static final String KEY_AGE = "age";
     public static final String KEY_HEIGHT = "height";
 ​
     public DBHelper(@Nullable Context context) {
         super(context, DB_NAME, null,DB_VERSION);
         this.context=context;
     }
 ​
     @Override
     public void onCreate(SQLiteDatabase sqLiteDatabase) {
         sqLiteDatabase.execSQL("create table " + TB_NAME1 + "(" +
                 KEY_ID + " integer primary key autoincrement, " +
                 KEY_NAME + " text not null, " +
                 KEY_AGE + " integer, " +
                 KEY_HEIGHT + " double" +
                 ");");
     }
 ​
     public SQLiteDatabase opendb(){
         SQLiteDatabase db=null;
         try {
             db=this.getWritableDatabase();
         }catch (Exception e){
             Log.i("mytag","db open failed...");
         }
 ​
         return db;
     }
     public void closedb(SQLiteDatabase database){
         if(database!=null)
             database.close();
     }
     public long insertdb(SQLiteDatabase database, ContentValues contentValues){
         long res=-1;
         if(database!=null)
             res=database.insert(TB_NAME1,null,contentValues);
         return res;
     }
     //查询所有用户信息
     public Cursor Queryall(SQLiteDatabase database){
         Cursor cursor=null;
         if(database!=null)
             cursor=database.query(TB_NAME1,null,null,null,null,null,null);
         return cursor;
     }
     //通过ID号查询信息
     public Cursor QueryByID(SQLiteDatabase database,String[] selectionArgs){
         Cursor cursor=null;
         if(database!=null)
             cursor=database.query(TB_NAME1,null,KEY_ID+"=?",selectionArgs,null,null,null);
         return cursor;
     }
     //删除一条记录
     public int delete(SQLiteDatabase database,String whereClause,String[] whereArgs){
         int res=0;
         if(database!=null)
             res=database.delete(TB_NAME1,whereClause,whereArgs);
         return res;
     }
     @Override
     public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
 ​
     }
 }

3.在清单文件中对provider对象进行注册

 <!--要与自定义的mime类型一致-->
 <provider
     android:authorities="com.mo.cp"
     android:name=".TESTCP"
     android:exported="true">
 </provider>

4.新建Model项目通过ContentResolver对象来实现CRUD

 public class Amain extends Activity {
     ContentResolver contentResolver;
 ​
     EditText name,age,height;
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.ly_amain);
         name=(EditText)findViewById(R.id.exer_id);
         age=(EditText)findViewById(R.id.exer_age);
         height=(EditText)findViewById(R.id.exer_height);
 ​
         contentResolver=getContentResolver();
         Listener Listener=new Listener();
         findViewById(R.id.exer_insert).setOnClickListener(Listener);
         findViewById(R.id.exer_queryall).setOnClickListener(Listener);
         findViewById(R.id.exer_query).setOnClickListener(Listener);
         findViewById(R.id.exer_delete).setOnClickListener(Listener);
 ​
     }
     class Listener implements View.OnClickListener{
         @Override
         public void onClick(View view) {
             switch (view.getId()){
                 case R.id.exer_insert:{
                     Uri res=null;
                     ContentValues contentValues=new ContentValues();
                     contentValues.put(profile.KEY_NAME,name.getText().toString());
                     contentValues.put(profile.KEY_AGE,age.getText().toString());
                     contentValues.put(profile.KEY_HEIGHT,height.getText().toString());
                     if(contentResolver!=null)
                         res=contentResolver.insert(Uri.parse(profile.uri_str+profile.multi_path1),contentValues);
                     if(res==null)
                         Toast.makeText(Amain.this,"failed",Toast.LENGTH_SHORT).show();
                     else
                         Toast.makeText(Amain.this,res.toString(),Toast.LENGTH_LONG).show();
                     break;
                 }
                 case R.id.exer_queryall:{
                     Cursor cursor=null;
                     String str="";
                     if(contentResolver!=null)
                        cursor= contentResolver.query(Uri.parse(profile.uri_str+profile.multi_path1),null,null,null,null);
                     while (cursor.moveToNext()){
                         str += "id:" + cursor.getInt(0) +
                                 "name:" + cursor.getString(1) +
                                 "age" + cursor.getInt(2) +
                                 "height" + cursor.getDouble(3) + "\n";
                         TextView tv=findViewById(R.id.exer_info);
                         tv.setText(str);
                     }
                     break;
                 }
                 case R.id.exer_query:{
                     String id=((EditText) findViewById(R.id.exer_id)).getText().toString();
                     Cursor cursor=null;
                     String str="";
                     String[] arg={id};
                     if(contentResolver!=null){
                         cursor=contentResolver.query(Uri.parse(profile.uri_str+ profile.Single_path1),null,null,arg,null);
                     }
                     cursor.moveToNext();
                         str += "id:" + cursor.getInt(0) +
                                 "name:" + cursor.getString(1) +
                                 "age" + cursor.getInt(2) +
                                 "height" + cursor.getDouble(3) + "\n";
                         TextView tv = findViewById(R.id.exer_result);
                         tv.setText(str);
 ​
                     break;
                 }
                 case R.id.exer_delete:{
                     String id=((EditText) findViewById(R.id.exer_id)).getText().toString();
                     int res=0;
                     if(contentResolver!=null){
                         res=contentResolver.delete(Uri.parse(profile.uri_str+profile.Single_path1),profile.KEY_ID+"=?",new String[]{id});
                     }
                     if(res>0)
                         Toast.makeText(Amain.this,"删除成功",Toast.LENGTH_SHORT).show();
                     else
                         Toast.makeText(Amain.this,"删除失败",Toast.LENGTH_SHORT).show();
                     break;
                 }
             }
         }
     }
 ​
     @Override
     protected void onDestroy() {
         super.onDestroy();
     }
 }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值