• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

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

互联网 diligentman 2周前 (04-07) 7次浏览

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

效果图:
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版本以上,需要获取运行时权限。我又在加上对话框,在初次进入时弹出询问用户获取权限。Android开发实现内部和外部存储文件
但是还是报错,FileNotFoundException。查了下原因,原来是Android 10之前,Android的文件存储现象就像个垃圾桶,但凡app取得了存储空间的读写权限WRITE_EXTERNAL_STORAGE,就可以肆意创建文件,难以管理。用户体验也特别差,打开文件管理器,会发现,想找个具体的文件根本无从下手。为了更好地管理自己的文件并减少混乱,加强隐私保护,Android Q开始引入了分区存储机制。外部存储空间被重新设计,按应用私有和公用共享划分。应用只能访问到自己私有空间,或者通过MediaStore API 和Storage Access Framework去访问共享的资源目录。
关闭了分区存储:android:requestLegacyExternalStorage="true"就能和原来一样在外部存储区肆意创建文件了 哈哈
Android开发实现内部和外部存储文件

参考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


程序员灯塔
转载请注明原文链接:Android开发实现内部和外部存储文件
喜欢 (0)