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中存取数据的功能实现了,效果图如下: