安卓速记2--数据存储方式

Android提供以下四种存储方式:

SharePreference

SQLite

File

ContentProvider

如果要实现数据共享,正确的方式是使用ContentProvider




SharedPreference

  • “用户的偏好设置”通常用来存储程序的一些配置信息。
  • 其存储在“data/data/程序包名/shared_prefs目录下。
  • 使用键-值的形式来存储数据;我们只需要调用SharedPreferences的getXxx(name), 就可以根据键获得对应的值!
  • SharedPreference本身只能获取数据,存储和修改要通过Editor对象来实现。


 

代码速记:

存储数据

SharedPreferencessp =context.getSharedPreferences("CITY", MODE_PRIVATE); //获取对象
Editoreditor=sp.edit();
editor.putString("CityName",City.getCity().getCityName());//存储数据
editor.commit();//将数据提交 

读取数据

 //定义一个读取SP文件的方法

public Map<String, String> read() {
Map<String, String> data =new HashMap<String, String>();
SharedPreferences sp =mContext.getSharedPreferences("mysp", Context.MODE_PRIVATE);
data.put("username", sp.getString("username","")); //获取数据;
data.put("passwd", sp.getString("passwd",""));
return data;
}

SharedPreference工具类:

SPUtils.java

package com.jay.sharedpreferencedemo3;

import android.content.Context;
import android.content.SharedPreferences;

import java.util.Map;

/**
 * Created by Jay on 2015/9/2 0002.
 */
public class SPUtils {
    /**
     * 保存在手机里的SP文件名
     */
    public static final String FILE_NAME = "my_sp";

    /**
     * 保存数据
     */
    public static void put(Context context, String key, Object obj) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        if (obj instanceof Boolean) {
            editor.putBoolean(key, (Boolean) obj);
        } else if (obj instanceof Float) {
            editor.putFloat(key, (Float) obj);
        } else if (obj instanceof Integer) {
            editor.putInt(key, (Integer) obj);
        } else if (obj instanceof Long) {
            editor.putLong(key, (Long) obj);
        } else {
            editor.putString(key, (String) obj);
        }
        editor.commit();
    }


    /**
     * 获取指定数据
     */
    public static Object get(Context context, String key, Object defaultObj) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        if (defaultObj instanceof Boolean) {
            return sp.getBoolean(key, (Boolean) defaultObj);
        } else if (defaultObj instanceof Float) {
            return sp.getFloat(key, (Float) defaultObj);
        } else if (defaultObj instanceof Integer) {
            return sp.getInt(key, (Integer) defaultObj);
        } else if (defaultObj instanceof Long) {
            return sp.getLong(key, (Long) defaultObj);
        } else if (defaultObj instanceof String) {
            return sp.getString(key, (String) defaultObj);
        }
        return null;
    }

    /**
     * 删除指定数据
     */
    public static void remove(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.remove(key);
        editor.commit();
    }


    /**
     * 返回所有键值对
     */
    public static Map<String, ?> getAll(Context context) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        Map<String, ?> map = sp.getAll();
        return map;
    }

    /**
     * 删除所有数据
     */
    public static void clear(Context context) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.clear();
        editor.commit();
    }

    /**
     * 检查key对应的数据是否存在
     */
    public static boolean contains(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        return sp.contains(key);
    }

}


SQLite

  • SQLite是一个轻量级关系型数据库,只有NULL、INTEGER、REAL(浮点数)、TEXT(字符串)和BLOB(大数据)五种类型,不存在BOOLEAN和DATE类型。
  • SQLiteOpenHelper:抽象类,我们通过继承该类,然后重写数据库创建以及更新的方法, 我们还可以通过该类的对象获得数据库实例,或者关闭数据库!
  • SQLiteDatabase:数据库访问类:我们可以通过该类的对象来对数据库做一些增删改查的操作
  • Cursor:游标,有点类似于JDBC里的resultset,结果集!可以简单理解为指向数据库中某 一个记录的指针!

代码速记:

(1).创建数据库

public class MyDBOpenHelper extends SQLiteOpenHelper {
    public MyDBOpenHelper(Contextcontext, String name, CursorFactory factory,
            int version){super(context, "my.db", null, 1); }
    @Override
    //数据库第一次创建时被调用
    public voidonCreate(SQLiteDatabase db) {
        db.execSQL("CREATETABLE person(personid INTEGER PRIMARY KEY AUTOINCREMENT,nameVARCHAR(20))");
       
    }
    //软件版本号发生改变时调用
    @Override
    public voidonUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("ALTERTABLE person ADD phone VARCHAR(12) NULL");
    }
}

(2).插入数据:

dbOpenHelper.getWritableDatabase()

public voidsave(Person p)
{
    SQLiteDatabase db =dbOpenHelper.getWritableDatabase();
    db.execSQL("<span style="color:#339999;">INSERT</span> INTOperson(name,phone) values(?,?)",new String[]{p.getName(),p.getPhone()});
}

3.删除数据:同上

    db.execSQL("DELETEFROM person WHEREpersonid = ?",new String[]{id});

4.修改数据:同上

    db.execSQL("UPDATEperson SET name =?,phone = ? WHERE personid = ?",newString[]{p.getName(),p.getPhone(),p.getId()});

5.查询数据:

dbOpenHelper.getReadableDatabase()

public Personfind(Integer id)
{
    SQLiteDatabase db =dbOpenHelper.getReadableDatabase();
    Cursor cursor =  db.rawQuery("SELECT * FROM person WHEREpersonid = ?",new String[]{id.toString()});
    //存在数据才返回true
    if(cursor.moveToFirst())
    {
        int personid =cursor.getInt(cursor.getColumnIndex("personid"));
        String name =cursor.getString(cursor.getColumnIndex("name"));
        String phone =cursor.getString(cursor.getColumnIndex("phone"));
        return new Person(personid,name,phone);
    }
    cursor.close();
    return null;
}

6.数据分页:

dbOpenHelper.getReadableDatabase()

publicList<Person> getScrollData(int offset,int maxResult)
{
    List<Person> person = newArrayList<Person>();
    SQLiteDatabase db =dbOpenHelper.getReadableDatabase();
    Cursor cursor =  db.rawQuery("SELECT * FROM person ORDERBY personid ASC LIMIT= ?,?",
        newString[]{String.valueOf(offset),String.valueOf(maxResult)});
    while(cursor.moveToNext())
    {
        int personid =cursor.getInt(cursor.getColumnIndex("personid"));
        String name =cursor.getString(cursor.getColumnIndex("name"));
        String phone =cursor.getString(cursor.getColumnIndex("phone"));
        person.add(newPerson(personid,name,phone)) ;
    }
    cursor.close();
    return person;
}


7.查询记录数:

dbOpenHelper.getReadableDatabase()

public longgetCount()
{
    SQLiteDatabase db =dbOpenHelper.getReadableDatabase();
    Cursor cursor =  db.rawQuery("SELECT COUNT (*) FROMperson",null);
    cursor.moveToFirst();
    long result = cursor.getLong(0);
    cursor.close();
    return result;     
}  

PS:除了上面获取条数的方法外还可以使用cursor.getCount()方法获得数据的条数, 但是SQL语句要改改!比如SELECT * FROMperson;

 

 File

文件存储读写

openFileOutput(filename,mode)         往文件写数据

openFileIntput(filename)       读取文件中的信息到程序

getDir(name,mode)             在app的data目录下获取或创建name对应的子目录

getFileDir()                   获取app的data目录的file目录的绝对路径

String[]fileList()      返回app的data目录下的全部文件

deleteFile(filename)             删除app的data目录下的指定文件


ContentProvider

ContentProvider相对于其它的方式比较复杂。它能够实现跨应用之间的数据操作。利用ContentResolver对象的delete、update、insert、query等方法去操ContentProvider的对象,让ContentProvider对象的方法去对数据操作。实现方式为:


  • 在A程序中定义一个ContentProvider,重载其增删查改等方法;

    • 在A程序中的AndroidManifest.xml中注册ContentProvider;
    • 在B程序中通过ContentResolver和Uri来获取ContentProvider的数据,同样利用Resolver的增删查改方法来获得和处理数据。

    在A程序定义一个Provider

    新建一个类,继承ContentProvider,并重载其delete()、insert()、query()、update()、getType()、onCreate()方法。譬如下面的例子,重载其onCreate和query方法
    注:从5.0开始,默认短信应用外的软件不能以写入短信数据库的形式发短信!
    public class MyProvider extends ContentProvider {
    
        @Override
        public int delete(Uri uri, String selection, String[] selectionArgs) {
            // TODO Auto-generated method stub
            return 0;
        }
    
        @Override
        public String getType(Uri uri) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public Uri insert(Uri uri, ContentValues values) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public boolean onCreate() {
            // 新建个数据库并插入一条数据
            SQLiteDatabase db=this.getContext().openOrCreateDatabase("test_db2.db", Context.MODE_PRIVATE, null);
            db.execSQL("CREATE TABLE t_user (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL)");
            ContentValues values=new ContentValues();
            values.put("name", "liangjh2");
            db.insert("t_user", "id", values);
            db.close();
            return false;
        }
    
        @Override
        public Cursor query(Uri uri, String[] projection, String selection,
                String[] selectionArgs, String sortOrder) {
            // 获取数据
            SQLiteDatabase db=this.getContext().openOrCreateDatabase("test_db2.db", Context.MODE_PRIVATE, null);
            Cursor c = db.query("t_user", null, null, null, null, null, null);
            db.close();
            return c;
        }
    
        @Override
        public int update(Uri uri, ContentValues values, String selection,
                String[] selectionArgs) {
            // TODO Auto-generated method stub
            return 0;
        }
    
    }


    注册ContentProvider
    在AndroidManifest.xml中声明ContentProvider,authorities属性定义了ContentProvider的Uri标识。关于Uri标识属另一个范畴,自行查询。provider标识要放在<application></application>里面。如果遇到了"Permission Denial: opening provide..."的错误,可以试试在节点加“android:exported="true"”。
    <application ...>
        ...
        <provider android:name=".MyProvider" android:authorities="com.example.androidtestdemo" android:exported="true"/>
    </application>

     

    在B程序获取数据
    用Context获取到当前的ContentResolver,根据Uri地址和ContentResolver的query方法获取A程序的数据。Uri地址和A程序中AndroidManifest.xml定义的autorities要一致。当然,同类可以进行其它的操作。
    Context ctx=MainActivity.this;
    ContentResolver resolver =ctx.getContentResolver();
    Uri uri=Uri.parse("content://com.example.androidtestdemo");
    Cursor c = resolver.query(uri, null, null, null, null);
    c.moveToFirst();
    while(!c.isAfterLast()){
        for(int i=0,j=c.getColumnCount();i<j;i++){
            Log.v("Android2",""+c.getString(i));
        }
        c.moveToNext();
    }

    读取收件箱信息:

    private void getMsgs(){
        Uri uri = Uri.parse("content://sms/");
        ContentResolver resolver = getContentResolver();
        //获取的是哪些列的信息
        Cursor cursor = resolver.query(uri, new String[]{"address","date","type","body"}, null, null, null);
        while(cursor.moveToNext())
        {
            String address = cursor.getString(0);
            String date = cursor.getString(1);
            String type = cursor.getString(2);
            String body = cursor.getString(3);
            System.out.println("地址:" + address);
            System.out.println("时间:" + date);
            System.out.println("类型:" + type);
            System.out.println("内容:" + body);
            System.out.println("======================");
        }
        cursor.close();
    }

    往AndroidManifest.xml加入读取收件箱的权限:

    <uses-permission android:name="android.permission.READ_SMS"/>

    往收件箱里插入一条信息

    private void insertMsg() {
        ContentResolver resolver = getContentResolver();
        Uri uri = Uri.parse("content://sms/");
        ContentValues conValues = new ContentValues();
        conValues.put("address", "123456789");
        conValues.put("type", 1);
        conValues.put("date", System.currentTimeMillis());
        conValues.put("body", "no zuo no die why you try!");
        resolver.insert(uri, conValues);
        Log.e("HeHe", "短信插入完毕~");
    }






    • 0
      点赞
    • 1
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

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

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

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值