HDU-安卓程序开发之简单存储/内部存储/外部存储 & 捉虫
前言
大三上学期可以说是各工科学生课最难最多的一学期了,又因下学期大家普遍需要找工作,所以都压力比较大吧…
安卓作为我本学期选的五门专业课中学的最认真的(因为每周都有布置作业),所以我对它相对比较了解,下面来给大家分享一下【第8章数据存储与访问-简单存储/内部存储/外部存储】的源码和心得
界面和源码
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="fourvolt69.lesson">
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"> </uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"> </uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"> </uses-permission>
//另外,外部存储因为需要访问程序数据之外的存储空间,所以需要在安卓机的设置(app permission->storage)把storage的权限给到本程序
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
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="fourvolt69.lesson.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="@+id/textView" />
<Button
android:text="简单读"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button2"
android:layout_alignBaseline="@+id/button"
android:layout_alignBottom="@+id/button"
android:layout_alignParentEnd="true"
android:layout_marginEnd="73dp" />
<Button
android:text="简单写"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="69dp"
android:id="@+id/button"
android:layout_below="@+id/editText3"
android:layout_toEndOf="@+id/textView" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:layout_marginTop="20dp"
android:id="@+id/editText3"
android:layout_below="@+id/editText2"
android:layout_centerHorizontal="true"
android:hint="height" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:layout_marginTop="20dp"
android:id="@+id/editText2"
android:layout_below="@+id/editText"
android:layout_alignStart="@+id/editText3"
android:hint="age" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:layout_marginTop="20dp"
android:id="@+id/editText"
android:layout_below="@+id/textView"
android:layout_alignStart="@+id/editText2"
android:hint="name" />
<Button
android:text="内部读"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button4"
android:layout_alignBaseline="@+id/button3"
android:layout_alignBottom="@+id/button3"
android:layout_alignStart="@+id/button2" />
<Button
android:text="外部读"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button6"
android:layout_alignBaseline="@+id/button5"
android:layout_alignBottom="@+id/button5"
android:layout_alignStart="@+id/button4" />
<Button
android:text="外部写"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button5"
android:layout_marginTop="15dp"
android:layout_below="@+id/button3"
android:layout_alignStart="@+id/button3" />
<Button
android:text="内部写"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:id="@+id/button3"
android:layout_below="@+id/button"
android:layout_alignStart="@+id/button" />
</RelativeLayout>
MainActivity.java
package fourvolt69.lesson;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.os.Environment;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
EditText nameText, ageText, heightText;
SharedPreferences sharedPreferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final String tag="sdCardReadWrite";
setContentView(R.layout.activity_main);
nameText = (EditText) findViewById(R.id.editText);
ageText = (EditText) findViewById(R.id.editText2);
heightText = (EditText) findViewById(R.id.editText3);
Button shSave = (Button) findViewById(R.id.button);
Button shRead = (Button) findViewById(R.id.button2);
Button inSave = (Button) findViewById(R.id.button3);
Button inRead = (Button) findViewById(R.id.button4);
Button sdSave = (Button) findViewById(R.id.button5);
Button sdRead = (Button) findViewById(R.id.button6);
/*
简单存储
sharedPreferences = getSharedPreferences("sp1",MODE_PRIVATE);
shSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SharedPreferences.Editor editor=sharedPreferences.edit();
editor.putString("name",nameText.getText().toString());
editor.putInt("age",Integer.valueOf(ageText.getText().toString()));
editor.putFloat("height",Float.valueOf(heightText.getText().toString()));
editor.commit();
}
});
shRead.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String name=sharedPreferences.getString("name","杭电学生");
int age=sharedPreferences.getInt("age",20);
float height=sharedPreferences.getFloat("height",1.70F);
nameText.setText(name);
ageText.setText(String.valueOf(age));
heightText.setText(String.valueOf(height));
}
});
*/
/*
内部存储
inSave.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view){
String text = nameText.getText().toString();
FileOutputStream fos = null;
try {
fos = openFileOutput("myName", Context.MODE_APPEND);
try{
fos.write(text.getBytes());
fos.flush();
}catch (IOException e){
e.printStackTrace();
}
}catch (FileNotFoundException e){
e.printStackTrace();
}finally {
try{
fos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
});
inRead.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view){
FileInputStream fis=null;
try {
fis=openFileInput("myName");
try{
byte[] readBytes=new byte[fis.available()];
while (fis.read(readBytes)!=-1){
}
String s = new String(readBytes);
nameText.setText(s);
} catch (IOException e){
e.printStackTrace();
}
}catch (FileNotFoundException e){
e.printStackTrace();
}finally {
try{
fis.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
});
*/
sdSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
File dir = new File(Environment.getExternalStorageDirectory().toString());
if(dir.exists()&&dir.canWrite()){
Log.d(tag,"该目录存在 且 可写");
File newFile = new File(Environment.getExternalStorageDirectory(),"myName2.txt");
FileOutputStream fos = null;
try{
newFile.createNewFile();
fos = new FileOutputStream(newFile);
fos.write(nameText.getText().toString().getBytes());
fos.flush();
Log.d(tag,"成功写入");
}catch (IOException e){
e.printStackTrace();
}finally {
try{
fos.close();
Log.d(tag,"关闭fos");
}catch (IOException e){
e.printStackTrace();
}
}
}
else {
Log.d(tag,"该目录不存在 或 不可写");
}
}
});
sdRead.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
File dir1 = new File(Environment.getExternalStorageDirectory(),"myName2.txt");
if(dir1.exists()&&dir1.canRead()){
Log.d(tag,"该目录存在 且 可读");
FileInputStream fis = null;
try{
fis = new FileInputStream(dir1);
try {
byte[] readBytes = new byte[fis.available()];
while (fis.read(readBytes)!=-1){
}
String s = new String(readBytes);
nameText.setText(s);
Log.d(tag,"读取成功");
}catch (IOException e){
e.printStackTrace();
}
}catch (IOException e){
e.printStackTrace();
}finally {
try{
fis.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
else{
Log.d(tag,"该目录不存在 或 不可读");
}
}
});
}
@Override
protected void onStop() {
super.onStop();
}
}
心得
此三块内容课时为3 * 45分钟,总的来说简单存储和内部存储算是比较简单的,我也没有遇到什么麻烦,而外部存储则比较苦恼,下面列举一些容易忽略的知识点和容易触发的小bug
- try & catch
//openFileOutput函数
String FILE_NAME = "fileDemo.txt";
FileOutputStream fos = openFileOutput(FILE_NAME,Context.MODE_PRIVATE)
String text = “Some data”;
fos.write(text.getBytes());
fos.flush();
fos.close();
//openFileInput()函数
String FILE_NAME = "fileDemo.txt";
FileInputStream fis = openFileInput(FILE_NAME);
//fis.available():fis的有效字节数
byte[] readBytes = new byte[fis.available()];
while(fis.read(readBytes) != -1){//从fis读取字节并存入数组readBytes,读到字节最后时会返回-1,循环就结束了
}
上面的两部分代码在实际使用过程中会遇到错误提示,因为文件操作可能会遇到各种问题而最终导致操作失败,因此代码应该使用try / catch捕获可能产生的异常
2. 在Android File Explorer中想要查看写入的文件,却发现白屏
关于此问题请前往站内博客:解决Android studio中的Android 7.0 在 Android Device Monitor(DDMS)的 File Explorer不显示目录树的问题
https://blog.csdn.net/itxiaolong3/article/details/70156276
3. 在Android File Explorer中想要查看写入的文件,发现/data打不开
当我们去点击/data/目录时,发现什么都没有,这是怎么回事呢?原因是我们权限不够,当前的用户没有权限访问data目录。
经大佬指点,改正后仍未解决,决定日后解决了再来更新。
据老师步骤,接下来应该是
4. 外部存储需要在安卓机的设置中赋予storage权限
如果在这个列表中没有出现你的程序,建议重启,再编译,应该就不会有问题啦!
5. 千万不要这样写路径,例如:"/mnt/sdcard/""/sdcard/storage/"
一想到Android中到SdCard就要想到 Environment,写入到路径一定要用Environment,读取到路径一定要要用Environment,因为每部手机到SdCard到路径都会不同Environment.getExternalStorageDirectory()
结语
经过余老师课上的悉心指导和课后布置的作业,我意外的有很多收获,在本学期课程完成之后我还会将所有课后作业和期末大作业上传至本平台,并更新博客,希望能够帮到广大网友和学弟学妹( X D )
本文地址:https://blog.csdn.net/fourvolt/article/details/110603064