六 文件存储
一、实验目的及任务
1、 掌握文件内存的使用
2、 掌握SD卡存储的使用
3、掌握SQLite数据库的增删改查操作。熟悉SQLiteDatabase操作类,SQLiteOpenHelper辅助类的使用
二、实验环境
1、 Jdk
2、 Android Studio
3、 Android SDK
三、实验步骤
使用File类开发一个文件浏览器,用于查看SD卡中的文件信息。
注意:使用ListView控件来显示指定目录中的全部文件和文件夹。
实验结果:
代码:
项目目录:
根布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/tva"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50sp"
android:orientation="horizontal"
android:paddingTop="15sp">
<ImageView
android:id="@+id/backArrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_keyboard_arrow_left_black_24dp"
android:onClick="goBack"/>
<TextView
android:layout_marginLeft="80sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="当前路径为: "/>
<TextView
android:id="@+id/thePath"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" "/>
</LinearLayout>
<ListView
android:id="@+id/mylistA"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
list View 布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/ll_view"
android:gravity="center"
android:layout_margin="10dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:background="#FAFAFA"
android:id="@+id/fileImg"
android:layout_width="60sp"
android:layout_height="60sp" />
<LinearLayout
android:layout_width="250sp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginLeft="30sp">
<TextView
android:id="@+id/fileName"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="文件名"
android:paddingTop="20sp"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
Java代码:
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//使用File类开发一个文件浏览器,用于查看SD卡中的文件信息。
//注意:使用ListView控件来显示指定目录中的全部文件和文件夹。
//只要求查看文件目录(不要求增删改查), 只要求在SD中
public class MainActivity extends AppCompatActivity {
LinearLayout linearLayoutA;//获取整个根布局linearLayout用户构建listView
TextView thePath;//赋值当前路径
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
linearLayoutA = findViewById(R.id.tva);//整个根布局linearLayout
thePath = findViewById(R.id.thePath);//跟布局中显示的路径
init();
}
public void init(){//初始化
thePath.setText(getSdCardPath());//将SD卡的根路径直接赋值给路径, 因为这是初始化
List<Map<String,Object>> listItems=new ArrayList<>();//用于构建list view
String[] childs = getChilds(getSdCardPath());//得到根路径下所有的文件名称
if (childs != null){//只要不是空
for(int i=0;i<childs.length;i++){//就将所有的这一级目录下所有的文件名都放到list view中
Map<String,Object> listItem=new HashMap<>();
listItem.put("fileName",childs[i]);
if(childs[i].contains(".") && childs[i].charAt(0)!='.'){//如果包含点就说明是个文件而不是文件夹
String type = childs[i].split(".")[1];//得到文件类型
if(type.equals("jpg") || type.equals("png")){//如果是图片的话就给它图片的图标
listItem.put("fileImg",R.drawable.ic_image_black_24dp);
}
}else { //不是图片
System.out.println("此处的文件路径为: "+getSdCardPath()+"/"+childs[i]);
File file = new File(getSdCardPath()+"/"+childs[i]);//将这个文件取出来 就能判断是文件夹还是文件
if(file.isDirectory()){//是文件夹 给它文件夹的图标
listItem.put("fileImg",R.drawable.ic_folder_black_24dp);
}else {//是非图片的文件 给它普通文件的图标
listItem.put("fileImg",R.drawable.ic_insert_drive_file_black_24dp);
}
}
listItems.add(listItem);
}
}
//new一个SimpleAdapter对象用于适配 list view
//这个对象的构造函数需要的参数包括
//当前应用的上下文ApplicationContext
//list view要放的 map元素(此处的元素 包含一个文件图标和一个文件名称组成的map)
//list view所对应的layout
//map元素 的所有的index名
//map元素 的所有的index所对应的在list view的layout中的id, 通过这样找到位置
SimpleAdapter simpleAdapter=new SimpleAdapter(getApplicationContext(), listItems, R.layout.message,
new String[]{"fileName","fileImg"}, new int[]{R.id.fileName, R.id.fileImg});
ListView myList = findViewById(R.id.mylistA);//new一个list view对象,
// 参数需要引用了这个list view的layout中这个list view的id
myList.setAdapter(simpleAdapter);//关键的一步, ListView需要set前面我们new的simpleAdapter对象
myList.setOnItemClickListener(new AdapterView.OnItemClickListener() {//用于打开下一个文件的操作
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView fileName = view.findViewById(R.id.fileName);
//在Activity当中使用findViewById()方法貌似不一定需要由view对象来点,
//但是如果直接使用, 在listView中获取到的值可能和想要的值不一样(会只获取第一个值, 也就是这里的Android文件夹)
String theName = fileName.getText().toString();
File theFile = new File(getSdCardPath()+"/"+theName);//锁定根部录下的这个文件, 判断是不是文件
if(theFile.isDirectory()){
System.out.println("判断为路径, 即将进入路径: "+getSdCardPath()+"/"+theName);
clickIn(getSdCardPath()+"/"+theName);
}else {//发现是个文件 而不是文件夹 不能进入
Toast toast=Toast.makeText(getApplicationContext(), "不能打开文件", Toast.LENGTH_SHORT);
toast.show();
}
}
});
}
//这个方法和init()方法神似, 只不过init()方法实在根文件路径下的, 这个方法有一个参数filePath, 实在根路径下的又一个路径, 也就说是进入了人某一个文件夹
public void clickIn(String filePath){
System.out.println("进入了clickIn()方法, 此时的文件路径为: "+filePath);
thePath.setText(filePath);
List<Map<String,Object>> listItems=new ArrayList<>();
String[] childs = getChilds(filePath);
if (childs != null){
for(int i=0;i<childs.length;i++){
Map<String,Object> listItem=new HashMap<>();
listItem.put("fileName",childs[i]);
if(childs[i].contains(".") && childs[i].charAt(0)!='.'){
System.out.println("childs[i]: "+childs[i]);
String type = childs[i].split(".")[1];
if(type.equals("jpg") || type.equals("png")){
listItem.put("fileImg",R.drawable.ic_image_black_24dp);
}
}else {
System.out.println("此处的文件路径为: "+filePath+"/"+childs[i]);
File file = new File(filePath+"/"+childs[i]);
if(file.isDirectory()){
listItem.put("fileImg",R.drawable.ic_folder_black_24dp);
}else {
listItem.put("fileImg",R.drawable.ic_insert_drive_file_black_24dp);
}
}
listItems.add(listItem);
}
}
SimpleAdapter simpleAdapter=new SimpleAdapter(getApplicationContext(), listItems, R.layout.message,
new String[]{"fileName","fileImg"}, new int[]{R.id.fileName, R.id.fileImg});
ListView myList = findViewById(R.id.mylistA);
myList.setAdapter(simpleAdapter);
final String theFilePath = filePath;
myList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView fileName = view.findViewById(R.id.fileName);
//在Activity当中使用findViewById()方法貌似不一定需要由view对象来点,
//但是如果直接使用, 在listView中获取到的值可能和想要的值不一样(会只获取第一个值, 也就是这里的Android文件夹)
String theName = fileName.getText().toString();
File theFile = new File(theFilePath+"/"+theName);
if(theFile.isDirectory()){
System.out.println("判断为路径, 即将进入路径: "+theFilePath+"/"+theName);
clickIn(theFilePath+"/"+theName);
}else {
Toast toast=Toast.makeText(getApplicationContext(), "不能打开文件", Toast.LENGTH_SHORT);
toast.show();
}
}
});
}
//点击监听: 返回上一级目录
public void goBack(View view){
String path = thePath.getText().toString();
if (path.equals(getSdCardPath())){
Toast toast=Toast.makeText(getApplicationContext(), "已经位于SD卡根目录", Toast.LENGTH_SHORT);
toast.show();
}else {
int lastIndexOf = path.lastIndexOf("/");
String newPath = path.substring(0,lastIndexOf);
System.out.println("返回上一级目录: "+newPath);
clickIn(newPath);
}
}
//判断SDCard是否存在
public static boolean isSdCardExist() {
return Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
}
//获取SDCard根目录
public static String getSdCardPath() {
boolean exist = isSdCardExist();
String sdpath = "";
if (exist) {
sdpath = Environment.getExternalStorageDirectory()
.getAbsolutePath();
} else {
sdpath = "不适用";
}
return sdpath;
}
//得到一个路径下所有的文件/文件夹
public static String[] getChilds(String pathString){
File path = new File(pathString);
return path.list();
}
}