Android中的sdcard是一个外部存储目录,是一个应用程序的私有目录,只有当前应用程序有权限访问读写,其他应用无权限访问。一般用来存放一些安全性不高,但比较大的数据。
使用Sdcard注意事项:
1.权限问题:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2.通过 Environment获取sdcard的路径:
Environment.getExternalStorageDirectory().getPath();
3.使用前需要判断sdcard状态:
if(!Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)){
//sdcard状态是没有挂载的情况
Toast.makeText(mContext, "sdcard不存在或未挂载", Toast.LENGTH_SHORT).show();
return ;
}
4.需要判断sdcard剩余空间:
File sdcard_file = Environment.getExternalStorageDirectory(); //获得sdcard目录对象
long usableSpace = sdcard_file.getUsableSpace(); //获取该目录下可用空间的大小
//将long类型的文件大小格式转换为M或G
String usableSpaceSize = Formatter.formatFileSize(this, usableSpace);
//假如下载一个电影需要100M,用户手机不足100M,则提示用户
if (usableSpace < 100*1024*1024) {
Toast.makeText(mContext, "sdcard剩余空间不足,剩余空间为:usableSpaceSize", 0).show();
return;
}
5.下面通过模拟一个登录页面,并实现保存用户名和密码的小案例,来详细介绍sdcard存储数据的过程:
①布局文件代码:
<span style="font-size:18px;"><LinearLayout 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=".MainActivity"
android:orientation="vertical" >
<EditText
android:id="@+id/et_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入用户名"/>
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:inputType="textPassword"
android:hint="请输入密码"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CheckBox
android:id="@+id/cb_rem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="记住密码"/>
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="登 录"/>
</RelativeLayout>
</LinearLayout></span>
<span style="font-size:18px;">package com.example.savedatatosd;
import java.io.File;
import java.util.Map;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
private EditText et_password;
private EditText et_username;
private CheckBox cb_rem;
private Button btn_login;
private Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
//初始化控件
et_password = (EditText) findViewById(R.id.et_password);
et_username = (EditText) findViewById(R.id.et_username);
cb_rem = (CheckBox) findViewById(R.id.cb_rem);
btn_login = (Button) findViewById(R.id.btn_login);
//给登录按钮设置监听事件
btn_login.setOnClickListener(this);
//再次进入应用时,先判断用户是否点击了保存按钮,如果保存的话,则回显出保存的内容
Map<String, String> userInfo = UserInfoUtils.getUserInfo();
if (userInfo != null) { //用户信息不为空,则说明保存了信息
et_username.setText(userInfo.get("username"));
et_password.setText(userInfo.get("password"));
//设置按钮为选择状态
cb_rem.setChecked(true);
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_login:
//获取用户输入的内容
String password = et_password.getText().toString().trim();
String username = et_username.getText().toString().trim();
//记录CheckBox的选中状态
boolean isChecked = cb_rem.isChecked();
//1,判空
if (TextUtils.isEmpty(password) || TextUtils.isEmpty(username)) {
Toast.makeText(mContext, "用户名密码不能为空", 0).show();
return;
}
//2,判断可用空间是否满足存储数据
File sdcard_file = Environment.getExternalStorageDirectory(); //获得sdcard目录对象
long usableSpace = sdcard_file.getUsableSpace(); //获取该目录下可用空间的大小
//将long类型的文件大小格式转换为M或G
String usableSpaceSize = Formatter.formatFileSize(this, usableSpace);
//假如下载一个电影需要100M,用户手机不足100M,则提示用户
if (usableSpace < 100*1024*1024) {
Toast.makeText(mContext, "sdcard剩余空间不足,剩余空间为:usableSpaceSize", 0).show();
return;
}
//如果上面的两个条件都满足,则执行下面的代码
//如果CheckBox被选中,则保存用户信息
if (isChecked) {
//因为要保存到sdcard上,所以先判断sdcard是否挂载了
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
//如果sdcard每个挂载,则提示用户
Toast.makeText(mContext, "sdcard没有挂载或不可用", 0).show();
}
boolean result = UserInfoUtils.saveUserInfo(username, password);
if (result) {
Toast.makeText(mContext, "用户名密码保存成功", 0).show();
}else {
Toast.makeText(mContext, "用户名密码保存失败", 0).show();
}
}
break;
}
}
}</span>
③实现往sdcard中存、取数据的工具类:
<span style="font-size:18px;">package com.example.savedatatosd;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import android.os.Environment;
public class UserInfoUtils {
/*
* 保存用户信息到sdcard
* 参数为用户输入的用户名和密码
*/
public static boolean saveUserInfo(String username, String password) {
try {
//封装传过来的用户名和密码,"##"为分割符,一般用正则表达式或file.separator()
String userInfo = username + "##" + password;
//指定保存的路径(通过API获得)
String path = Environment.getExternalStorageDirectory().getPath();
System.out.println(path);//我用的是genymotion虚拟机,保存路径为: /storage/emulated/0
//创建file
File file = new File(path, "userinfo.txt");
//创建文件输出流,把文件写到sdcard
FileOutputStream fos = new FileOutputStream(file);
fos.write(userInfo.getBytes());
fos.close();
return true; //如果保存成功,则返回true
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/*
* 从sdcard中取出数据
*/
public static Map<String, String> getUserInfo(){
try {
//读取的路径、文件和保存时的相同
//指定保存的路径
String path = Environment.getExternalStorageDirectory().getPath();
//创建file
File file = new File(path, "userinfo.txt");
//使用缓冲流把数据读出(也可以使用内存流),这里使用缓存流,是因为其有readLine方法,可以逐行读取
FileInputStream fis = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
//读取一行
String readLine = br.readLine();
//对读取的内容按照标记进行分割
String[] split = readLine.split("##");
//把分割后的数据保存到HashMap集合中
HashMap<String, String>map = new HashMap<String, String>();
map.put("username", split[0]);
map.put("password", split[1]);
//关流
br.close();
fis.close();
//把map返回回去
return map;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}</span><span style="font-size:14px;">
</span>
④输入用户名和密码,选中“记住密码”,点击“登录按钮”,退出后,下次再进入用户名和密码便会回显出来,说明往sdcard中存取数据的功能实现了,效果图如下: