350 likes | 656 Views
第四章 Android数据存储与传感器. 课程内容. SQLite 数据存储 私有文件夹、资源和 Assets 读写 Preferece 数据存储 Content Provider 数据存储 传感器应用. SQLite简介. 在 Android 的开发中使用的数据库是 SQLite , 它是一个轻量级的数据库、非常小 、移植性好、效率高、可靠,嵌入式设备因为受到硬件条件的限制所以非常适合使用 SQLite 数据库。. SQLite的基本使用方法. 创建和删除数据库
E N D
课程内容 • SQLite数据存储 • 私有文件夹、资源和Assets读写 • Preferece数据存储 • Content Provider数据存储 • 传感器应用
SQLite简介 • 在Android的开发中使用的数据库是SQLite ,它是一个轻量级的数据库、非常小 、移植性好、效率高、可靠,嵌入式设备因为受到硬件条件的限制所以非常适合使用 SQLite 数据库。
SQLite的基本使用方法 • 创建和删除数据库 封装一个类去继承SQLiteOpenHelper在构造函数中传入数据库名称与数据库版本号,数据库被创建的时候会调用onCreate(SQLiteDatabase db) 方法,数据库版本号发生改变的时候会调用onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)方法,可以方便的对软件升级后做出相应处理避免覆盖安装数据库发生改变产生的错误。调用SQLiteOpenHelper 的getReadableDatabase()方法去创建数据库,如果数据库不存在则创建并且返回SQLiteDatabase对象,如果数据库存在则不创建只返回SQLiteDatabase对象。调用 deleteDatabase(DATABASE_NAME)方法 传入数据库名称则可删除数据库。
表的创建 数据库是可以由多张数据表组成的如果添加一张数据库的表的话可以使用 数据库语句 create table 名称(内容) 来进行添加 。 这里给出一条创建数据库的语句: create table Test(id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT,width INTEGER DEFAULT 100,height INTEGER DEFAULT 200,number INTEGER); 意思是创建一张表 名称为Test的表中包含的字段为 : id为INTEGER 类型并且递增 name为Text类型 width、height为INTEGER 默认数值为100和200 number为INTEGER 类型。
DatabaseHelper类: public class DatabaseHelper extends SQLiteOpenHelper { private static DatabaseHelper mInstance = null; public static final String DATABASE_NAME = "mydatabase.db"; private static final int DATABASE_VERSION = 1; /** 数据库SQL语句 添加一个表 **/ private static final String TABLE_CREATE = "create table Test(" + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "name TEXT," + "width INTEGER DEFAULT 100," + "height INTEGER DEFAULT 200," + "number INTEGER);"; DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); }
static synchronized DatabaseHelper getInstance(Context context) { if (mInstance == null) { mInstance = new DatabaseHelper(context); } return mInstance; } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(TABLE_CREATE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } public boolean deleteDatabase(Context context) { return context.deleteDatabase(DATABASE_NAME); }
DatabaseActivity类: public class DatabaseActivity extends Activity { private static final String NAME = "name"; private static final String TABLE_NAME = "Test"; private static final String ID = "id"; DatabaseHelper DbHelper = null; SQLiteDatabase Db = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 创建DatabaseHelper对象 DbHelper = DatabaseHelper.getInstance(this); // 调用getReadableDatabase方法如果数据库不存在 则创建 如果存在则打开 Db = DbHelper.getReadableDatabase(); Toast.makeText(this, "成功创建数据库", Toast.LENGTH_LONG).show(); for(int i=0; i<10; i++) { insert(NAME,"数据名称" + i); } //下面为按钮监听方法
数据的增删改查 代码中写了四个方法对应数据的增删改查操作: insert() delete() update() query() 具体见代码
public void insert(String key, String date) { ContentValues values = new ContentValues(); values.put(key, date); Db.insert(TABLE_NAME, null, values); } public void delete(String key, String date) { Db.delete(TABLE_NAME, key + "=?", new String[] { date }); }
public void update(String key, String oldDate, String newDate) { ContentValues values = new ContentValues(); values.put(key, newDate); Db.update(TABLE_NAME, values, key + "=?", new String[] { oldDate }); } public Cursor find(String key, String date) { Cursor cursor = Db.query(TABLE_NAME, null, key + "=?", new String[] { date }, null, null, null); if (cursor != null) { cursor.moveToFirst(); } return cursor; }
Android数据存储的主要方式 1.SharedPreferences 使用SharedPreferences处理数据的新建、储存、读取、删除SharedPreferences保存后生成的是XML文件,内容是以节点的形式保存在文件中,同时,SharedPreferences类提供了非常丰富的处理数据的方法,但是不适合存储大量的数据。因此,一般使用它来保存用户的一些设置,如:游戏进度,声音设置,解锁物品等等。 2.在私有文件夹下自定义创建文件 在本地私有文件夹下使用自己生成的文件处理数据的新建 储存、读取、删除如果不想把内容存在SharedPreferences中,我们可以自己写一个文件保存需要的数据,在这里我将文件保存在系统中的工程路径下。这样做虽然可以提高数据保存的自由度,但是,我们因此就需要自己写代码来解析这个文件,以取得自己需要的信息。
3、在工程的raw目录下创建、读写文件 Android 下提供了专门读取程序res/raw路径下资源的方法,但是没有提供写入raw内容的方法,也就是说只能读不能写,在做软件的时候有时须要读取大量的文字资源,由于这些资源文字在软件中不会改变所以无需去对它的内容修改,就可以使用raw来操作数据。 4、在SD卡中创建、读写文件 我们还可以把数据保存在SD卡中,在SD卡中建立一个文件去保存数据。但是注意,SD卡 用户是可以访问的,也就是说只应该把一些可有可无的数据存在SD卡中,这样,即使用户删除了卡中的内容也不会影响软件的使用。
Android中文件读取和存储的方式 Android平台支持Java平台下的文件I/O操作,主要使 用FileInputStream和FileOutputStream这两个类 来实现文件的读取和存储,获取这两个类对象的方式有 以下两种: 1.通过构造函数直接创建 2.调用Context.openFileOutput和Context.openFileInput 方法来创建 除了上述两个方法外,Context对象还提供了其他几个用于对文件进行 操作的方法(见书p64)
在使用openFileOutput方法打开文件以写入数据时, 需要指定打开模式,默认为MODE_PRIVATE,其他见 书P64-表4-2 例1.Android中几种主要数据存储方式的简单实现
SharedPreferences 声明 • /** 使用SharedPreferences 来储存与读取数据 **/ • SharedPreferences mShared = null; • /** 程序中可以同时存在多个SharedPreferences数据, 根据SharedPreferences的名称就可以拿到对象 **/ • public final static String SHARED_MAIN = "main"; • /** SharedPreferences中储存数据的Key名称 **/ • public final static String KEY_NAME = "name"; • public final static String KEY_NUMBER = "number"; • /** SharedPreferences中储存数据的路径 **/ • public final static String DATA_URL = "/data/data/"; • public final static String SHARED_MAIN_XML = "main.xml";
SharedPreferences实现过程 • /** 拿到名称是SHARED_MAIN 的SharedPreferences对象 **/ • mShared = getSharedPreferences(SHARED_MAIN, Context.MODE_PRIVATE); • /** 拿到SharedPreferences中保存的数值 第二个参数为如果SharedPreferences中没有保存就赋一个默认值 **/ • String name = mShared.getString(KEY_NAME, "姓名为空"); • String number = mShared.getString(KEY_NUMBER, "号码为空"); • /** 开始保存入SharedPreferences **/ • Editor editor = mShared.edit(); • editor.putString(KEY_NAME, name); • editor.putString(KEY_NUMBER, number); • /** put完必须要commit()否则无法保存 **/ • editor.commit();
在私有文件夹下自定义创建文件 • public final static String FILE_NAME = "Date.txt"; • /** File中储存数据的路径 **/ • public final static String DATA_URL = "/data/data/";
读取文件内容 • FileInputStream inStream = this.openFileInput(FILE_NAME); • ByteArrayOutputStream stream = new ByteArrayOutputStream(); • byte[] buffer = new byte[1024]; • int length = -1; • while ((length = inStream.read(buffer)) != -1) • { • stream.write(buffer, 0, length); • } • stream.close(); • inStream.close();
写入文件 • FileOutputStream outStream = this.openFileOutput(FILE_NAME, • Context.MODE_WORLD_READABLE); • outStream.write(str.getBytes()); • outStream.close();
在工程的raw目录下读文件 • in = this.getResources().openRawResource(ID); • byte[] buff = new byte[1024];// 缓存 • in.read(buff); • temp = EncodingUtils.getString(buff, "UTF-8"); • in.close(); • 在Assets目录文件读 • AssetManager assetManager = getAssets(); • inputStream = assetManager.open("mytext.txt"); • ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); • byte[] bytes = new byte[4096]; • int len = 0; • while ((len = inputStream.read(bytes)) > 0) • byteStream.write(bytes, 0, len); • return new String(byteStream.toByteArray(), "UTF8");
SD卡文件读 • String path = Environment.getExternalStorageDirectory() + "/" • + FILE_NAME; • FileInputStream fi = new FileInputStream(path); • BufferedReader br = new BufferedReader(new InputStreamReader(fi)); • String readString = new String(); • while ((readString = br.readLine()) != null) • { • // 数据多的话须要在这里处理 readString • return readString; • } • fi.close();
SD卡文件写 • FileOutputStream fileOutputStream = null; • File file = new File(Environment.getExternalStorageDirectory(), • FILE_NAME); • fileOutputStream = new FileOutputStream(file); • fileOutputStream.write(str.getBytes()); • fileOutputStream.close(); • SD卡权限 • <!-- SDCard中创建与删除文件权限 --> • <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> • <!-- SDCard写入数据权限 --> • <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
ContentProvider 在Android中,ContentProvider是数据对外的接 口,程序通过ContentProvider访问数据而不需要关 心数据具体的存储及访问过程,这样既提高了数据的 访问效率,同时也保护了数据。Activity类中有一个 继承自ContentWapper的getContentResolver()无 参数方法,该方法返回一个ContentResolver对象, 通过调用其query、insert、update、delete方法访 问数据。这几个方法的第一个参数均为URI型,用来 标识资源。
Android的ContentProvider URI有固定的形式: content : //contract / people 前缀:固定为content : // 认证:contract 资源的唯一标识符 路径:people 具体的资源类型
ContentProvider 如何向外界提供数据? Android提供了ContentProvider,一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据完全暴露出去,而且ContentProviders是以类似数据库中表的方式将数据暴露,也就是说ContentProvider就像一个“数据库”。那么外界获取其提供的数据,也就应该与从数据库中获取数据的操作基本一样,只不过是采用URI来表示外界需要访问的“数据库”。至于如何从URI中识别出外界需要的是哪个“数据库”,这就是Android底层需要做的事情了。ContentProvider向外界提供数据操作的接口: query(Uri, String[], String, String[], String) insert(Uri, ContentValues) update(Uri, ContentValues, String, String[]) delete(Uri, String, String[])
ContentProvider 如何组织数据? 组织数据主要包括:存储数据,读取数据,以数据库 的方式暴露数据。数据的存储需要根据设计的需求, 选择合适的存储结构,首选数据库,当然也可以选择 本地其他文件,甚至可以是网络上的数据。数据的读 取,以数据库的方式暴露数据这就要求,无论数据是 如何存储的,数据最后必须以数据的方式访问。
如何创建ContentProvider? 可通过2种方法:创建一个属于你自己的 ContentProvider或者将你的数据添加到一个已经存 在的ContentProvider中,当然前提是有相同数据类 型并且有写入Content provider的权限。 实现方法: 1.实现一个ContentProvider的子类,并实现其重载 方法 2.在AndroidManifest.xml中添加Provider的声明 (见书中例子)
Android平台下传感器应用的开发 Android支持许多的传感器,而正是因为目前的手机都内置了许多传感器,使我们的游戏开发不再只是单纯的按键操作。下面我们来看一下Android支持的传感器都有哪些: 加速度传感器(accelerometer) 陀螺仪传感器(gyroscope) 环境光照传感器(light) 磁力传感器(magnetic field) 方向传感器(orientation) 压力传感器(pressure) 距离传感器(proximity) 温度传感器(temperature)
使用传感器的一般步骤: 1.SensorMannager传感器管理对象 手机中的所有传感器都须要通过SensorMannager来访问,调用getSystemService (SENSOR_SERVICE)方法就可以拿到当前手机的传感器管理对象。 2.实现SensorEventListener接口 通过实现SensorEventListener这个接口 onSensorChanged (SensorEvent event)方法我们可以捕获手机传感器的状态,拿到手机 X轴Y轴Z轴三个方向的重力分量 3.注册SensorEventListener使用SensorMannager调用getDefaultSensor( )方法拿到相应传感器的Sensor对象,最后,使用SensorMannager调用registerListener()方法来注册传感器。
传感器应用传感器对象和注册 /**得到SensorManager对象**/ mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); mSensor = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); • // 注册listener,第三个参数是检测的精确度 • //SENSOR_DELAY_FASTEST 最灵敏 因为太快了没必要 • //SENSOR_DELAY_GAME 游戏开发中使用 • //SENSOR_DELAY_NORMAL 正常速度 • //SENSOR_DELAY_UI 最慢的速度 mSensorMgr.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME);
实现SensorEventListener接口 • public void onSensorChanged(SensorEvent event) { • mGX = event.values[SensorManager.DATA_X]; • mGY= event.values[SensorManager.DATA_Y]; • mGZ = event.values[SensorManager.DATA_Z]; • ….
在游戏开发中,我们最常使用到的传感器是加速度计(Accelerometer),也就是通常我们说的重力感应。下面我们通过一个小例子,来熟悉一下传感器的使用方法吧;在游戏开发中,我们最常使用到的传感器是加速度计(Accelerometer),也就是通常我们说的重力感应。下面我们通过一个小例子,来熟悉一下传感器的使用方法吧;