SharedPreferences存储+SD卡存储
一.SharedPreferences存储
1.SharedPreferences简介
SharedPreferences简称Sp(后面都会称Sp),是一种轻量级的数据存储方式,采用Key/value的方式 进行映射,最终会在手机的/data/data/package_name/shared_prefs/目录下以xml的格式存在。
但是 请注意:千万不要使用Sp去存储量大的数据,也千万不要去让你的Sp文件超级大,否则会大大影响应用性能, 甚至出现ANR(程序无响应)
通过Key/Value的形式进行数据存储,存取方便
2.写(存)数据
**步骤1:**得到SharedPreferences对象 getSharedPreferences(“文件的名称”,“文件的类型”);
(1).Context.MODE_PRIVATE:指定该SharedPreferences数据只能被应用程序读写
(2)MODE_APPEND:检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
以下不在建议使用
(3).Context.MODE_WORLD_READABLE:指定该SharedPreferences数据能被其他
应用程序读,但不能写。
(4).Context,MODE_WORLD_WRITEABLE:指定该SharedPreferences数据能被其他应用程序写,但不能读。
**步骤2:**得到 SharedPreferences.Editor编辑对象
SharedPreferences.Editor editor=sp.edit();
**步骤3:**添加数据
editor.putBoolean(key,value)
editor.putString()
editor.putInt()
editor.putFloat()
editor.putLong()
**步骤4:**提交数据 editor.commit()或者apply()(推荐用这个.异步提交)
Editor其他方法: editor.clear() 清除数据 editor.remove(key) 移除指定key对应的数据
简单说就是 获取对象 获取编辑者 放入数据 提交
private void write() {
SharedPreferences sp = getSharedPreferences("login", MODE_PRIVATE);
SharedPreferences.Editor edit = sp.edit();
edit.putInt("username", 1051252897);
edit.putString("password", 159753 + "");
edit.commit();
}
3.读(取)数据
步骤1:得到SharedPreferences对象 getSharedPreferences(“文件的名称”,“文件的类型”);
步骤2:读取数据 String msg = sp.getString(key,defValue);
but.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences sp = getSharedPreferences("login", MODE_PRIVATE);
String username = sp.getString("username", "111");
String pass = sp.getString("pass", "qweqweqwe");
Toast.makeText(MainActivity.this, username + "-----" + pass, Toast.LENGTH_SHORT).show();
}
});
完整JAVA代码
public class MainActivity extends AppCompatActivity {
private Button but;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
but = (Button) findViewById(R.id.but);
but.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {//读取
SharedPreferences sp = getSharedPreferences("login", MODE_PRIVATE);
String username = sp.getString("username", "111");
String pass = sp.getString("pass", "qweqweqwe");
Toast.makeText(MainActivity.this, username + "-----" + pass, Toast.LENGTH_SHORT).show();
}
});
}
private void write() {//写入
SharedPreferences sp = getSharedPreferences("login", MODE_PRIVATE);
SharedPreferences.Editor edit = sp.edit();
edit.putInt("username", 1051252897);
edit.putString("password", 159753 + "");
edit.commit();
}
}
4.小案例
实现保存密码功能,可以在下次打开程序时自动填充密码
布局文件
<?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"
android:padding="20dp"
tools:context=".LoginActivity">
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入账号" />
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码"
android:inputType="textPassword" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<CheckBox
android:id="@+id/cb_rem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="记住密码" />
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:text="登陆" />
</LinearLayout>
</LinearLayout>
java代码
其实现原理
就是在第一次登陆时,根据是否选中,保存账号密码,然后记录这次的选中状态,
下次打开程序时,如果保存的状态为true,则取出账号密码,设置到编辑文本上
public class LoginActivity extends AppCompatActivity {
private EditText username;
private EditText password;
private CheckBox cbRem;
private Button btnLogin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initViews();
}
private void initViews() {
username = (EditText) findViewById(R.id.username);
password = (EditText) findViewById(R.id.password);
cbRem = (CheckBox) findViewById(R.id.cb_rem);
btnLogin = (Button) findViewById(R.id.btn_login);
SharedPreferences login = getSharedPreferences("login", MODE_PRIVATE);
//从文件中获取到,上一次复选框是否被点击
boolean isChecked = login.getBoolean("isChecked", false);
String user = login.getString("username", "");
String pass = login.getString("password", "");
final SharedPreferences.Editor edit = login.edit();
if (isChecked) {//如果复选框上一次被点击,则将保存的用户名和密码设置到编辑文本框
username.setText(user);
password.setText(pass);
cbRem.setChecked(isChecked);
}
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (cbRem.isChecked()) {//如果复选框被选中,保存账号和密码以及选中状态
edit.putString("username", username.getText().toString());
edit.putString("password", password.getText().toString());
edit.putBoolean("isChecked", true);
edit.commit();
} else {
edit.remove("username");
edit.remove("password");//删除密码
edit.putBoolean("isChecked", false);
edit.commit();
}
Toast.makeText(LoginActivity.this, username.getText().toString() + "---" + password.getText().toString(), Toast.LENGTH_SHORT).show();
}
});
}
}
效果展示
二.内部文件存储
将文件存储到内部,存储路径是唯一的
写入
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = openFileOutput("aa.json", MODE_PRIVATE);
fileOutputStream.write("hello".getBytes());
fileOutputStream.flush();
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
读取
FileInputStream fileInputStream = null;
try {
fileInputStream= openFileInput("aa.json");
byte[] b = new byte[1024];
int len = 0;
while((len = fileInputStream.read(b)) != -1){
Log.i(TAG, "onClick: "+new String(b,0,len));
}
} catch (Exception e) {
e.printStackTrace();
}
三.SD卡存储
SD卡介绍:
一般手机文件管理 根路径 /storage/emulated/0/或者/mnt/shell/emulated/0
2.重要代码:
(1)Environment.getExternalStorageState();// 判断SD卡是否
(2)Environment.getExternalStorageDirectory(); 获取SD卡的根目录
(3)Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); 获取SD卡公开目录pictures文件夹
3.权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
布局文件
<?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=".MainActivity">
<Button
android:text="写"
android:id="@+id/but_write"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:text="读"
android:id="@+id/but_read"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Activity中的java代码
public class MainActivity extends AppCompatActivity {
private Button butWrite;
private Button butRead;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//请求权限
//第一个:当前版本号 第二个:23 也就是6.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String[] str = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(str, 100);
}
initViews();
}
private void initViews() {
butWrite = (Button) findViewById(R.id.but_write);
butRead = (Button) findViewById(R.id.but_read);
butRead.setOnClickListener(new View.OnClickListener() {//从SD卡读文件
@Override
public void onClick(View v) {
File directory = Environment.getExternalStorageDirectory();
File file = new File(directory, "a.txt");
try {
FileInputStream is = new FileInputStream(file);
int len = 0;
byte[] bys = new byte[1024];
while ((len = is.read(bys)) != -1) {
String s = new String(bys, 0, len);
Toast.makeText(MainActivity.this, "" + s, Toast.LENGTH_SHORT).show();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
butWrite.setOnClickListener(new View.OnClickListener() {//写文件到SD卡
@Override
public void onClick(View v) {
File directory = Environment.getExternalStorageDirectory();
try {
//创建输出流
FileOutputStream os = new FileOutputStream(new File(directory, "a.txt"));
os.write("123456".getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
/**
* @param requestCode 请求码
* @param permissions 权限
* @param grantResults 结果
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//在请求码100 权限获取失败
if (requestCode == 100 && grantResults[0] == PackageManager.PERMISSION_DENIED) {
Toast.makeText(this, "不同意", Toast.LENGTH_SHORT).show();
} else {//权限获取成功
Toast.makeText(this, "同意", Toast.LENGTH_SHORT).show();
}
}
}
记得要动态获取权限
四.SD存储小案例
实现网上下载图片,然后显示到布局中
布局文件
<?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">
<Button
android:text="下载到SD"
android:layout_width="wrap_content"
android:id="@+id/but_Down"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/but_Up"
android:text="从SD中读取"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/img_show"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/ic_launcher" />
</LinearLayout>
Activity的java代码
public class Main2Activity extends AppCompatActivity {
private Button butDown;
private Button butUp;
private ImageView imgShow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initViews();
}
private void initViews() {
butDown = (Button) findViewById(R.id.but_Down);
butUp = (Button) findViewById(R.id.but_Up);
imgShow = (ImageView) findViewById(R.id.img_show);
butDown.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//异步任务下载图片
new MyTask().execute("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1365465540,3598159423&fm=26&gp=0.jpg");
}
});
butUp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
File directory = Environment.getExternalStorageDirectory();//获取SD卡地址
Bitmap bitmap = BitmapFactory.decodeFile(directory + "/b.jpg");//将下载的图片转换成bitmap
imgShow.setImageBitmap(bitmap);//设置
}
});
}
class MyTask extends AsyncTask<String, Void, String> {
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (s != null) {
Toast.makeText(Main2Activity.this, "下载成功", Toast.LENGTH_SHORT).show();
}
}
@Override
protected String doInBackground(String... strings) {
try {
URL url = new URL(strings[0]);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.connect();
File directory = Environment.getExternalStorageDirectory();
if (connection.getResponseCode() == 200) {
InputStream is = connection.getInputStream();
if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED){
FileOutputStream fos = new FileOutputStream(new File(directory, "b.jpg"));
int len = 0;
byte[] bys = new byte[1024];
while ((len = is.read(bys)) != -1) {
fos.write(bys, 0, len);
}
return "ok";
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
}
需要网络权限和读写SD卡的权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
效果展示
要开心加油