Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

Android之sdcard保存数据

$
0
0

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>


②MainActivity的代码:

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




作者:ljw124213 发表于2016/9/13 22:40:21 原文链接
阅读:86 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles