Android数据存储详解

目录:
    1.概述
    2.SQLite
        2.1 概述:
        2.2 数据类型+存储位置
        2.3 数据操作及其相关方法
        2.4 代码示例      
    3.SharePreferences
        3.1 概述
        3.2 操作模式+存储位置
        3.4 代码示例               
    4.File
        4.1 概述
        4.2 操作模式+存储位置
        4.3 手机内存+sdcard保存 
    5.Content provider   
    6.网络存储
    
1.概述
    数据存储在App开发和使用中是必不可少的,比如我们会从网络中保存图片、视频等到本地,同时我们的应用在用户使用过程中会
对用户的行为做一些记录,以此达到增加用户体验的效果,至于保存哪些用户数据需要由需求而定。
    当然我们数据存储的方式也不止一种,在android平台下包含:SQLite,SharePreferences,File,Content provider,网络存储等5种
存储方式,至于选用哪一种存储方式比较合理,就需要我们在实际开发中综合考虑,当然,我们在后面也会对每一种存储方式适合存储
什么样的数据做一些简单的概述。

2.SQLite
    2.1 概述:
        SQLite属于轻型嵌入式关系型数据库,占用资源比较低,应用场景主要在存储一些需要具备一些保密性,数据量比较大,同时
逻辑关系比较复杂的数据,比如:在天气应用中记录用户时区与位置,在闹钟应用中存储一些用户定义任务等等。

    2.2 数据类型+存储位置
        (1)数据类型:NULL,INTEGER(整型),TEXT(字符串文本),REAL(浮点型),BLOB(二进制型)
        (2)默认存储位置:/data/data/<packageName>/databases
        
    2.3 数据操作及其相关方法
        (1) 对于数据库的操作位于android.database.sqlite包下,主要的类有:SQLiteOpenHelper(数据库帮助类)和SQLiteDatabase(数据库
    类),SQLiteOpenHelper类主要用户数据库创建于版本管理。而SQLiteDatabase类当然主要用于数据库的常规操作(增删改查)和数据库的维护
        
        (2) SQLiteOpenHelper常用方法
        
    /*构造方法参数:
    *   1.Context:上下文
    *   2.name:需要创建的数据库名
    *   3.SQLiteDatabase.CursorFactory:提供创建Cursor对象,默认为null
    *   4.version:数据库版本
    *   5.errorHandler:数据库中断时的错误报告处理,null,为默认处理方式
    * */
    public MySqliteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {}

    public MySqliteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {}

    //返回链接的数据库名
    public String getDatabaseName() {}

    //调用时间:在数据库需要onDowngrade的时候调用与onUpgrade类似
    //方法在事务中执行,如果出现异常,数据会回滚
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
 
    //数据库已经被打开的时候调用
    public void onOpen(SQLiteDatabase db) {}

    //在数据库链接正在配置是调用,用于开启也些相关配置
    public void onConfigure(SQLiteDatabase db) {}
    
    //关闭数据库链接
    public synchronized void close() {}
    
    //获取一个可读的数据库对象
    public SQLiteDatabase getReadableDatabase() {}
    
    //获取一个可读写的数据库对象
    public SQLiteDatabase getWritableDatabase() {}
    
    //数据库第一次创建时调用
    public void onCreate(SQLiteDatabase db) {}
    
    //调用时间:在数据库需要更新的时候调用
    //方法在事务中执行,如果出现异常,数据会回滚                
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}

   
        (3) SQLiteDatabase常用方法
        
    数据库操作型方法:
        //创建数据库,该数据库在关闭之后数据将消失
        public static SQLiteDatabase create(CursorFactory factory) {}
        
        //打开或者创建指定文件路径的数据库
        public static SQLiteDatabase openOrCreateDatabase(File file, CursorFactory factory) {}
        
        //打开指定文件路径的数据库
        public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) {}
        
        //删除指定路径的数据库
        public static boolean deleteDatabase(File file) {}
      
    数据表与数据处理型方法:
    
        //执行sql语句,可实现增删改查,与表的创建,删除
        public void execSQL(String sql, Object[] bindArgs) throws SQLException {}
        public void execSQL(String sql) throws SQLException {}
        
        //删除指定数据
        public int delete(String table, String whereClause, String[] whereArgs) {}
        
        //查询数据
         public Cursor query(boolean distinct, String table, String[] columns,
            String selection, String[] selectionArgs, String groupBy,
            String having, String orderBy, String limit) {}
            
        //执行已定义的sql语句,返回结果Cursor
        public Cursor rawQuery(String sql, String[] selectionArgs) {}
        
        //插入数据
        public long insert(String table, String nullColumnHack, ContentValues values) {}
        
        //更新数据
         public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {}
  
    事务处理型方法:    
        //表示事务执行成功
        public void setTransactionSuccessful() {}
        //结束某个事务
        public void endTransaction() {}
        //开启事务
        private void beginTransaction(){}
          
    2.4 代码示例
(1) MySqliteOpenHelper.java
package com.example.database;

import android.content.Context;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

/**
 * Created by elimy on 2016-09-03.
 */
public class MySqliteOpenHelper extends SQLiteOpenHelper {
    private final String DEBUG ="DEBUG";

    //如果数据库名和版本固定,不需要改变可以如下设置,调用时只需要传入上下文即可
    private static final String DEFULT_DB_NAME ="first.db";
    private static final int DEFULT_VERSION = 1;
    public MySqliteOpenHelper(Context context) {
        super(context, DEFULT_DB_NAME, null, DEFULT_VERSION);
    }

    /*构造方法参数:
    *   1.Context:上下文
    *   2.name:需要创建的数据库名
    *   3.SQLiteDatabase.CursorFactory:提供创建Cursor对象,默认为null
    *   4.version:数据库版本
    *   5.errorHandler:数据库中断时的错误报告处理,null,为默认处理方式
    * */
    public MySqliteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {
        super(context, name, factory, version, errorHandler);
    }

    public MySqliteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    /*
    * 作用:返回链接的数据库名
    * */
    @Override
    public String getDatabaseName() {
        return super.getDatabaseName();
    }

    /*
    *调用时间:在数据库需要onDowngrade的时候调用与onUpgrade类似
    * 方法在事务中执行,如果出现异常,数据会回滚
    * */
    @Override
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.d(DEBUG,"onDowngrade()");
        super.onDowngrade(db, oldVersion, newVersion);
    }
    /*
    *调用时间:数据库已经被打开的时候调用
    * */
    @Override
    public void onOpen(SQLiteDatabase db) {
        Log.d(DEBUG,"onOpen()");
        super.onOpen(db);
    }

    /*
    *在数据库链接正在配置是调用,用于开启也些相关配置
    * */
    @Override
    public void onConfigure(SQLiteDatabase db) {
        Log.d(DEBUG,"onConfigure()");
        super.onConfigure(db);
    }
    /*
    *关闭数据库链接
    * */
    @Override
    public synchronized void close() {
        Log.d(DEBUG,"close()");
        super.close();
    }
    /*
    * 获取一个可读的数据库对象
    * */
    @Override
    public SQLiteDatabase getReadableDatabase() {
        Log.d(DEBUG,"getReadableDatabase()");
        return super.getReadableDatabase();
    }
    /*
    * 获取一个可读写的数据库对象
    * */
    @Override
    public SQLiteDatabase getWritableDatabase() {
        Log.d(DEBUG,"getWritableDatabase()");
        return super.getWritableDatabase();
    }
    /*
    * 数据库第一次创建时调用
    * */
    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建数据表users
        db.execSQL("create table users(" +
                "u_id INTEGER primary key autoincrement," +
                "u_name TEXT," +
                "u_password TEXT," +
                "u_sex TEXT," +
                "u_age INTEGER)");
        Log.d(DEBUG,"onCreate()");
    }
    /*
    *调用时间:在数据库需要更新的时候调用
    * 方法在事务中执行,如果出现异常,数据会回滚
    * */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.d(DEBUG,"onUpgrade()");
    }
}

(2) SqliteActivity.java
package com.example.database;

import android.content.ContentValues;
import android.content.DialogInterface;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class SqliteActivity extends AppCompatActivity implements View.OnClickListener {
    private Button add,update,delete,select;
    private MySqliteOpenHelper helper;
    private SQLiteDatabase db;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sqlite);
        //初始化数据
        add = (Button) findViewById(R.id.add);
        update = (Button) findViewById(R.id.update);
        select = (Button) findViewById(R.id.select);
        delete = (Button) findViewById(R.id.delete);
        //注册监听器
        add.setOnClickListener(this);
        update.setOnClickListener(this);
        select.setOnClickListener(this);
        delete.setOnClickListener(this);

        //通过MySqliteOpenHelper的带一个参数构造函数,初始化helper对象
        helper = new MySqliteOpenHelper(SqliteActivity.this);
    }

    public  void insertData(){
        //开启一个可写的数据库对象
        db = helper.getWritableDatabase();
        //插入数据集(键值对)初始化
        ContentValues values = new ContentValues();
        values.put("u_name","Elimy");
        values.put("u_password","456");
        values.put("u_sex","男");
        values.put("u_age",26);
        //插入数据
        //table:表名, nullColumnHack:如果可为空的字段未赋值则设置为空,
        // ContentValues:数据集
        long back = db.insert("users",null,values);
        if (back !=-1){
            Toast.makeText(SqliteActivity.this,"添加成功",Toast.LENGTH_SHORT).show();
            Log.d("add","添加成功");
        }else {
            Log.d("add","添加失败");
        }
        //释放数据库连接对象
        db.close();
    }
    /*
    * 更新数据
    * */
    public  void updateData(){
        //开启一个可写的数据库对象
        db = helper.getWritableDatabase();
        //插入数据集(键值对)初始化
        ContentValues values = new ContentValues();
        values.put("u_name","Andy");
        values.put("u_password","789");
        values.put("u_sex","女");
        values.put("u_age",26);
        //更新数据
        long back = db.update("users",values,"u_id=?",new String[]{"1"});
        if (back !=0){
            Toast.makeText(SqliteActivity.this,"修改成功",Toast.LENGTH_SHORT).show();
            Log.d("update","修改成功");
        }else {
            Log.d("update","修改失败");
        }
        //释放数据库连接对象
        db.close();
    }
    /*
    * 查询数据
    * */
    public  void selectData(){
        //开启一个可写的数据库对象
        db = helper.getReadableDatabase();
        //查询
        Cursor cursor = db.query("users",new String[]{"u_name","u_password","u_sex","u_age"},null,null,null,null,null);
        while (cursor.moveToNext()){
            Log.d("users",cursor.getString(cursor.getColumnIndex("u_name"))+"+"+cursor.getString(cursor.getColumnIndex("u_password"))+"+"+cursor.getString(cursor.getColumnIndex("u_sex"))+"+"+cursor.getString(cursor.getColumnIndex("u_age")));
        }
        //释放数据库连接对象
        db.close();
    }
    /*
    * 删除数据
    * */
    public  void deleteData(){
        //开启一个可写的数据库对象
        db = helper.getWritableDatabase();
        //删除数据
        int back = db.delete("users","u_id=?",new String[]{"1"});
        if (back == 0){
            Log.d("delete","删除失败");
        }else {
            Log.d("delete","删除成功");
        }
        //释放数据库连接对象
        db.close();
    }
    /*
    * 点击事件监听方法
    * */
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.add :
                insertData();
                break;
            case R.id.update:
                updateData();
                break;
            case R.id.select:
                selectData();
                break;
            case R.id.delete:
                deleteData();
                break;
            default:
                break;
        }
    }
}

(3) activity_sqlite.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context="com.example.database.SqliteActivity">

    <Button
        android:id="@+id/add"
        android:text="插入数据"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/update"
        android:layout_below="@+id/add"
        android:text="修改数据"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/select"
        android:text="查询数据"
        android:layout_below="@+id/update"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/delete"
        android:text="删除数据"
        android:layout_below="@+id/select"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>

(4) 操作和相应的Log打印(ps:之前添加过一条)
添加数据:
    09-03 08:39:37.976 9594-9594/? D/DEBUG: getWritableDatabase()
    09-03 08:39:37.980 9594-9594/? D/DEBUG: onConfigure()
    09-03 08:39:37.980 9594-9594/? D/DEBUG: onOpen()
    09-03 08:39:37.992 9594-9594/? D/add: 添加成功

修改数据:
    09-03 08:40:45.972 9594-9594/? D/DEBUG: getWritableDatabase()
    09-03 08:40:45.972 9594-9594/? D/DEBUG: onConfigure()
    09-03 08:40:45.972 9594-9594/? D/DEBUG: onOpen()
    09-03 08:40:45.980 9594-9594/? D/update: 修改成功

查询数据:
    09-03 08:42:22.672 9594-9594/? D/DEBUG: getReadableDatabase()
    09-03 08:42:22.676 9594-9594/? D/DEBUG: onConfigure()
    09-03 08:42:22.676 9594-9594/? D/DEBUG: onOpen()
    09-03 08:42:22.676 9594-9594/? D/users: Andy+789+女+26
    09-03 08:42:22.676 9594-9594/? D/users: Elimy+456+男+26

删除数据+查询数据:
    09-03 08:43:17.040 9594-9594/? D/DEBUG: getWritableDatabase()
    09-03 08:43:17.040 9594-9594/? D/DEBUG: onConfigure()
    09-03 08:43:17.044 9594-9594/? D/DEBUG: onOpen()
    09-03 08:43:17.052 9594-9594/? D/delete: 删除成功
    09-03 08:43:23.084 416-565/system_process W/ThrottleService: unable to find stats for iface rmnet0
    09-03 08:43:23.496 9594-9594/? D/DEBUG: getReadableDatabase()
    09-03 08:43:23.496 9594-9594/? D/DEBUG: onConfigure()
    09-03 08:43:23.496 9594-9594/? D/DEBUG: onOpen()
    09-03 08:43:23.496 9594-9594/? D/users: Elimy+456+男+26

3.SharePreferences
    3.1 概述
        SharePreferences是一种轻量级的存储数据方式,以xml键值对的形式存储数据,应用场景主要是存储应用的配置信息
        
    3.2 操作模式+存储位置
        (1)操作模式:
            MODE_PRIVATE:文件仅应用程序自己能访问。

            MODE_WORLD_READABLE:文件除了自己访问外还可以被其它应该程序读取(推荐使用Content provider)

            MODE_WORLD_WRITEABLE:文件除了自己访问外还可以被其它应该程序读取和写入(推荐使用Content provider)
            
            MODE_APPEND:在文件尾部追加
            
        (2)默认存储位置:/data/data/<packageName>/shared_prefs
    
    3.4 代码示例(实现登陆功能,将用户名、密码以及是否保存密码数据保存到SharePreferences文件中,当然实际开发为了账户安全
需慎重使用)

(1) MainActivity.java
package com.example.sharepreferences;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private EditText edit_userNmae,edit_password;
    private Button cancel,login,read;
    private CheckBox save;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化控件
        edit_userNmae = (EditText) findViewById(R.id.editText_name);
        edit_password = (EditText) findViewById(R.id.editText_pas);
        cancel = (Button) findViewById(R.id.cancel);
        login = (Button) findViewById(R.id.login);
        save = (CheckBox) findViewById(R.id.check);
        read = (Button) findViewById(R.id.read);
        //注册监听
        cancel.setOnClickListener(this);
        login.setOnClickListener(this);
        read.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.cancel:
                Toast.makeText(MainActivity.this,"取消登录",Toast.LENGTH_SHORT).show();
                break;
            case R.id.login:
                //获取用户输入数据
                String user_name = edit_userNmae.getText().toString().trim();
                String password = edit_password.getText().toString().trim();
                Boolean isSavePas = save.isChecked();
                //创建SharedPreferences对象,默认以应用程序包名为文件名
                // SharedPreferences preferences = getPreferences(MODE_PRIVATE);
                SharedPreferences preferences = getSharedPreferences("info",this.MODE_PRIVATE);
                //PreferenceManager实例化,默认以应用程序包名为文件名
                //SharedPreferences preferences2 = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
                //获取编辑类实例
                SharedPreferences.Editor editor = preferences.edit();
                //put数据
                editor.putString("username",user_name);
                editor.putString("password",password);
                editor.putBoolean("isSavePas",isSavePas);
                //提交事务
                editor.commit();
                break;
            case R.id.read:
                //声明并初始化SharedPreferences
                SharedPreferences backPreferences = getSharedPreferences("info",this.MODE_PRIVATE);
                //获取preference中的数据
                String backName = backPreferences.getString("username","");
                String backPassword = backPreferences.getString("password","");
                Boolean backChecked = backPreferences.getBoolean("isSavePas",false);
                //打印显示
                Log.d("back",backName+"+"+backPassword+"+"+backChecked);
                break;
            default:
                break;
        }
    }
}

(2) activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context="com.example.sharepreferences.MainActivity">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="登陆"
        android:layout_centerHorizontal="true"
        android:id="@+id/title"
        android:layout_alignParentTop="true" />
<RelativeLayout
    android:id="@+id/edit_layout"
    android:layout_marginTop="10dp"
    android:layout_below="@+id/title"
    android:layout_centerHorizontal="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_alignBaseline="@+id/editText_name"
        android:text="用户名:"
        android:id="@+id/user_name"

        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="密码:"
        android:layout_alignBaseline="@+id/editText_pas"
        android:id="@+id/password"
        android:layout_below="@+id/user_name"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:hint="请输入用户名"
        android:ems="10"
        android:id="@+id/editText_name"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/user_name"
        android:layout_toEndOf="@+id/user_name" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="textPassword"
        android:ems="10"
        android:layout_alignLeft="@+id/editText_name"
        android:layout_toRightOf="@+id/password"
        android:id="@+id/editText_pas"
        android:layout_below="@+id/editText_name"
        android:layout_centerHorizontal="true" />
    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="保存密码"
        android:id="@+id/check"
        android:layout_below="@+id/password"
        android:checked="false" />
</RelativeLayout>
    <RelativeLayout
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:layout_below="@+id/edit_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/relativeLayout">

    </RelativeLayout>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登陆"
        android:id="@+id/login"
        android:layout_below="@+id/relativeLayout"
        android:layout_toRightOf="@+id/title"
        android:layout_alignRight="@+id/edit_layout"
        android:layout_alignEnd="@+id/edit_layout" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="取消"
        android:id="@+id/cancel"
        android:layout_alignTop="@+id/relativeLayout"
        android:layout_alignLeft="@+id/edit_layout"
        android:layout_alignStart="@+id/edit_layout"
        android:layout_toStartOf="@+id/title"
        android:layout_toLeftOf="@+id/title" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="读取数据"
        android:id="@+id/read"
        android:layout_below="@+id/cancel"
        android:layout_marginTop="50dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />


</RelativeLayout>

(3) 效果截图


(4) Log打印(点击登陆,再点击读取数据)
    09-03 13:21:30.503 3745-3745/com.example.sharepreferences D/back: elimy+456+true
  
(5) DDMS查看手机文件截图
     
    
4.File
    4.1 概述
        File文件存储,在android应用做,我们除了一些简单的数据和关系型数据需要通过Sharepreference和sqlite存储以外,通常
还有大数据型文件存储的需求,比如文本文件、图片文件、视频文件等,这时候File文件存储就比较符合需求,当然默认存储位置在手机
内存中,由于内存有限,大多数情况会有存储到sdcard的需求。
    
    4.2 操作模式+存储位置
            MODE_PRIVATE:文件仅应用程序自己能访问(默认)。

            MODE_WORLD_READABLE:文件除了自己访问外还可以被其它应该程序读取(推荐使用Content provider)

            MODE_WORLD_WRITEABLE:文件除了自己访问外还可以被其它应该程序读取和写入(推荐使用Content provider)
            
            MODE_APPEND:在文件尾部追加
            
        (2)默认存储位置:/data/data/<packageName>/files
        
    4.3 手机内存+sdcard保存文件
    
(1)MainActivity.java
package com.example.file;

import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private EditText editTitle,editContent;
    private Button savePhone,saveSD;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化控件
        editTitle = (EditText) findViewById(R.id.edit_title);
        editContent = (EditText) findViewById(R.id.edit_content);
        savePhone = (Button) findViewById(R.id.phone_save);
        saveSD = (Button) findViewById(R.id.sdcard_save);
        //注册监听
        savePhone.setOnClickListener(this);
        saveSD.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        //获取用户输入数据
        String title = editTitle.getText().toString().trim();
        String content = editContent.getText().toString().trim();
        switch (v.getId()){
            case R.id.phone_save:
                if (title != null && content!= null){
                    try {
                        //通过文件输出流写入文件到手机内存
                        //声明并初始化FileOutputStream
                        //参数:
                        //    name:文件名
                        //    mode:操作模式
                        FileOutputStream fos =this.openFileOutput("test.txt", Context.MODE_APPEND);
                        //写入title
                        fos.write(title.getBytes());
                        //写入换行符
                        fos.write("\n".getBytes());
                        //写入coontent
                        fos.write(content.getBytes());
                        //关闭文件流
                        fos.close();
                        Toast.makeText(MainActivity.this,"保存到手机默认地址成功!",Toast.LENGTH_SHORT).show();
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }else {
                    Toast.makeText(MainActivity.this,"请填写内容再保存!",Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.sdcard_save:
                if (title !=null && content!= null){
                       //判断sdcard是否挂载
                        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
                          //获取sdcard根目录
                            File sdcard_dir = Environment.getExternalStorageDirectory();
                            Log.d("sdcard_dir",sdcard_dir.toString());
                            //实例化saveFile
                            File saveFile = new File(sdcard_dir,"test.txt");

                            try {
                                //实例化指向目的文件位置的FileOutputStream
                                FileOutputStream fos=new FileOutputStream(saveFile,true);
                                //写入内容
                                fos.write(title.getBytes());
                                fos.write("\n".getBytes());
                                fos.write(content.getBytes());
                                //关闭文件流
                                fos.close();
                                Toast.makeText(MainActivity.this,"保存sdcard成功!",Toast.LENGTH_SHORT).show();
                            } catch (FileNotFoundException e) {
                                e.printStackTrace();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                }else {
                    Toast.makeText(MainActivity.this,"请填写内容再保存!",Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                break;
        }
    }
}

(2)布局activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context="com.example.file.MainActivity">



    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="标题:"
        android:id="@+id/title"
        android:layout_alignBaseline="@+id/edit_title"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />
    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/edit_title"
        android:hint="请输入标题"
        android:layout_toRightOf="@+id/title"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />

<RelativeLayout
    android:layout_marginTop="20dp"
    android:layout_below="@+id/title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/Content_Layout">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="内容:"
        android:layout_alignBaseline="@+id/edit_content"
        android:id="@+id/content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />
    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="textMultiLine"
        android:ems="10"
        android:hint="请输入内容"
        android:id="@+id/edit_content"
        android:layout_toRightOf="@+id/content"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />
</RelativeLayout>
<LinearLayout
    android:layout_marginTop="80dp"
    android:layout_below="@+id/Content_Layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <Button
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:text="保存到手机"
        android:id="@+id/phone_save" />

    <Button
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:text="保存到sdcard"
        android:id="@+id/sdcard_save" />

</LinearLayout>


</RelativeLayout>

(3)访问sdcard需要注册权限
    <!--写文件到sdcard权限-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!--在sdcard创建和删除文件的权限-->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

(4))手机内存和sdcard保存文件效果图+验证截图

                                        (1)布局效果图                                                                                                         (2)sdcard验证保存成功截图


                                          (3) 手机内存查看验证截图


5.Content provider
    Content provider也被封为四大组件之一,是一种应用之间提供数据共享的机制,其实他的存储方式也是通过数据库或者其他存储
方式实现的,他只是提供一个供外界访问的接口,方便外界访问而已。之前我写过一篇关于Content provider的文章,这里就不做总结了,需要的伙伴可以看看,比较基础。
http://blog.csdn.net/qq_28057577/article/details/51454326

6.网络存储
    所谓的网络存储也就是通过网络请求获取数据,后面在网络部分进行学习,在此暂时就不学习了。

推荐文章:http://www.cnblogs.com/hanyonglu/archive/2012/03/01/2374894.html
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值