android开发学习(二)——保存文件到手机内存和SD卡,文件访问权限,获取内存大小


谈三点:保存文件到手机内存和SD卡,文件访问权限,获取手机内存和SD卡容量大小


一,保存文件到手机内存和SD卡

这里引用一个案例,写一个登录界面,选择记住密码时将密码保存在手机内存或者SD卡上。

保存到手机内存:

MainActivity.java

<span style="font-size:14px;">package com.example.login;

import java.util.Map;

import com.example.login.service.LoginService;

import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

	private static final String tag = "MainActivity";
	private EditText et_name;
	private EditText et_password;
	private CheckBox RemenberPassword;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// 初始化
		et_name = (EditText) findViewById(R.id.et_name);
		et_password = (EditText) findViewById(R.id.et_password);
		RemenberPassword = (CheckBox) findViewById(R.id.cb_remenberpawd);
	}

	/**
	 * 登录
	 */
	@SuppressLint("ShowToast")
	public void login(View view) {
		String name = et_name.getText().toString().trim();
		String password = et_password.getText().toString();

		if (TextUtils.isEmpty(name) || TextUtils.isEmpty(password)) {
			Toast.makeText(this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show();
		} else {
			// 判断是否保存用户名密码
			if (RemenberPassword.isChecked()) {
				// 保存密码
				Log.i(tag, "需要保存的用户名和密码。");
				boolean result = LoginService.saveUserInfo(this, name, password);
				if (result) {
					Toast.makeText(this, "保存用户信息成功", Toast.LENGTH_SHORT).show();
				}
			}

			// 登录,发送消息到服务器,服务器验证正确性
			if ("123".equals(name) && "4038".equals(password)) {
				Toast.makeText(this, "登录成功", Toast.LENGTH_LONG).show();
			} else {
				Toast.makeText(this, "登录失败", Toast.LENGTH_LONG).show();
			}
		}
	}
}
</span>

LoginService.java


<span style="font-size:14px;">package com.example.login.service;

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.content.Context;

/**
 * 保存用户名和密码的业务方法
 * Context 上下文 就是一个类,提供一些方便的api,
 * 可以得到应用程序的环境 环境包名 安装路径 文件的路径 资源的路径  资产的路径
 * @author Administrator
 */
public class LoginService {
	public static boolean saveUserInfo(Context context, String name,
			String password) {
		// File file = new File("/data/data/com.example.login/Info.txt");//不够灵活,一旦修改包名路径就无效
		// context.getFilesDir();//帮助我们返回一个目录 /data/data/包名/files/
		File file = new File(context.getFilesDir(), "Infor.txt");
		try {
			FileOutputStream fos = new FileOutputStream(file);
			fos.write((name + "##" + password).getBytes());
			fos.close();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
}
</span>

这里我们用到了一个获取目录路径的API——Context,上下文  就是一个类,提供一些方便的api,可以得到应用程序的环境
环境包名  安装路径  文件的路径  资源的路径  资产的路径

1】context.getFileDir  得到目录:/data/data/包名/files/

2】context.getCacheDir  得到目录:/data/data/包名/cache/

3】context.openFileOutput(String name, int mode)  :Open a private file associated with this Context's application package for writing. Creates the file if it doesn't already exist.  (打开这个Context's的应用程序包写入相关的私人文件。创建文件,如果它不存在。)

    Parameters:

         name The name of the file to open; can not contain path separators.

         mode Operating mode. Use 0 or MODE_PRIVATE for the default operation, MODE_APPEND to append to an existing file, MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE to control permissions.

    Returns: FileOutputStream Resulting output stream.

    Throws: FileNotFoundException


其中第三种方法也是写入手机内存的一种操作方式,这种方式可以定义写入文件的权限,而代码中的方式写入的文件权限是默认的,默认的就是private,权限的问题后面会讲到。


保存到SD卡上:


上述代码可以将数据写入SD卡上,就是将目录路径改变。

不过在对SD卡写入时,要注意一个问题:

这里是告诉我们对SD卡写入操作时,要获取权限,需要我们在AndroidManifest.xml文件中添加权限:android.permission.WRITE_EXTERNAL_STORAGE


还有,对SD卡的操作前,要检查SD卡的状态,能否被操作:

Environment.getExternalStorageState()     检测外部存储器的状态,返回String类型的数据

这里需要判断所得的环境状态,在Environment中有很多定义好的状态:

他们的意思分别是:(中英文)

MEDIA_BAD_REMOVAL:不正确卸载状态
getExternalStorageState() returns MEDIA_BAD_REMOVAL
if the media was removed before it was unmounted.

MEDIA_CHECKING:装载且正在磁盘检查状态
getExternalStorageState() returns MEDIA_CHECKING
if the media is present and being disk-checked

MEDIA_MOUNTED:装载可读写状态
getExternalStorageState() returns MEDIA_MOUNTED
if the media is present and mounted at its mount point with read/write access.

MEDIA_MOUNTED_READ_ONLY:装载只可读状态
getExternalStorageState() returns MEDIA_MOUNTED_READ_ONLY
if the media is present and mounted at its mount point with read only access.

MEDIA_NOFS:装载但是不支持文件系统
getExternalStorageState() returns MEDIA_NOFS
if the media is present but is blank or is using an unsupported filesystem

MEDIA_REMOVED:卸载状态
getExternalStorageState() returns MEDIA_REMOVED
if the media is not present.

MEDIA_SHARED:卸载并且通过USB存储共享
getExternalStorageState() returns MEDIA_SHARED
if the media is present not mounted, and shared via USB mass storage.

MEDIA_UNMOUNTABLE:如果媒体是存在的,但不能被安装。通常这种情况发生,如果在媒体上的文件系统

被破坏。
getExternalStorageState() returns MEDIA_UNMOUNTABLE
if the media is present but cannot be mounted. Typically this happens if the file system on

the media is corrupted.

MEDIA_UNMOUNTED:没有正确安装状态,未安装好
getExternalStorageState() returns MEDIA_UNMOUNTED
if the media is present but not mounted.


在对SD卡写入的操作中,路径问题也同对手机内存写入操作一样,有定义好的API让我们获取路径,不用写固定路径:

Environment.getExternalStorageDirectory()     获取外部存储设备路径目录


所以应该是这样的:


需要注意的是,这里只是介绍对手机内存和SD卡的写入操作,而案例中的用户名,密码保存方式不能用这种方式,应为作为分隔符的“##”可能与密码弄混,这样安全性就大大减少,并且容易出现bug。所以在用户名,密码一类的配置信息写出一般用SharedPreferences方法,关于这个方法的具体说明,我将在下一篇笔记中讲解。


文件访问权限:


这里在cmd中挂在android的Linux环境,进行一些操作:



这里通过chmod 命令可以更改文件的属性权限。


这里的Infor.txt文件就是写入手机内存时用的上面文件输入输出流方式,权限是默认的,就是private。

而下面的四个文件:ReadWrite.txt、private.txt、read.txt、write.txt都是用context.openFileOutput(String name, int mode) 方法写入的,代码如下:

MainActivity.java

package com.example.login;

import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Toast;

import com.example.login.service.LoginService;

public class MainActivity extends Activity {

	private static final String tag = "MainActivity";
	private EditText et_name;
	private EditText et_password;
	private CheckBox RemenberPassword;
	private RadioGroup rg_mode;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// 初始化
		et_name = (EditText) findViewById(R.id.et_name);
		et_password = (EditText) findViewById(R.id.et_password);
		RemenberPassword = (CheckBox) findViewById(R.id.cb_remenberpawd);
		rg_mode = (RadioGroup) findViewById(R.id.rg_mode);
	}

	/**
	 * 登录
	 */
	public void login(View view) {
		String name = et_name.getText().toString().trim();
		String password = et_password.getText().toString();

		if (TextUtils.isEmpty(name) || TextUtils.isEmpty(password)) {
			Toast.makeText(this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show();
		} else {
			// 判断是否保存用户名密码
			if (RemenberPassword.isChecked()) {
				// 保存密码
				Log.i(tag, "需要保存的用户名和密码。");

				int mode = rg_mode.getCheckedRadioButtonId();
				int moded = 0 ;
				switch (mode) {
				case R.id.rb_private:
					moded = 1;
					break;
				case R.id.rb_read:
					moded = 2;
					break;
				case R.id.rb_write:
					moded = 3;
					break;
				case R.id.rb_read_write:
					moded = 4;
					break;
				default:
					break;
				}
				boolean result = LoginService.saveUserInfo(this, name, password, moded);
				if (result) {
					Toast.makeText(this, "保存用户信息成功", Toast.LENGTH_SHORT).show();
				}
			}

			// 登录,发送消息到服务器,服务器验证正确性
			if ("123".equals(name) && "4038".equals(password)) {
				Toast.makeText(this, "登录成功", Toast.LENGTH_LONG).show();
			} else {
				Toast.makeText(this, "登录失败", Toast.LENGTH_LONG).show();
			}
		}
	}
}

LoginService.java


package com.example.login.service;

import java.io.FileOutputStream;

import android.content.Context;

/**
 * 保存用户名和密码的业务方法
 * Context  上下文 就是一个类,提供一些方便的api,
 * 可以得到应用程序的环境 环境包名 安装路径 文件的路径 资源的路径 资产的路径
 * @author Administrator
 */
public class LoginService {
	public static boolean saveUserInfo(Context context, String name, String password, int moded) {
		FileOutputStream fos = null;
		try {
			switch (moded) {
			case 1:
				fos = context.openFileOutput("private.txt", Context.MODE_PRIVATE);
				break;
			case 2:
				fos = context.openFileOutput("read.txt", Context.MODE_WORLD_READABLE);
				break;
			case 3:
				fos = context.openFileOutput("write.txt", Context.MODE_WORLD_WRITEABLE);
				break;
			case 4:
				fos = context.openFileOutput("ReadWrite.txt",
						Context.MODE_WORLD_READABLE+Context.MODE_WORLD_WRITEABLE);
				break;
			}
			fos.write((name + "##" + password).getBytes());
			fos.close();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
}


界面如下:




获取手机内存和SD卡大小

这里的方法是从android系统源代码中提取的,获取系统信息的很多方法可以从android源代码中学习。这里就是简单介绍获取SD卡容量和手机内存容量的方法,代码如下:

package com.example.readsdsize;

import java.io.File;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.StatFs;
import android.text.format.Formatter;
import android.widget.TextView;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		TextView tv = (TextView) findViewById(R.id.read_sd);

		File path = Environment.getExternalStorageDirectory();
		StatFs stat = new StatFs(path.getPath());
		long blockSize = stat.getBlockSize();
		long totalBlocks = stat.getBlockCount();
		long availableBlocks = stat.getAvailableBlocks();

		long totalSize = blockSize * totalBlocks;
		long availSize = blockSize * availableBlocks;

		String totalStr = Formatter.formatFileSize(this, totalSize);
		String availStr = Formatter.formatFileSize(this, availSize);

		tv.setText("外部总内存:" + totalStr + "\n" + "外部可用内存:" + availStr+ "\n"+ getRomSpaceInfo());
	}
	
	public String getRomSpaceInfo() {
		File path = Environment.getDataDirectory();
		StatFs stat = new StatFs(path.getPath());
		long blockSize = stat.getBlockSize();
		long totalBlocks = stat.getBlockCount();
		long availableBlocks = stat.getAvailableBlocks();

		long totalSize = blockSize * totalBlocks;
		long availSize = blockSize * availableBlocks;

		String totalStr = Formatter.formatFileSize(this, totalSize);
		String availStr = Formatter.formatFileSize(this, availSize);

		return "内部总内存:" + totalStr + "\n" + "内部可用内存:" + availStr;
	}

}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值