Android开发实现内部和外部存储文件

news/2024/7/16 9:28:06

Android开发实现内部和外部存储文件

效果图:
在这里插入图片描述
activity_main.xml代码:

<?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:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:orientation="horizontal">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="文件名字:"
                android:textSize="35dp"></TextView>

            <EditText
                android:id="@+id/et_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="35dp"></EditText>
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="文件内容:"
                android:textSize="35dp"></TextView>

            <EditText
                android:id="@+id/et_content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="35dp"></EditText>
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp">
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20dp"
                android:layout_weight="1"
                android:text="存入INTERNAL文件"
                android:onClick="Save_in"></Button>
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20dp"
                android:layout_weight="1"
                android:text="存入EXTERNAL文件"
                android:onClick="Save_ex"></Button>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Internal文件内容:"
                android:textSize="30dp">

            </TextView>
            <TextView
                android:id="@+id/incontent"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="30dp">
            </TextView>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="External文件内容:"
                android:textSize="30dp">

            </TextView>
            <TextView
                android:id="@+id/excontent"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="30dp">
            </TextView>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp">
            <Button
                android:layout_weight="1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20dp"
                android:text="从INTERNAL取文件"
                android:onClick="Out_in"></Button>
            <Button
                android:layout_weight="1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20dp"
                android:text="从EXTERNAL取文件"
                android:onClick="Out_ex"></Button>
        </LinearLayout>
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java代码:

package com.henu.saveinfile;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.file.FileVisitOption;

public class MainActivity extends AppCompatActivity {
    private EditText et_name;
    private EditText et_content;
    private TextView tv_in_content;
    private TextView tv_ex_content;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_name = (EditText) findViewById(R.id.et_name);
        et_content = (EditText) findViewById(R.id.et_content);
        tv_in_content = (TextView) findViewById(R.id.incontent);
        tv_ex_content = (TextView) findViewById(R.id.excontent);

        //弹出请求获取存储权限的对话框
        int REQUEST_EXTERNAL_STORAGE = 1;
        String[] PERMISSIONS_STORAGE = {
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
        };
        int permission = ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (permission != PackageManager.PERMISSION_GRANTED) {
            // We don't have permission so prompt the user
            ActivityCompat.requestPermissions(
                    MainActivity.this,
                    PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE
            );
        }
    }
//存入内部存储区
    public void Save_in(View v) {
        FileOutputStream fos;
        try {
            fos = openFileOutput(et_name.getText().toString().trim(), Context.MODE_PRIVATE);
            fos.write(et_content.getText().toString().trim().getBytes());
            fos.close();
            Toast.makeText(this, "存入内部成功", Toast.LENGTH_SHORT).show();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
//从内部存储区取出文件并显示
    public void Out_in(View v) {

        FileInputStream fis;
        try {
            fis = openFileInput(et_name.getText().toString().trim());
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            tv_in_content.setText(getFilesDir() + "/" + et_name.getText().toString().trim() + ".txt" + ":" + new String(buffer));
            fis.close();
            Toast.makeText(this, "从内部读取成功", Toast.LENGTH_SHORT).show();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
//判断外部存储区是否可用
    public boolean isExternalStorageWritable() {
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            return true;
        }
        return false;
    }
    //把文件存入外部存储区
    public void Save_ex(View v) {
        if (isExternalStorageWritable()) {
            File file = new File(Environment.getExternalStorageDirectory(), et_name.getText().toString().trim() + ".txt");
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(file);
                fos.write(et_content.getText().toString().trim().getBytes());
                Toast.makeText(this, "创建成功", Toast.LENGTH_SHORT).show();
            } catch (FileNotFoundException e) {
                Toast.makeText(this, "请允许\"SavelInFile\"访问您设备上的照片、\n" +
                        "媒体内容和文件\n", Toast.LENGTH_LONG).show();
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            Toast.makeText(this, "外部存储区不可用", Toast.LENGTH_SHORT).show();
        }

    }
//取出外部文件并显示出来
    public void Out_ex(View v) {
        File file = new File(Environment.getExternalStorageDirectory(), et_name.getText().toString().trim() + ".txt");
        FileInputStream fis;
        try {
            fis = new FileInputStream(file);
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            tv_ex_content.setText(Environment.getExternalStorageDirectory().getPath() + "/" + et_name.getText().toString().trim() + ".txt" + ":" + new String(buffer));
            Toast.makeText(this, "从外部读取成功", Toast.LENGTH_SHORT).show();
            fis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

AndroidManifest.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.henu.saveinfile">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>//获取外部存储区写的权限(有了写的权限就能有了读的权限)
    <application
        android:requestLegacyExternalStorage="true"//停用分区存储
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.SaveInFile">
        <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>

遇到的问题:
在外部存储文件时老是报错:FileNotFoundException,找不到文件。一般这样的问题有两个原因,一个是路径错误,一个是没有权限。我这是在创建文件时报错,所以原因是后者。但是我已经在AndroidManifest.xml文件中加入android:name=“android.permission.WRITE_EXTERNAL_STORAGE”/>获取到权限了,为什么还是报错。原来是安卓6版本以上,需要获取运行时权限。我又在加上对话框,在初次进入时弹出询问用户获取权限。在这里插入图片描述
但是还是报错,FileNotFoundException。查了下原因,原来是Android 10之前,Android的文件存储现象就像个垃圾桶,但凡app取得了存储空间的读写权限WRITE_EXTERNAL_STORAGE,就可以肆意创建文件,难以管理。用户体验也特别差,打开文件管理器,会发现,想找个具体的文件根本无从下手。为了更好地管理自己的文件并减少混乱,加强隐私保护,Android Q开始引入了分区存储机制。外部存储空间被重新设计,按应用私有和公用共享划分。应用只能访问到自己私有空间,或者通过MediaStore API 和Storage Access Framework去访问共享的资源目录。
关闭了分区存储:android:requestLegacyExternalStorage="true"就能和原来一样在外部存储区肆意创建文件了 哈哈
在这里插入图片描述

参考https://zhuanlan.zhihu.com/p/351713186
参考https://blog.csdn.net/qxs965266509/article/details/50606385?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161760026116780265414814%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=161760026116780265414814&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-50606385.pc_search_result_no_baidu_js&utm_term=Android+filenotfoundexception


http://www.niftyadmin.cn/n/3649785.html

相关文章

[Domino]使用DIIOP必须作的DOMINO手动设置

使用DIIOP必须作的DOMINO手动设置编写者日期关键词郑昀ultrapower2005-6-26Java Domino Configuration应用场景通过DIIOP访问Domino R6服务器&#xff0c;必须在服务器端手动配置本文讲述的三个地方。Lotus Domino服务的启动设置必须有DIIOP请您检查Domino Server是否把DIIOP任…

flutter中的动画效果_Flutter中的基本动画

flutter中的动画效果While Flutter has an enormous amount of amazing packages for creating animation effects for your apps, there are also built-in methods for manually creating more fine-tuned animations. 尽管Flutter提供了大量令人惊叹的软件包&#xff0c;可为…

Android使用SharedPreferneces存储数据

Android使用SharedPreferneces存储数据 实现效果&#xff1a; java代码&#xff1a; package com.henu.sharedpreferences;import androidx.appcompat.app.AppCompatActivity;import android.content.Context; import android.content.SharedPreferences; import android.os.…

typescript 模块_TypeScript中的模块增强

typescript 模块Before getting into module augmentation, let’s look at some TypeScript merging principles which will become useful as we progress. 在进行模块扩充之前&#xff0c;让我们看一下一些TypeScript合并原理&#xff0c;这些原理将随着我们的进步而变得有用…

阴阳怕懵懂吗?

阴阳怕懵懂吗&#xff1f;郑昀 20060621 最近看来势必要有一批人跟着麦田的《 阴阳怕懵懂&#xff0c;说说“无名小站” - 麦田的读书生活 》和方兴东的《 创业者最核心的品质是什么&#xff1f;对模糊性的高度容忍--方兴东观察》的博文继续往下谈。嗯&#xff0c;这就是话题的…

Android开发使用SQLite数据库和Listview实现数据的存储与展示

Android开发使用SQLite数据库和Listview实现数据的存储与展示 实现效果&#xff1a; 使用了SimpleCursorAdapter方便数据库和listview之间的数据传递。 MainActivity.java&#xff1a; package com.henu.saveindatabase;import androidx.appcompat.app.AppCompatActivity;i…

js更改css属性_CSS会更改属性:何时以及何时不使用它

js更改css属性The will-change CSS property is commonly misunderstood or not used correctly, in this short post I will demystify the property so you can make your CSS animations and transitions as performant as possible. will-change CSS属性通常被误解或使用不…

在不断地试错中调整向前

在不断地试错中调整向前郑昀 20060619 几个月前的这两篇文章《Web2.0创业&#xff1a;程序员的创业&#xff1f; - 玩火者的自白 - 邱致中的IT博客》和《Web2.0创业&#xff1a;需要什么样的团队》说的模模糊糊&#xff0c;我们看得也是懵懵懂懂。本来许多事情就是要在不断地…