SharedPreferences存储+SD卡存储
SharedPreferences存储
特点
1、保存少量的数据,且这些数据的格式非常简单。 存储5种原始数据类型: boolean, float, int, long, String
2、比如应用程序的各种配置信息(如是否打开音效、是否使用震动效果、小游戏的玩家积分等),记住密码功能,音乐播放器播放模式。
写数据
//写数据
//参数一 xml文件的名字 参数二 模式 MODE_PRIVATE 指定该SharedPreferences数据只能被本应用程序读写
SharedPreferences preferences = getSharedPreferences("login", MODE_PRIVATE);
//获取编辑对象
SharedPreferences.Editor edit = preferences.edit();
//写入数据的内容
edit.putInt("age", 18);
edit.putString("name", "科比");
edit.putBoolean("isMan", true);
edit.putFloat("price", 17.1f);
edit.putLong("id", 1234567);
//提交数据
edit.commit();
在执行完上面这段代码后系统会在data文件夹下自动生成文件
文件的内容也会自动创建
读数据
步骤1:得到SharedPreferences对象 getSharedPreferences(“文件的名称”,“文件的类型”);
步骤2:读取数据 String msg = sp.getString(key,defValue);
//读数据
btnRead.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences login = getSharedPreferences("login", MODE_PRIVATE);
String username = login.getString("name", "科比");
Toast.makeText(MainActivity.this, ""+username, Toast.LENGTH_SHORT).show();
}
});
案例(记住用户登录信息)
效果展示:
xml布局代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Main2Activity">
<LinearLayout
android:padding="8dp"
android:layout_margin="5dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="用户名:"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/et_username"
android:background="@drawable/border"
android:paddingLeft="5dp"
android:hint="请输入用户名"
android:layout_width="match_parent"
android:layout_height="50dp" />
</LinearLayout>
<LinearLayout
android:padding="8dp"
android:layout_margin="5dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="密 码:"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/et_password"
android:background="@drawable/border"
android:paddingLeft="5dp"
android:hint="请输入密码"
android:layout_width="match_parent"
android:layout_height="50dp" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CheckBox
android:id="@+id/cb_rem"
android:layout_marginLeft="70dp"
android:text="记住用户"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn_login"
android:layout_marginLeft="40dp"
android:text="登录"
android:layout_width="195dp"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
java代码:
public class Main2Activity extends AppCompatActivity {
private EditText etUsername;
private EditText etPassword;
private CheckBox cbRem;
private Button btnLogin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initViews();
//用户第二次登录
SharedPreferences welcome = getSharedPreferences("welcome", MODE_PRIVATE);
//判断是否记住
boolean isCk = welcome.getBoolean("isCk", false);
if (isCk){
String username = welcome.getString("username", "");
String password = welcome.getString("password", "");
etUsername.setText(username);
etPassword.setText(password);
cbRem.setChecked(true);
}
//登录点击事件
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//判断多选框选中状态
if (cbRem.isChecked()){
String username = etUsername.getText().toString();
String password = etPassword.getText().toString();
//存入sp
SharedPreferences welcome = getSharedPreferences("welcome", MODE_PRIVATE);
SharedPreferences.Editor edit = welcome.edit();
edit.putString("username",username);
edit.putString("password",password);
//中间值,复选框是否被选中
edit.putBoolean("isCk",true);
edit.commit();
}
}
});
}
private void initViews() {
etUsername = (EditText) findViewById(R.id.et_username);
etPassword = (EditText) findViewById(R.id.et_password);
cbRem = (CheckBox) findViewById(R.id.cb_rem);
btnLogin = (Button) findViewById(R.id.btn_login);
}
}
外部文件存储(SD卡)
重要代码
(1)Environment.getExternalStorageState(); 判断SD卡是否
(2)Environment.getExternalStorageDirectory(); 获取SD卡的根目录
(3)Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); 获取SD卡公开目录pictures文件夹
读写权限
必须在清单文件中添加读写权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
为了更好的用户体验,6.0及之后的版本需要动态添加读写权限
//运行时权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//添加权限
String[] strings = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
//参数一:添加的权限数组,参数二:请求码
requestPermissions(strings, 100);
}
我们可以去查看用户是否授权
//用户是否授权
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 100 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "确定", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "取消", Toast.LENGTH_SHORT).show();
}
}
接下来补全代码,测试效果
xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Main3Activity">
<Button
android:id="@+id/btn_write"
android:text="Write"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn_read"
android:text="Read"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
java:
public class Main3Activity extends AppCompatActivity {
private Button btnWrite;
private Button btnRead;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
btnRead = (Button) findViewById(R.id.btn_read);
btnWrite = (Button) findViewById(R.id.btn_write);
//运行时权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String[] strings = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(strings, 100);
}
//读取SD卡数据
btnRead.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获取SD卡的根路径
File file = Environment.getExternalStorageDirectory();
FileInputStream fis = null;
StringBuffer stringBuffer = new StringBuffer();
try {
fis = new FileInputStream(new File(file,"a.txt"));
byte[] bytes = new byte[1024];
int len = 0;
while ((len = fis.read(bytes))!=-1){
stringBuffer.append(new String(bytes,0,len));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//吐司从SD卡中读取到的信息
Toast.makeText(Main3Activity.this, ""+stringBuffer, Toast.LENGTH_SHORT).show();
}
});
//写入SD卡数据
btnWrite.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获取SD卡的根路径
File file = Environment.getExternalStorageDirectory();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File(file, "a.txt"));
fos.write("这是信息".getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
});
}
//用户是否授权
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 100 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "确定", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "取消", Toast.LENGTH_SHORT).show();
}
}
}
案例(从网络下载图片保存到SD卡,再读取到页面)
xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Main4Activity">
<Button
android:id="@+id/btn_load"
android:text="下载图片"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn_set"
android:text="设置图片"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/iv_pic"
android:src="@mipmap/ic_launcher_round"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
java:
public class Main4Activity extends AppCompatActivity {
private Button btnLoad;
private Button btnSet;
private ImageView ivPic;
private String picUrl = "http://www.qubaobei.com/ios/cf/uploadfile/132/9/8289.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
btnLoad = (Button) findViewById(R.id.btn_load);
btnSet = (Button) findViewById(R.id.btn_set);
ivPic = (ImageView) findViewById(R.id.iv_pic);
//从网络上下载图片存储到SD卡中
btnLoad.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//开启网络下载的异步任务
new MyTask().execute(picUrl);
}
});
//从文件中读取图片
btnSet.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
File file = Environment.getExternalStorageDirectory();
Bitmap bitmap = BitmapFactory.decodeFile(new File(file, "a.jpg").getAbsolutePath());
ivPic.setImageBitmap(bitmap);
}
});
}
class MyTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... strings) {
//写数据的流
FileOutputStream fos = null;
//读数据的流
InputStream is = null;
//向SD卡写的输入流
HttpURLConnection connection = null;
try {
URL url = new URL(strings[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
//判断响应码是否为200
if (connection.getResponseCode() == 200) {
is = connection.getInputStream();
//判断SD卡是否挂载
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
//获取SD卡路径
File file = Environment.getExternalStorageDirectory();
fos = new FileOutputStream(new File(file, "a.jpg"));
byte[] bytes = new byte[1024];
int len = 0;
while ((len = is.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭流
if (is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection!=null){
connection.disconnect();
}
}
return null;
}
}
}