前4种为本地数据存储方式
一、SharedPreferences 1、特点:存储量小,时间持久
MainActivity
参考资料:Intent相关知识
package com.example.storagestudy;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void operate(View v){
Intent it=null;
switch (v.getId()){
case R.id.share_btn:
it = new Intent(this,ShareActivity.class);
break;
case R.id.external_btn:
it = new Intent(this,ExternalActivity.class);
break;
default:
it = new Intent(this,InternalActivity.class);
break;
}
startActivity(it);
}
}
效果图:
activity_share.xml
ShareActivity(存储信息)
四步:
①获取SharePreference对象(参数1:文件名,参数2:操作模式)
SharedPreferences share = getSharedPreferences("myshare", MODE_PRIVATE);
②获取Editor对象
SharedPreferences.Editor edt = share.edit();
③存储信息(把输入框的内容以key–value存储进去)
edt.putString("account", account); edt.putString("pwd", pwd);
④执行提交操作
edt.commit();
package com.example.storagestudy;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class ShareActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_share);
final EditText accEdt=(EditText)findViewById(R.id.acc_edt);
final EditText pwdEdt=(EditText)findViewById(R.id.pwd_edt);
findViewById(R.id.login_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//1、获取两个输入框(账号、密码输入框)的内容
String account=accEdt.getText().toString();
String pwd=pwdEdt.getText().toString();
//2、验证(admin 123算成功)
if(account.equals("admin")&&pwd.equals("123")){
//2.1、存储信息到SharePreference中
//①获取SharePreference对象(参数1:文件名【本质上是一个xml文件】,参数2:操作模式)
SharedPreferences share=getSharedPreferences("myshare",MODE_PRIVATE);
//②获取Editor对象
SharedPreferences.Editor edt=share.edit();
//③存储信息(把输入框的内容以key--value存储进去)
edt.putString("account",account);
edt.putString("pwd",pwd);
//④执行提交操作
edt.commit();
Toast.makeText(ShareActivity.this,"登录成功",Toast.LENGTH_SHORT).show();
}else{
//2.2、验证失败,提示用户(账号或密码错误等等)
Toast.makeText(ShareActivity.this,"账号或密码错误",Toast.LENGTH_SHORT).show();
}
}
});
}
}
效果图:
登录失败,不会生成;登录成功,检查到没有,会自行创建一个myshare.xml:
打开Device File Explorer --> data --> data --> 当前包名com.example.storagestudy --> 生成shared_prefs:myshare.xml
myshare.xml
ShareActivity(添加读取信息相关代码)
读取信息:下一次再进入此界面时,能出现已经配置好的信息(账号、密码)
三步
①获取SharePreference对象(参数1:,参数2:操作模式)因为myshare文件已经被创建了,所以在这里会直接打开
SharedPreferences share = getSharedPreferences("myshare", MODE_PRIVATE);
②根据key获取内容(参数1:key,参数2:当对应key不存在时,返回参数2的内容作为默认值)
String accStr = share.getString("account", ""); String pwdStr = share.getString("pwd", "");
③将上面读取出来的内容设置到相应的文本显示框
accEdt.setText(accStr); pwdEdt.setText(pwdStr);
package com.example.storagestudy;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class ShareActivity extends AppCompatActivity {
//后续会使用到这两个控件,故提取为全局变量
private EditText accEdt;
private EditText pwdEdt;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_share);
// 初始化控件
accEdt = (EditText) findViewById(R.id.acc_edt);
pwdEdt = (EditText) findViewById(R.id.pwd_edt);
//2.1、存储信息到SharePreference中
//①获取SharePreference对象(参数1:文件名【本质上是一个xml文件】,参数2:操作模式)因为myshare文件已经被创建了,所以在这里会直接打开
SharedPreferences share = getSharedPreferences("myshare", MODE_PRIVATE);
//②根据key获取内容(参数1:key,参数2:当对应key不存在时,返回参数2的内容作为默认值)
String accStr = share.getString("account", "");
String pwdStr = share.getString("pwd", "");
//将上面读取出来的内容设置到相应的文本显示框
accEdt.setText(accStr);
pwdEdt.setText(pwdStr);
findViewById(R.id.login_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
... ...
}
}
});
}
}
效果图:
再点进去时,出现之前配置好的信息(账号、密码)
将之前存储的信息全部清空
edt.clear();
二、 外部存储ExternalStorage
1、 概念
区分:
内存:设备的容量
内部存储:设备中一个实际存在的位置
外部存储:设备中一个比较特殊的位置,由于手机不同,位置也不一样,可能在storage/sdcard或者mnt/xxxx/0下
外部存储:
1、外部存储的位置可使用
Environment.getExternalStorageDirectory().getAbsolutePath()
获得
2、9大公有目录,以作用来命名(DCIM:存储照片,DOWNLOAD:下载文件,直接存储在外部存储的根目录下,需要申请权限
3、私有目录,Android/data/应用包名,只能被当前应用访问到
注意:
①在实际开发中不建议在内部存储中存储数据,因为容量很有限
②在实际开发中经常讲把数据存储到私有目录,便于系统维护,软件卸载了数据就删除了
2、 具体操作activity_external.xml
外部存储要申请权限
写入的权限,创建和删除文件的权限
AndroidManifest.xml
android.permission.MOUNT_UNMOUNT_FILESYSTEMS添加权限报错的两种解决方案
ExternalActivity(写入外部存储文件)写入步骤
1、创建文件输出流(参数1:传入文件目录,参数2:表示是否可以追加内容)
FileOutputStream fos = new FileOutputStream(path, true);
2、获取输入框的内容
String str = infoEdt.getText().toString();
3、以字节流的方式写入内容(输入框的内容)
fos.write(str.getBytes());
4、关闭流
fos.close();
文件所在路径:
String path= Environment.getExternalStorageDirectory().getAbsolutePath()+"/imooc.txt";
Log.d(TAG, path);
具体代码:
02-22 15:17:59.304 7048-7048/com.example.storagestudy D/ExternalActivity: /storage/sdcard/imooc.txt
package com.example.storagestudy;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class ExternalActivity extends AppCompatActivity {
private static final String TAG = "ExternalActivity";
private EditText infoEdt;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_external);
infoEdt = (EditText) findViewById(R.id.info_edt);
TextView txt = (TextView) findViewById(R.id.textView);
}
public void operate(View view) {
//Environment.getExternalStorageDirectory():拿到根目录
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/imooc.txt";
Log.d(TAG, "operate: " + path);
//equals的话,内存卡存在
// if (Environment.getExternalStorageState().equals("mounted"))
switch (view.getId()) {
case R.id.save_btn:
//创建一个文件
File file = new File(path);
try {
//如果不存在,创建一个新的
if (!file.exists()) {
file.createNewFile();
}
//有文件了,往里面输出内容
//创建文件输出流(参数1:传入文件目录,参数2:表示是否可以追加内容)
FileOutputStream fos = new FileOutputStream(path, true);
//获取输入框的内容
String str = infoEdt.getText().toString();
//以字节流的方式写入内容(输入框的内容)
fos.write(str.getBytes());
//关闭流
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
case R.id.read_btn:
break;
}
}
}
效果图:
在文件目录下生成了imooc.txt文件
注意:模拟器只能输英文、数字和符号
其中内容为:
hello,imooc
安卓权限代表意思
ExternalActivity(读取外部存储文件)读取步骤
1、创建文件输入流
FileInputStream fis = new FileInputStream(path);
2、创建字节数组
byte[] b = new byte[1024];
3、读取输入流内容(读取的内容存储在字节数组中),返回读取到的长度
int len= fis.read(b);
4、利用保存读取内容的字节数组,生成字符串
String str2=new String(b,0,len);
5、将内容显示在文本显示框(读文件是不需要申请权限的)
txt.setText(str2);
6、关闭流
fis.close();
public class ExternalActivity extends AppCompatActivity {
... ...
public void operate(View view) {
... ...
switch (view.getId()) {
... ...
case R.id.read_btn:
try {
//创建文件输入流
FileInputStream fis = new FileInputStream(path);
//创建字节数组
byte[] b = new byte[1024];
//读取输入流内容(读取的内容存储在字节数组中),返回读取到的长度
int len= fis.read(b);
//利用保存读取内容的字节数组,生成字符串
String str2=new String(b,0,len);
//将内容显示在文本显示框(读文件是不需要申请权限的)
txt.setText(str2);
//关闭流
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
}
效果图:
注意:android6.0以上,需要动态申请权限。
方法一:手动打开外部存储权限。设置 --> 应用 --> 权限打开,即可
方法二:
InternalActivity(写入内部存储文件)
不需要写入权限
写入步骤:
1、创建文件输出流(参数:传入文件目录) 不追加,直接用新的内容覆盖老的内容
FileOutputStream fos=new FileOutputStream(file);
2、获取输入框的内容,转化为String类型,然后以字节流的方式写入内容
fos.write(edt.getText().toString().getBytes());
3、关闭输出流对象
fos.close();
具体代码:
package com.example.storagestudy;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import org.w3c.dom.Text;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class InternalActivity extends AppCompatActivity {
private EditText edt;
private TextView txt;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_internal);
//初始化控件
edt = (EditText)findViewById(R.id.editText);
txt = (TextView)findViewById(R.id.textView);
}
public void operate(View view) {
//新建一个文件
File file=new File(getFilesDir(),"getFilesDir.txt");
switch (view.getId()){
case R.id.save_btn:
try{
//若文件不存在,则创建一个新的文件
if(!file.exists()){
file.createNewFile();
}
//创建文件输出流(参数1:传入文件目录) 不追加,直接用新的内容覆盖老的内容
FileOutputStream fos=new FileOutputStream(file);
//获取输入框的内容,转化为String类型,然后以字节流的方式写入内容
fos.write(edt.getText().toString().getBytes());
//关闭流
fos.close();
}
catch (IOException e) {
e.printStackTrace();
}
break;
case R.id.read_btn:
break;
}
}
}
data --> data --> 该包名com.example.storage --> files --> 生成普通文件getFileDir.txt
getFileDir.txt文件内容: