Android入门之读写本地文件的实现

目录
  • 简介
  • 课程目标
  • UI端
  • 后端代码
  • 运行效果

简介

为了这个系列,我的代码已经准备到了第150天了。接下来的内容会越来越精彩,我们也越来越开始进入Android的一些高级功能上的编程了。今天我们就要讲Android中对本地文件进行读写的全过程。

课程目标

  • 输入文件名、输入文件内容后按【保存到SD卡】,可以把文件保存到SD卡根目录;
  • 输入文件名,按【读取SD卡中的文件】,可以根据输入的文件名把文件内容显示成Toast;
  • 搞清Android中对于SD卡读写时所需要的静态权限申请、动态权限申请;

以上一共我们有3个目标,根据目标下面开始教程。

UI端

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="清输入文件名" />

    <EditText
        android:id="@+id/editFileName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="文件名" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="清输入文件内容" />

    <EditText
        android:id="@+id/editFileContents"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="文件内容" />

    <Button
        android:id="@+id/buttonSave"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="保存到SD卡" />

    <Button
        android:id="@+id/buttonClean"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="清空" />

    <Button
        android:id="@+id/buttonRead"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="读取sd卡中的文件" />

</LinearLayout>

我们的UI端很简单,用LinearLayout从上到下依次把一系列元素都设置好。接着我们来看我们的后端代码。

静态授权-AndroidManifest.xml文件内容

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <!-- 在SDCard中创建与删除文件权限 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
        tools:ignore="ProtectedPermissions" />
    <!-- 往SDCard写入数据权限 -->
    <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />
    <!--外部存储的写权限-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!--外部存储的读权限-->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <application
        android:requestLegacyExternalStorage="true"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.DemoSimpleFile"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
            <meta-data
                android:name="ScopedStorage"
                android:value="true" />
        </activity>
    </application>

</manifest>

注意以上的4行<uses-permission>。

后端代码

文件读写帮助类-SDFileUtility.java

package org.mk.android.demo;

import android.content.Context;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class SDFileUtility {
    private final static String TAG = "DemoSimpleFile";
    private Context context;

    public SDFileUtility() {
    }

    public SDFileUtility(Context context) {
        super();
        this.context = context;
    }

    //往SD卡写入文件的方法
    public void savaFileToSD(String fileName, String fileContents) throws Exception {
        //如果手机已插入sd卡,且app具有读写sd卡的权限
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            fileName = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + fileName;
            //这里就不要用openFileOutput了,那个是往手机内存中写数据的
            FileOutputStream output = null;
            try {
                output = new FileOutputStream(fileName);
                output.write(fileContents.getBytes());
                //将String字符串以字节流的形式写入到输出流中
            } catch (Exception e) {
                Log.e(TAG, "saveFileTOSD error: " + e.getMessage(), e);
            } finally {
                try {
                    output.close();
                    //关闭输出流
                } catch (Exception e) {
                }
            }

        } else Toast.makeText(context, "SD卡不存在或者不可读写", Toast.LENGTH_SHORT).show();
    }

    //读取SD卡中文件的方法
    //定义读取文件的方法:
    public String readFromSD(String fileName) throws IOException {
        StringBuilder sb = new StringBuilder("");
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            fileName = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + fileName;
            FileInputStream input = null;
            try {
                //打开文件输入流
                input = new FileInputStream(fileName);
                byte[] temp = new byte[1024];

                int len = 0;
                //读取文件内容:
                while ((len = input.read(temp)) > 0) {
                    sb.append(new String(temp, 0, len));
                }
            } catch (Exception e) {
                Log.e(TAG, "readFromSD error: " + e.getMessage(), e);
            } finally {
                try {
                    //关闭输入流
                    input.close();
                } catch (Exception e) {
                }
            }

        }
        return sb.toString();
    }
}

后端主交互类-MainActivity.java

package org.mk.android.demo;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private EditText editFileName;
    private EditText editContents;
    private Button buttonSave;
    private Button buttonClean;
    private Button buttonRead;
    private Context mContext;
    private final static String TAG = "DemoSimpleFile";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = getApplicationContext();
        bindViews();
    }

    private void bindViews() {
        editFileName = (EditText) findViewById(R.id.editFileName);
        editContents = (EditText) findViewById(R.id.editFileContents);
        buttonSave = (Button) findViewById(R.id.buttonSave);
        buttonClean = (Button) findViewById(R.id.buttonClean);
        buttonRead = (Button) findViewById(R.id.buttonRead);

        buttonSave.setOnClickListener(this);
        buttonClean.setOnClickListener(this);
        buttonRead.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.buttonClean:
                editContents.setText("");
                editFileName.setText("");
                break;
            case R.id.buttonSave:
                if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.R) {
                    Log.i(TAG,">>>>>>version.SDK->"+Build.VERSION.SDK_INT);
                    if (!Environment.isExternalStorageManager()) {
                        Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                        this.startActivity(intent);
                        return;
                    }
                }
                Log.i(TAG,">>>>>>start to writeFile");
                writeFile();
                Log.i(TAG,">>>>>>write success");

                break;
            case R.id.buttonRead:
                if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.R) {
                    Log.i(TAG,">>>>>>version.SDK->"+Build.VERSION.SDK_INT);
                    if (!Environment.isExternalStorageManager()) {
                        Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                        this.startActivity(intent);
                        return;
                    }
                }
                Log.i(TAG,">>>>>>start to readFile");
                readFile();
                Log.i(TAG,">>>>>>read success");

                break;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1 && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
            //writeFile();
            Log.i(TAG,">>>>>>onRequestPermissionsResult");
        }
    }

    private void writeFile() {
        String fileName = editFileName.getText().toString();
        String fileContents = editContents.getText().toString();
        SDFileUtility sdHelper = new SDFileUtility(mContext);
        try {
            sdHelper.savaFileToSD(fileName, fileContents);
            Toast.makeText(getApplicationContext(), "数据写入成功", Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            Log.e(TAG, "save contents into file has errors: " + e.getMessage(), e);
            Toast.makeText(getApplicationContext(), "数据写入失败", Toast.LENGTH_SHORT).show();
        }
    }

    private void readFile() {
        String detail = "";
        SDFileUtility sdHelper2 = new SDFileUtility(mContext);
        try {
            String fileName2 = editFileName.getText().toString();
            detail = sdHelper2.readFromSD(fileName2);
        } catch (Exception e) {
            Log.e(TAG, "read contents from file has errors: " + e.getMessage(), e);
        }
        Toast.makeText(getApplicationContext(), detail, Toast.LENGTH_SHORT).show();
    }
}

核心代码导读

读写手机SD卡,我们除了在AndroidManifest.xml文件中静态申请权限外还需要使用代码动态申请权限,这是Android6后的权限限制带来的问题。

case R.id.buttonSave:
     if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.R) {
       Log.i(TAG,">>>>>>version.SDK->"+Build.VERSION.SDK_INT);
       if (!Environment.isExternalStorageManager()) {
         Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
         his.startActivity(intent);
         return;
       }
     }

这一段代码就是使用代码在写文件前动态申请权限用的,当这段代码执行后会弹出以下这样的一个对话框

点击这个APP应用,然后来到第二个对话框

点击我红圈处标出的开关按钮

然后重新运行APP即可。

运行效果

到此这篇关于Android入门之读写本地文件的实现的文章就介绍到这了,更多相关Android读写本地文件内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • android开发实现文件读写

    本文实例为大家分享了android实现文件读写的具体代码,供大家参考,具体内容如下 读取 /** * 文件读取 * @param is 文件的输入流 * @return 返回文件数组 */ private byte[] read(InputStream is) { //缓冲区inputStream BufferedInputStream bis = null; //用于存储数据 ByteArrayOutputStream baos = null; try { //每次读1024 byte[] b

  • Android读写文件工具类详解

    本文实例为大家分享了Android读写文件工具类的具体代码,供大家参考,具体内容如下 public class Utils { private static String path1 = Environment.getExternalStorageDirectory().getAbsolutePath(); private static String path2 = Environment.getDownloadCacheDirectory().getAbsolutePath(); privat

  • android实现文件读写功能

    本文实例为大家分享了android实现文件读写功能的具体代码,供大家参考,具体内容如下 读取: public static String _getJsonString(String fileName) throws IOException { if ((fileName == null) || fileName.isEmpty()) { return ""; } String retString = ""; FileInputStream fis = null; S

  • Android 打开本地pdf文件

    Android 中打开pdf文件也是一种很常见的场景,但是上网找了好多资料,有用WebView加载的,但是要用vpn才能搞,最后发现一个库挺不错的,再次分享给大家 android-pdfview.下面主要说一下该库的使用方法. 1. 该库的下载地址 https://github.com/JoanZapata/android-pdfview 源码下载:http://xiazai.jb51.net/201704/yuanma/android-pdfview-master_jb51.rar 2. an

  • Android 如何本地加载pdf文件

    大部分app打开pdf文件是通过intent调起手机中能打开pdf文件的工具,来查看pdf文件,如果需求是,用户在app内下载好pdf文件后,不通过第三方的工具,本地打开. 这样的需求要怎么实现呢?上网查了一些资料,发现了一个很好用PDF开源库. 使用起来也很简单,首先添加PDFView的引用 compile 'com.github.barteksc:android-pdf-viewer:2.4.0' 布局中引用PdfView <LinearLayout xmlns:android="ht

  • Android入门之读写本地文件的实现

    目录 简介 课程目标 UI端 后端代码 运行效果 简介 为了这个系列,我的代码已经准备到了第150天了.接下来的内容会越来越精彩,我们也越来越开始进入Android的一些高级功能上的编程了.今天我们就要讲Android中对本地文件进行读写的全过程. 课程目标 输入文件名.输入文件内容后按[保存到SD卡],可以把文件保存到SD卡根目录: 输入文件名,按[读取SD卡中的文件],可以根据输入的文件名把文件内容显示成Toast: 搞清Android中对于SD卡读写时所需要的静态权限申请.动态权限申请:

  • Android编程中读写私有文件的方法

    本文实例讲述了Android编程中读写私有文件的方法.分享给大家供大家参考,具体如下: 所谓私有文件,则是指程序自己能读取,而其它程序没有权限访问的文件,此文件保存在Data.app.程序包.file目录下面. 其中写文件的方法比较简单: private void writeFile(String fileName, String info) { try { FileOutputStream fout = openFileOutput(fileName, MODE_PRIVATE); byte[

  • Java 解决读写本地文件中文乱码的问题

    Java 解决读写本地文件中文乱码的问题 前言: 在用Java程序进行读写含中文的txt文件时,经常会出现读出或写入的内容会出现乱码.原因其实很简单,就是系统的编码和程序的编码采用了不同的编码格式.通常,假如自己不修改的话,windows自身采用的编码格式是gbk(而gbk和gb2312基本上是一样的编码方式),而IDE中Encode不修改的话,默认是utf-8的编码,这就是为什么会出现乱码的原因.当在OS下手工创建并写入的txt文件(gbk),用程序直接去读(utf-8),就会乱码.为了避免可

  • Json读写本地文件实现代码

    复制代码 代码如下: import java.io.*; /** * Created by tang on 14-3-1. */public class JsonUtils { //从给定位置读取Json文件    public static String readJson(String path){        //从给定位置获取文件        File file = new File(path);        BufferedReader reader = null;       

  • Android入门之使用SharedPreference存取信息详解

    目录 简介 SharedPreference原理 SharedPreference的存储 后端代码 SharedPreferenceHelper.java HomePage.java MainActivity.java 简介 上一篇我们介绍了在android里如何读写本地文件.我们有一种场景,类似网页的cookie,要把用户的一些储如上一次登录.使用的痕迹等信息保存下来以便于每次不需要做重复“填表单”的操作,当在这种场景下我们如果也使用本地文件读写的话显然是“太重”了.因此android提供了一

  • Android如何读写CSV文件方法示例

    前言 本文主要给大家介绍的是关于Android读写CSV文件的相关内容,CSV也就是Comma-Separated Values逗号分隔的文本文件, 读写csv文件和读写普通文件类似:写的时候给数据之间添加上逗号. 设定存储路径和文件名: private static final String FILE_FOLDER = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "AboutVie

  • Android Studio中生成aar文件及本地方式使用aar文件的方法

    主要讲解Android Studio中生成aar文件以及本地方式使用aar文件的方法,具体内容详情如下所示: 在Android Studio中对一个自己库进行生成操作时将会同时生成*.jar与*.aar文件. 分别存储位置: *.jar:库/build/intermediates/bundles/debug(release)/classes.jar *.aar:库/build/outputs/aar/libraryname.aar 两者区别: *.jar:只包含了class文件与清单文件,不包含

  • Android NDK开发(C语言-文件读写)

    目录 1.文件读写 1.1打开文件 1.2关闭文件 1.3读取文件 1.4写入文件 1.5读写二进制I/O文件 1.6获取文件的大小 1.7文本简单加密.解密 1.8二进制文件简单加解密 1.文件读写 一个文件,无论它是文本文件还是二进制文件,都是代表了一系列的字节.C 语言不仅提供了访问顶层的函数,也提供了底层(OS)调用来处理存储设备上的文件. 1.1打开文件 我们可以使用 fopen( ) 函数来创建一个新的文件或者打开一个已有的文件,这个调用会初始化类型 FILE 的一个对象,类型 FI

  • Golang+Android基于HttpURLConnection实现的文件上传功能示例

    本文实例讲述了Golang+Android基于HttpURLConnection实现的文件上传功能.分享给大家供大家参考,具体如下: 这里要演示的是使用Android程序作为客户端(使用HttpURLConnection访问网络),Golang程序作为服务器端,实现文件上传. 客户端代码: public static String uploadFile(String uploadUrl, String filePath) { Log.v(TAG, "url:" + uploadUrl)

  • js 获取本地文件及目录的方法(推荐)

    Javascript是网页制作中离不开的脚本语言,依靠它,一个网页的内容才生动活泼.富有朝气.但也许你还没有发现并应用它的一些更高级的功能吧?比如,对文件和文件夹进行读.写和删除,就象在VB.VC等高级语言中经常做的工作一样.怎么样,你是否需要了解这方面的知识?那就请跟我来,本文将详细描述如何使用Javascript语言进行文件操作. 一.功能实现核心:FileSystemObject 对象 其实,要在Javascript中实现文件操作功能,主要就是依靠FileSystemobject对象.在详

随机推荐