Android进阶:android本地数据操作—步骤2:Android本地文件操作

本地数据存储

Android常用数据存储

  • 1. SharedPreferences存储数据
  • 2. 文件存储(内部,外部)
  • 3. SQLite数据库存储
  • 4. ContentProvider存储数据
  • 5. 网络存储数据

一、SharedPreferences存储数据 

SharedPreferences

•用于存放一些类似登录的配置信息
• 本质上是一个xml文件,是通过类似键值对的方式存放信息
• 位于程序私有目录中,即data/data/[packageName]/shared_prefs

 特点:
* (1)以键值对的形式保存到data/data/应用程序包名/shared_prefs目录的XXX.xml文件中
* (2)目前支持的数据类型有String int float boolean long
* (3)不支持自定义的Object
* (4)通常用来存储App上的用户配置信息.如:是否震动,是否打开背景音乐 小游戏积分 用户账号密码信息

 

SharedPreferences操作模式

  • MODE_APPEND: 追加方式存储

  • MODE_PRIVATE: 私有方式存储,其他应用无法访问

  • MODE_WORLD_READABLE: 可被其他应用读取

  •  MODE_WORLD_WRITEABLE:可被其他应用写入

案例实现:

存储信息到sharedPreference中

SharedPreferences share = getSharedPreferences("myshare", MODE_PRIVATE);
                    //2.获取Editor对象
                    SharedPreferences.Editor editor = share.edit();
                    //3.存储信息
                    editor.putString("account", accountStr);
                    editor.putString("pwd", pwdStr);
                    //4.指定提交操作
                    editor.commit();

读取SharedPreference中的信息

  /**
         * 自动读取SharedPreference的数据
         */
        //1获取Sharedpreference对象
        SharedPreferences share=getSharedPreferences("myshare",MODE_PRIVATE);
        //2根据key获取内容(参数1:key,参数2:当对应key不存在时返回参数2 的内容作为默认值)
        String accStr=share.getString("account","");
        String pwdStr=share.getString("pwd","");
        //让控件显示sharedpreference的信息
        account.setText(accStr);
        pwd.setText(pwdStr);

完整案例:

public class ShareActivity extends AppCompatActivity  {

    private EditText account;
    private EditText pwd;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_share);
        account = findViewById(R.id.account);
        pwd = findViewById(R.id.pwd);
        /**
         * 自动读取SharedPreference的数据
         */
        //1获取Sharedpreference对象
        SharedPreferences share=getSharedPreferences("myshare",MODE_PRIVATE);
        //2根据key获取内容(参数1:key,参数2:当对应key不存在时返回参数2 的内容作为默认值)
        String accStr=share.getString("account","");
        String pwdStr=share.getString("pwd","");
        //让控件显示sharedpreference的信息
        account.setText(accStr);
        pwd.setText(pwdStr);
        /**
         * 存储数据到sharedpreference
         */
        findViewById(R.id.login_bt).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //1获取两个输入框的内容
                String accountStr=account.getText().toString();
                String pwdStr=pwd.getText().toString();
                //2.验证
                   //2.1验证成功,存储信息到sharepreference
                   //1.获取sharedpreference对象(参数1:文件名称,参数2:操作模式)
                if(accountStr.equals("admin")&&pwdStr.equals("123")) {
                    SharedPreferences share = getSharedPreferences("myshare", MODE_PRIVATE);
                    //2.获取Editor对象
                    SharedPreferences.Editor editor = share.edit();
                    //3.存储信息
                    editor.putString("account", accountStr);
                    editor.putString("pwd", pwdStr);
                    //4.指定提交操作
                    editor.commit();
                    Toast.makeText(ShareActivity.this, "验证成功", Toast.LENGTH_SHORT).show();
                }
                   //2.2验证失败,提示用户
                else
                Toast.makeText(ShareActivity.this,"验证失败",Toast.LENGTH_SHORT).show();

            }
        });
    }

}

 位于程序私有目录中,即data/data/[packageName]/shared_prefs/myshare.xml

外部存储ExternalStorage

内存:设备实际的容量

内部存储:文件存储在内部存储中,只能被该应用使用如:SharedPreference

* Internal Storage特点:
* 1.内部存储总是可用的
* 2.内部存储的文件默认只能被当前应用程序访问,它是私有的
* 3.如果App卸载,内部存储文件也会被删除
* 4.如果文件只提供给当前的应用程序访问,那么放到内部存储中比较合适
* 5.内部存储器的读取速度最快且内部存储空间十分珍贵,开发中需要合理使用
*

外部存储ExternalStorage的特点

* 1.外部存储不见得总是可用的: 例如:SD卡被移除了
* 2.外部存储是全局可见的,存放到外部存储中的文件可以被当前设备中所有能够操作该文件的app访问
* 3.为了更好的管理外部存储,Android系统进行了更细致的划分:公共的外部存储和私有的外部存储,当app卸载的时候
* 公共的外部存储中的文件不会被删除,私有外部存储的文件会被删除
* 4.如果你当前文件需要分享给其它的app访问或者使用,文件需要长久保存,文件比较大,或者文件的安全性不做具体要求时,可以考虑使用外部存储

  •  storage或者mnt文件夹
  •  Environment.getExternalStorageDirectory() //获取外部存储的文件目录
  •  公有目录(DCIM、DOWNLOAD等)//可以被其他应用访问
  •  私有目录(Android/data/应用包名)//随应用卸载而卸载

外部存储的动态权限(android6.0后要动态请求权限)

一、读写文件的时候要获取权限

1.在AndroidManifest.xml中声明权限

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET"/>

2.android6.0之后要在动态申请权限

    //android6.0之后要动态获取权限
    private void checkPermission(Activity activity) {
        // Storage Permissions
        final int REQUEST_EXTERNAL_STORAGE = 1;
        String[] PERMISSIONS_STORAGE = {
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE};

        try {
            //检测是否有写的权限
            int permission = ActivityCompat.checkSelfPermission(DownLoadActivity.this,
                    "android.permission.WRITE_EXTERNAL_STORAGE");
            if (permission != PackageManager.PERMISSION_GRANTED) {
                // 没有写的权限,去申请写的权限,会弹出对话框
                ActivityCompat.requestPermissions(DownLoadActivity.this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

• ContextCompat.checkSelfPermission(context,permission)
• ActivityCompat.requestPermissions(activity,permissions,code)

案例:

public class ExternalActivity extends AppCompatActivity {

    private EditText infoEdit;
    private TextView txt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_external);
        infoEdit = findViewById(R.id.info_Edit);
        txt = findViewById(R.id.show_txt);
        //动态添加权限
        checkPermission(this);
    }
    //操作方法
    public void operate(View v) {
        //判断内存卡是否存在
        if (Environment.getExternalStorageState().equals("mounted")) {
            //获取外部存储的的绝对路径
            String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/text.txt";
            //查看一下路径
            Log.e("TAG", path);
            switch (v.getId()) {
                //保存内容
                case R.id.save_btn:
                    //新建text.txt文件
                    File file = new File(path);
                    //如果文件不存在,则创建
                    try {
                        if (!file.exists()) {
                            file.createNewFile();
                        }
                        //创建文件输入流写入数据
                        //参数1:文件路径,参数2:可以拼接
                        FileOutputStream fos = new FileOutputStream(path, true);
                        String str = infoEdit.getText().toString();
                        //以字节流的方式写进去
                        fos.write(str.getBytes());
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
                    //读取内容
                case R.id.read_btn:
                    //文件输入流读取数据
                    try {
                        FileInputStream fis=new FileInputStream(path);
                        byte[] b=new byte[1024];
                        //返回实际读取长度
                        int len=fis.read(b);
                        //利用字节数组生成字符串
                        String str=new String(b,0,len);
                        //显示在文本框上
                        txt.setText(str);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
            }

        }
    }
    //android6.0之后要动态获取权限
    private void checkPermission(Activity activity) {
        // Storage Permissions
        final int REQUEST_EXTERNAL_STORAGE = 1;
        String[] PERMISSIONS_STORAGE = {
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE};

        try {
            //检测是否有写的权限
            int permission = ActivityCompat.checkSelfPermission(ExternalActivity.this,
                    "android.permission.WRITE_EXTERNAL_STORAGE");
            if (permission != PackageManager.PERMISSION_GRANTED) {
                // 没有写的权限,去申请写的权限,会弹出对话框
                ActivityCompat.requestPermissions(ExternalActivity.this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

存储路径: /storage/emulated/0/text.txt 

 获取外部存储的目录(私有目录)

好处

  • 应用被卸载后,这两个目录的内容也会被清除掉
  • 不需要任何权限就可以操作

• Context.getExternalFilesDir(String type);//需要长时间保存的数据

String type是Environment下的文件类型
获取到 SDCard/Android/data/包名/files/ 目录

• Context.getExternalCacheDir();//临时保存的数据
获取到 SDCard/Android/data/包名/cache/目录

内部存储InternalStorage

  • 内部存储,简称为内存
  • 通过DDMS-->File Explorer可以找到,文件夹叫做data
  • 内存中有两个文件夹:app,data
  1. app:应用的apk文件存放位置
  2. data:应用包名的文件夹

* Internal Storage特点:

* 1.内部存储总是可用的
* 2.内部存储的文件默认只能被当前应用程序访问,它是私有的
* 3.如果App卸载,内部存储文件也会被删除
* 4.如果文件只提供给当前的应用程序访问,那么放到内部存储中比较合适
* 5.内部存储器的读取速度最快且内部存储空间十分珍贵,开发中需要合理使用
*

获取内部存储的目录(不需要设置权限就可以读写操作)

• Context.getFilesDir() 获取/data/data/包名/files (files:放的是普通数据)

• Context.getCacheDir() 获取/data/data/包名/cache(cache:放的是缓存数据)

与上面外部存储的操作除了路径不一样几乎一样的操作

不需要权限

//操作方法
    public void operate(View v) {
            String path = InternalActivity.this.getFilesDir().getPath()+"/text.txt";
            //查看一下路径
            Log.e("TAG", path);
            switch (v.getId()) {
                //保存内容
                case R.id.save_btn:
                    //新建text.txt文件
                    File file = new File(path);
                    //等价File file = new File(getFilesDir(),"text.txt");
                    //如果文件不存在,则创建
                    try {
                        if (!file.exists()) {
                            file.createNewFile();
                        }
                        //创建文件输入流写入数据
                        //参数1:文件路径,参数2:可以拼接
                        FileOutputStream fos = new FileOutputStream(path, true);
                        String str = infoEdit.getText().toString();
                        //以字节流的方式写进去
                        fos.write(str.getBytes());
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
                //读取内容
                case R.id.read_btn:
                    //文件输入流读取数据
                    try {
                        FileInputStream fis=new FileInputStream(path);
                        byte[] b=new byte[1024];
                        //返回实际读取长度
                        int len=fis.read(b);
                        //利用字节数组生成字符串
                        String str=new String(b,0,len);
                        //显示在文本框上
                        txt.setText(str);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
            }

        }

FileNotFound异常解决方案

1. 检查下错误提示中的路径是否存在

2. 检查权限是否处理正确
3. 确认设备是否有SDCard

DDMS中data、SDCard目录无法展开

1. 模拟器需要更改只读权限,有的真机data目录需要root

2. Environment.getExternalStorageDirectory()的获取目 录才是SDCard的实际目录,因为系统不同路径会有差异

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值