`
sillycat
  • 浏览: 2578809 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Android UI(3)Getting Started - Saving Data

 
阅读更多
Android UI(3)Getting Started - Saving Data

1. Saving Data
Saving Key-Value Sets
SharedPreferences object points to a file containing key-value pairs and provides simple methods to read and write them.

Get a Handle to a SharedPreferences
getSharedPreferences(key_name,mode) - Multiple shared preference files identified by names, and this is called by Context.

In activity:
Context context = getActivity();
SharedPreferences sharedPref = context.getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE);

getPreferences() - Only one shared preference file for the activity.

SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);

If we create preferences file with MODE_WORLD_READABLE or MODE_WORLD_WRITEABLE, then other apps can access the data.

Write to Shared Preferences
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(getString(R.string.saved_high_score), newHighScore); // getString()
editor.commit();

Read from Shared Preferences
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = getResources().getInteger(R.string.saved_high_score_default);

long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue);

2. Saving Files
Deal with the android file system with the File API. It is good the store the image files or anything exchanged over a network.

Choose Internal or External Storage
“internal” and "external" storage are coming from the old days, when most devices offered built-in non-volatile  memory(internal storage), removable storage medium such as a micro SD card(external storage).

The apps are installed onto the internal storage by default, you can specify the android:installLocation in manifest file.

Obtain Permissions for External Storage
<manifest …>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest>

Right now, apps have the read permission by default to external storage.

And for internal storage, by default, apps have that permissions.

Save a File on Internal Storage
File handler methods:
getFileDir()

getCacheDir()

File file = new File(context.getFilesDir(), filename);

Examples to write a file>
String filename = "myfile";
String hello = "Hello";
FileOutputStream outputStream;
try{
     outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
     outputStream.write(hello.getBytes());
}catch(Exception e){
     e.printStackTrace();
}finally{
     outputStream.close();
}

Save a File on External Storage
public boolean isExternalStorageWritable(){
     String state = Environment.getExternalStorageState();
     if(Evironment.MEDIA_MOUNTED.equals(state)){
          return true;
     }
     return false;
}

/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable(){
     String state = Environment.getExternalStorageState();
     if(Environment.MEDIA_MOUNTED.equals(state) ||
          Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)){
          return true;
     }
     return false;
}

Even all the files stored on external storage can be accessed by other apps. But there are still 2 parts in external, private and public.

public File getAlbumStorageDir(String albumName){
     File file = new File(Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_PICTURES),albumName);
     if(!file.mkdirs()){
          Log.e(LOG_TAG, "Directory not there");
     }
     return file;
}

public File getAlbumStorageDir(Context context, String albumName){
     File file = new File(context.getExternalFilesDir(
               Environment.DIRECTORY_PICTURES), albumName);
     if(!file.mkdirs()){
          Log.e(LOG_TAG, "Directory not there!");
     }
     return file;
}

Query Free Space
getFreeSpace()
getTotalSpace()

Delete a File
myFile.delete()

myContext.deleteFile(fileName);

3. Saving Data in SQL Databases
android.database.sqlite

Define a Schema and Contract
//===========database
public static final String TABLE_NAME = "product";
public static final String COLUMN_NAME_PRODUCT_ID = "product_id";
public static final String COLUMN_NAME_PRODUCT_NAME = "product_name";
public static final String COLUMN_NAME_PRODUCT_PRICE = "product_price";
public static final String COLUMN_NAME_PRODUCT_DESN = "product_desn";
public static final String COLUMN_NAME_PRODUCT_IMAGE_URL = "product_imageurl";

publicstaticfinalStringSQL_CREATE = "CREATE TABLE " + TABLE_NAME + " ( " +
     COLUMN_NAME_PRODUCT_ID + " INTEGER PRIMARY KEY," +
     COLUMN_NAME_PRODUCT_NAME + " TEXT," +
     COLUMN_NAME_PRODUCT_PRICE + " TEXT," +
     COLUMN_NAME_PRODUCT_DESN + " TEXT," +
     COLUMN_NAME_PRODUCT_IMAGE_URL + " TEXT" +
     ");";
public static final String SQL_DROP = "DROP TABLE IF EXISTS " + TABLE_NAME;
//===========database

I defined all these things in my model object.

Create a Database Using a SQL Helper
package com.sillycat.easyrestclientandroid.dao.db;

import com.sillycat.easyrestclientandroid.model.Product;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class BasicDBHelper extends SQLiteOpenHelper {

     public static final int DATABASE_VERSION = 1;

     public static final String DATABASE_NAME = "sillycat.db";

     public BasicDBHelper(Context context) {
          super(context, DATABASE_NAME, null, DATABASE_VERSION);
     }

     public void onCreate(SQLiteDatabase db) {
          db.execSQL(Product.SQL_CREATE);
     }

     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
          db.execSQL(Product.SQL_DROP);
          onCreate(db);
     }
   
}

Put Information into a Database
public class ProductDBDAOImpl implements ProductDAO {
     private BasicDBHelper helper;
     public ProductDBDAOImpl(BasicDBHelper helper) {
          this.helper = helper;
     }
…snip…
public Product insert(Product product) {
     synchronized (DBGuard.class) {
          SQLiteDatabase db = null;
          try {
               db = helper.getWritableDatabase();
               Long id = db.insert(Product.TABLE_NAME,
               Product.COLUMN_NAME_PRODUCT_NAME, getValues(product));
               product.setProductId(id);
          } catch (Exception e) {
               e.printStackTrace();
          } finally {
               if (db != null) {
                    db.close();
               }
          }
          return product;
     }
}


private ContentValues getValues(Product item) {
     ContentValues values = new ContentValues();
     values.put(Product.COLUMN_NAME_PRODUCT_DESN, item.getProductDesn());
     values.put(Product.COLUMN_NAME_PRODUCT_ID, item.getProductId());
     values.put(Product.COLUMN_NAME_PRODUCT_IMAGE_URL,item.getProductImageURL());
     values.put(Product.COLUMN_NAME_PRODUCT_NAME, item.getProductName());
     values.put(Product.COLUMN_NAME_PRODUCT_PRICE, item.getProductPrice());
     return values;
}


…snip…
}

Read Information from a Database
public List<Product> all() {
     List<Product> items = new ArrayList<Product>();
     synchronized (DBGuard.class) {
          SQLiteDatabase db = null;
          Cursor cursor = null;
          try {
               db = helper.getReadableDatabase();
               cursor = db.query(Product.TABLE_NAME, new String[] {
                    Product.COLUMN_NAME_PRODUCT_DESN,
                    Product.COLUMN_NAME_PRODUCT_ID,
                    Product.COLUMN_NAME_PRODUCT_IMAGE_URL,
                    Product.COLUMN_NAME_PRODUCT_NAME,
                    Product.COLUMN_NAME_PRODUCT_PRICE }, null, null, null, null, null);
               if (cursor != null && cursor.getColumnCount() > 0) {
                    cursor.moveToFirst();
                    while (cursor.getPosition() != cursor.getCount()) {
                         items.add(getItem(cursor));
                         cursor.moveToNext();
                    }
               }
          } catch (Exception e) {
               e.printStackTrace();
          } finally {
               if (cursor != null) {
                    cursor.close();
               }
               if (db != null) {
                    db.close();
               }
          }
     }
     return items;
}


private Product getItem(Cursor cursor) {
     Product item = new Product();
     item.setProductDesn(cursor.getString(0));
     item.setProductId(cursor.getLong(1));
     item.setProductImageURL(cursor.getString(2));
     item.setProductName(cursor.getString(3));
     item.setProductPrice(cursor.getString(4));
     return item;
}



Delete Information from a Database
publicboolean deleteById(Long productId) {
     synchronized (DBGuard.class) {
          SQLiteDatabase db = null;
          try {
               db = helper.getReadableDatabase();
               db.delete(Product.TABLE_NAME, "id = ?",
               new String[] { productId + "" });
          } catch (Exception e) {
               e.printStackTrace();
          } finally {
               if (db != null) {
                    db.close();
               }
          }
     }
     return false;
}


Update a Database
public Product update(Product product) {
     Product item = null;
     synchronized (DBGuard.class) {
          SQLiteDatabase db = null;
          try {
               db = helper.getWritableDatabase();
               db.update(Product.TABLE_NAME, getValues(product), "id=?",
               new String[] { "" + product.getProductId() });
          } catch (Exception e) {
               e.printStackTrace();
          } finally {
               if (db != null) {
                    db.close();
               }
          }
     }
     return item;
}



DBGuard is just an empty class that used to lock the synchronized things. I am not sure it is necessary. How can the customer type his mobile devices in that fast? Haha.


References:
http://developer.android.com/training/basics/data-storage/index.html


分享到:
评论

相关推荐

    Professional Android 4 Application Development 源代码

    Chapter 2: Getting Started Developing for Android Developing for Mobile and Embedded Devices Android Development Tools Chapter 3: Creating Applications and Activities What Makes an Android Application...

    iOS 10 Programming for Beginners

    Getting Started with the List Working More with Lists Where Are We? Where's My Data? Foodie Reviews Saving Reviews Universal iMessages Notifications Just a Peek Beta and Store Submission

    HTML5 GAMES Creating Fun with HTML5 CSS3 and WebGL 英文PDF

    - **WebStorage**: Introduced as a method for storing data on the client side, useful for saving game progress or high scores. - **WebGL**: Detailed as a technology for rendering 3D and 2D graphics ...

    python3.6.5参考手册 chm

    Data Instead Of Unicode Vs. 8-bit Overview Of Syntax Changes New Syntax Changed Syntax Removed Syntax Changes Already Present In Python 2.6 Library Changes PEP 3101: A New Approach To String ...

    三菱FX系列PLC与昆仑通态触摸屏在磨床控制中的应用及优化

    内容概要:本文详细介绍了使用三菱FX系列PLC与昆仑通态/三菱GT系列触摸屏进行磨床控制的具体方法和技术细节。主要内容涵盖PLC的梯形图编程,包括脉冲输出控制、急停逻辑、伺服电机控制等;触摸屏的HMI界面设计,涉及砂轮磨损补偿、数值输入框的边界检查、动态效果实现等;以及PLC与触摸屏之间的通讯配置和调试技巧。文中还分享了许多实际操作中的经验和注意事项,如脉冲输出模式的设置、通讯参数的一致性、硬件连接的可靠性等。 适合人群:从事工业自动化控制领域的工程师和技术人员,尤其是对PLC编程和HMI设计有一定基础的人群。 使用场景及目标:适用于中小型加工车间的磨床控制系统的设计与调试。主要目标是提高磨床控制系统的稳定性和精度,减少调试时间和错误发生的可能性。 其他说明:文章不仅提供了具体的编程代码和配置步骤,还分享了许多实际操作中的经验和教训,帮助读者更好地理解和掌握相关技术和技巧。

    邢台市-沙河市--街道行政区划_130582_Shp-wgs84坐标系.rar

    街道级行政区划shp数据,wgs84坐标系,直接下载使用。

    邢台市-内丘县--街道行政区划_130523_Shp-wgs84坐标系.rar

    街道级行政区划shp数据,wgs84坐标系,直接下载使用。

    IEEE Standard for Verilog Hardware Description Language.pdf.wim

    IEEE Standard for Verilog Hardware Description Language.pdf.wim

    晋中市-和顺县-街道行政区划_140723_Shp数据-wgs84坐标系.rar

    晋中市-和顺县-街道行政区划_140723_Shp数据-wgs84坐标系.rar

    FPGA与CY7C68013A实现USB2.0多通道高精度数据采集系统的详细解析

    内容概要:本文深入探讨了基于FPGA(Xilinx Spartan-6)和CY7C68013A的多通道数据采集系统的设计与实现。系统能够支持八路或十六路24位ADC的同时采样,并通过USB2.0接口将数据稳定传输至上位机。文中详细介绍了硬件架构的选择、FPGA内部FIFO设计、USB固件配置以及上位机软件开发等多个方面的关键技术点。特别强调了跨时钟域FIFO设计、端点配置优化、多线程同步读取等技巧对于提高系统性能的重要作用。此外,还分享了许多实际开发过程中遇到的问题及其解决方案,如电磁兼容性处理、时钟漂移补偿、数据包丢失预防等。 适合人群:从事嵌入式系统开发、FPGA编程、USB通信协议研究的专业技术人员,尤其是那些正在探索高效数据采集方案的研发人员。 使用场景及目标:适用于需要进行多通道同步数据采集的应用场合,比如工业自动化检测设备、医疗仪器、环境监测等领域。目标是帮助开发者掌握构建高性能、可靠性的数据采集系统的完整流程和技术要点。 其他说明:作者不仅提供了详细的代码片段作为参考,还分享了很多宝贵的实践经验,有助于读者更好地理解和应用相关技术。

    电力现货价格建模中基于贝叶斯校正与跳变分量的MCMC算法Matlab/C++实现及其应用

    内容概要:本文探讨了利用贝叶斯校正和跳变分量在电力现货价格建模中的应用,特别是通过MCMC算法进行参数估计的方法。文中详细介绍了模型的基本架构,即均值回归过程与多组跳变过程的叠加,并展示了如何通过Matlab和C++-Mex实现这一复杂的模型。模型的核心在于通过数据驱动的方式确定最优跳变分量个数,从而更好地捕捉电力市场价格的尖峰特性。此外,还讨论了模型的实际应用效果以及不同市场之间的差异,强调了贝叶斯框架在极端事件预测方面的优势。 适合人群:从事电力市场研究、金融工程、数据分析的专业人士,尤其是对贝叶斯统计和MCMC算法有一定了解的研究人员和技术开发者。 使用场景及目标:适用于希望提高电力现货价格预测准确性的人群,尤其是在面对频繁波动的市场环境时。通过引入多个带符号的跳变分量,能够更精确地捕捉市场动态,帮助决策者制定更好的风险管理策略。 其他说明:文中提供了详细的代码实现和后验诊断方法,确保模型不仅理论上可行,而且在实践中也能高效运行。特别指出,在不同市场环境下,模型参数会有不同的表现形式,体现了模型的高度灵活性和适应性。

    上市公司环境排放明细(2008-2021年)

    上市公司环境排放明细(2008-2021年)

    信捷XC3 PLC与施耐德ATV12变频器自动化通讯方案及应用

    内容概要:本文详细介绍了信捷XC3 PLC与施耐德ATV12变频器之间的自动化通讯解决方案。主要内容涵盖硬件连接、PLC程序逻辑设计、触摸屏交互以及断电自恢复等功能。首先,硬件方面采用RS485接口进行连接,确保通信稳定。其次,PLC程序分为三个主要部分:上电自检、实时状态轮询和频率设定。通过Modbus协议实现设备间的数据交互,并解决了通讯冲突等问题。此外,触摸屏提供了友好的人机界面,支持频率设定和状态监控。最后,实现了断电自恢复功能,确保设备在意外断电后能够自动恢复正常运行。 适合人群:从事工业自动化领域的工程师和技术人员,特别是熟悉PLC编程和变频器应用的专业人士。 使用场景及目标:适用于需要提高生产设备自动化水平的企业,旨在减少人工干预,提升生产效率和设备可靠性。具体应用场景包括但不限于工厂生产线、自动化控制系统等。 其他说明:文中提供了详细的代码示例和调试技巧,帮助读者更好地理解和实施该方案。同时强调了硬件配置和参数设置的重要性,为实际项目提供宝贵的实践经验。

    120吨双级反渗透与混床系统的S7-200 Smart PLC自动化控制及加药程序详解

    内容概要:本文详细介绍了120吨双级反渗透与混床系统的自动化控制系统及其加药程序。系统采用西门子S7-200 Smart PLC进行控制,涵盖了一键制水、阻垢剂和杀菌剂的自动投加、反渗透膜保护、混床再生控制等功能。文中展示了具体的PLC编程逻辑,如定时器的应用、硬件互锁设计、模拟量处理以及HMI画面设计等。此外,还包括详细的电气图纸和操作维护手册,提供了丰富的实战经验和优化建议。 适合人群:具备一定PLC编程基础的自动化工程师和技术人员。 使用场景及目标:适用于工业水处理领域的自动化控制系统设计与实施,帮助工程师理解和掌握S7-200 Smart PLC的实际应用技巧,提高系统的可靠性和效率。 其他说明:文章不仅提供了完整的程序代码和注释,还分享了许多实战中的踩坑记录和优化建议,对于初学者来说是非常宝贵的学习资源。

    包头市-达尔罕茂明安联合旗-街道行政区划_150223_Shp数据-wgs84坐标系.rar

    包头市-达尔罕茂明安联合旗-街道行政区划_150223_Shp数据-wgs84坐标系.rar

    HCIA-Datacom高阶:vlan、vlanif、单臂路由、静态路由、ospf综合实验

    HCIA-Datacom高阶:vlan、vlanif、单臂路由、静态路由、ospf综合实验

    张家口市-桥东区--街道行政区划_130702_Shp-wgs84坐标系.rar

    街道级行政区划shp数据,wgs84坐标系,直接下载使用。

    LabVIEW测试系统在工业自动化领域的应用与优势解析

    内容概要:本文详细介绍了LabVIEW测试系统在工业自动化领域的应用及其优势。首先,通过具体案例展示了LabVIEW在24小时不间断测试PCBA模块中的高效性和稳定性,特别是在异常处理和数据存储方面的强大功能。其次,文章强调了LabVIEW在硬件交互、PID控制、版本管理和文档生成等方面的优势,如利用DAQmx驱动进行精确的压力控制,以及通过Project Library机制实现无缝版本升级。此外,文中还提到LabVIEW的图形化编程特性使得复杂工程需求能够快速落地,并且提供了丰富的信号处理函数库,适用于各种测试场景。最后,文章讨论了LabVIEW在商用系统中的部署能力和售后服务支持,如快速生成报表和稳定的远程监控功能。 适合人群:从事工业自动化、测试系统开发的工程师和技术人员。 使用场景及目标:① 实现高效的工业自动化测试系统;② 提高测试系统的稳定性和可靠性;③ 加速复杂工程需求的快速落地;④ 提供便捷的版本管理和文档生成工具。 其他说明:尽管LabVIEW的图形化编程对习惯文本编码的工程师有一定学习曲线,但对于大多数标准测试场景而言,其提供的稳定性和易用性使其成为理想的开发工具。

    光伏充电站动态能量调度策略:基于MATLAB的电动汽车充放电优化与光伏利用率提升

    内容概要:本文详细介绍了光伏充电站的能量调度策略及其MATLAB实现。主要内容包括:定义关键变量如光伏出力波动容忍阈值、电价系数等,建立准入控制机制将充电站分为‘饥饿’和‘饱和’两种模式,通过计算每辆车的充放电灵活度进行车辆调度,采用动态定价策略激励车主错峰充电,以及运用凸优化算法求解最优充电方案。最终实现了光伏利用率的显著提高和车主充电体验的优化。 适合人群:对新能源汽车充电站运营、光伏能源管理和智能调度算法感兴趣的工程师和技术人员。 使用场景及目标:适用于希望深入了解并应用光伏充电站能量调度策略的研究人员和从业者。主要目标是在确保车主按时充电的前提下,最大限度地利用光伏发电,减少能源浪费,同时通过动态定价机制平衡供需关系。 其他说明:文中提供了详细的代码片段和图表解释,帮助读者更好地理解和复现该调度策略。此外,还讨论了一些实际应用中的挑战和改进建议,如精确定位车辆停留时间和引入联邦学习更新灵活度模型等。

    基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip

    基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip,个人经导师指导并认可通过的高分设计项目,评审分99分,代码完整确保可以运行,小白也可以亲自搞定,主要针对计算机相关专业的正在做大作业的学生和需要项目实战练习的学习者,可作为毕业设计、课程设计、期末大作业。 基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue3实现的仿小米商城项目源代码+项目详细文档.zip基于Vue

Global site tag (gtag.js) - Google Analytics