📜  Android中的外部存储示例

📅  最后修改于: 2021-05-08 20:26:29             🧑  作者: Mango

Android提供了多种选项来存储应用程序数据,这些数据使用类似于计算机平台上基于磁盘的系统的文件系统

  • 特定应用程序的存储:将数据文件存储在内部卷目录中或外部。这些数据文件仅供应用程序使用。它使用内部存储目录来保存敏感信息,例如其他应用程序不应访问的用户名和密码。
  • 共享存储:存储应用可能需要与其他应用共享的数据文件,例如图像,音频,视频,文档等。
  • 共享首选项:以键-值对的形式存储原始数据类型,例如integer,float,boolean, 字符串和long。
  • 数据库:将结构化数据(例如用户信息(姓名,年龄,电话,电子邮件,地址等))存储到私有数据库中。

建议开发人员使用可选的选项来存储数据,具体取决于所需的空间可靠的数据访问数据保密性。通过USB大容量存储传输,可以在共享的外部存储上公开访问通过外部存储设备保存的数据文件。数据文件使用FileOutputStream对象存储在外部存储中,并且可以使用FileInputStream对象读取

外部存储空间可用性

为了避免首先导致应用崩溃,我们需要检查存储SD卡是否可用于读写操作。方法getExternalStorageState()用于确定已挂载的存储介质(例如SD卡)的状态是否丢失,只读或可读且可写。下面是代码片段,我们将使用这些代码片段来检查外部存储设备的可用性。

Java
boolean isAvailable= false;
boolean isWritable= false;
boolean isReadable= false;
String state = Environment.getExternalStorageState();
  
if(Environment.MEDIA_MOUNTED.equals(state)) {
  // Operation possible - Read and Write
  isAvailable= true;
  isWritable= true;
  isReadable= true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
      // Operation possible - Read Only
      isAvailable= true;
      isWritable= false;
      isReadable= true;
} else {
      // SD card not available
      isAvailable = false;
      isWritable= false;
      isReadable= false; 
}


XML

    
    
    
    
        
          ...
        
    


XML

  ...
    Enter the Text Data
    Enter your information
    View Information
    Save Publicly
    Save Privately
  
    Saved Text Data
    Click to view saved information
    Go Back
    Public Data
    Private Data
  ...


XML
   
    #0F9D58
    #16E37F
    #03DAC5
  
    #0F9D58
    #FFFFFF


XML


  
    
  
    
  
    
  
    
  


XML


  
    


Java
import android.Manifest;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
  
public class MainActivity extends AppCompatActivity {
  
    // After API 23 the permission request for accessing external storage is changed
    // Before API 23 permission request is asked by the user during installation of app
    // After API 23 permission request is asked at runtime
    private int EXTERNAL_STORAGE_PERMISSION_CODE = 23;
    EditText editText;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
          
        // findViewById return a view, we need to cast it to EditText View
        editText = (EditText) findViewById(R.id.editText_data);
    }
  
    public void savePublicly(View view) {
        // Requesting Permission to access External Storage
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 
                EXTERNAL_STORAGE_PERMISSION_CODE);
        String editTextData = editText.getText().toString();
          
        // getExternalStoragePublicDirectory() represents root of external storage, we are using DOWNLOADS
        // We can use following directories: MUSIC, PODCASTS, ALARMS, RINGTONES, NOTIFICATIONS, PICTURES, MOVIES
        File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
          
        // Storing the data in file with name as geeksData.txt
        File file = new File(folder, "geeksData.txt");
        writeTextData(file, editTextData);
        editText.setText("");
    }
  
    public void savePrivately(View view) {
        String editTextData = editText.getText().toString();
          
        // Creating folder with name GeekForGeeks
        File folder = getExternalFilesDir("GeeksForGeeks");
          
        // Creating file with name gfg.txt
        File file = new File(folder, "gfg.txt");
        writeTextData(file, editTextData);
        editText.setText("");
    }
  
    public void viewInformation(View view) {
        // Creating an intent to start a new activity
        Intent intent = new Intent(MainActivity.this, ViewInformationActivity.class);
        startActivity(intent);
    }
  
    // writeTextData() method save the data into the file in byte format
    // It also toast a message "Done/filepath_where_the_file_is_saved"
    private void writeTextData(File file, String data) {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(data.getBytes());
            Toast.makeText(this, "Done" + file.getAbsolutePath(), Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}


XML


  
    


Java
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
  
public class ViewInformationActivity extends AppCompatActivity {
  
    TextView textView;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_information);
          
        // findViewById returns a view, we need to cast it into TextView
        textView = (TextView) findViewById(R.id.textView_get_saved_data);
    }
  
    public void showPublicData(View view) {
        // Accessing the saved data from the downloads folder
        File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
          
        // geeksData represent the file data that is saved publicly
        File file = new File(folder, "geeksData.txt");
        String data = getdata(file);
        if (data != null) {
            textView.setText(data);
        } else {
            textView.setText("No Data Found");
        }
    }
  
    public void showPrivateData(View view) {
          
        // GeeksForGeeks represent the folder name to access privately saved data
        File folder = getExternalFilesDir("GeeksForGeeks");
          
        // gft.txt is the file that is saved privately
        File file = new File(folder, "gfg.txt");
        String data = getdata(file);
        if (data != null) {
            textView.setText(data);
        } else {
            textView.setText("No Data Found");
        }
    }
  
    public void back(View view) {
        Intent intent = new Intent(ViewInformationActivity.this, MainActivity.class);
        startActivity(intent);
    }
  
    // getdata() is the method which reads the data
    // the data that is saved in byte format in the file
    private String getdata(File myfile) {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(myfile);
            int i = -1;
            StringBuffer buffer = new StringBuffer();
            while ((i = fileInputStream.read()) != -1) {
                buffer.append((char) i);
            }
            return buffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}


在外部存储中存储数据的方法

  • getExternalStoragePublicDirectory():这是目前建议的使文件保持公开状态的方法,即使从系统中卸载了应用程序,也不会删除这些文件。例如:即使在我们卸载相机后,相机单击的图像仍然可用。
  • getExternalFilesDir(String type):此方法用于存储仅特定于应用程序的私有数据。并在我们卸载应用程序时删除了数据。
  • getExternalStorageDirectory():不建议使用此方法。现在它是绝对的,并且用于访问API级别低于7的旧版本中的外部存储。

例子

在此示例中,我们将文本数据存储到外部存储中并获取以查看该数据。下面给出了一个示例GIF,以了解我们将在本文中做些什么注意,我们将使用Java语言实现该项目。

Android中的ExternalStorage

分步实施

步骤1:创建一个新项目

要在Android Studio中创建新项目,请参阅如何在Android Studio中创建/启动新项目。请注意,选择Java作为编程语言。

步骤2:外部存储的访问权限

要将数据读取和写入外部存储,该应用程序需要WRITE_EXTERNAL_STORAGEREAD_EXTERNAL_STORAGE系统权限。这些权限将添加到AndroidManifest.xml文件中。在软件包名称之后添加这些权限。

XML格式


    
    
    
    
        
          ...
        
    

步骤3:在创建布局和相应的Java文件之前,让我们添加一些在布局文件中使用的字符串属性

转到应用程序> res>值>字符串.xml并插入以下代码段

XML格式


  ...
    Enter the Text Data
    Enter your information
    View Information
    Save Publicly
    Save Privately
  
    Saved Text Data
    Click to view saved information
    Go Back
    Public Data
    Private Data
  ...

现在转到app> res> values> colors.xml并按如下所示更改颜色属性,以使App Bar更具吸引力。

XML格式

   
    #0F9D58
    #16E37F
    #03DAC5
  
    #0F9D58
    #FFFFFF

再次转到app> res> drawable并创建一个新的Drawable Resource File并将其命名为button_layout 。在此,我们正在修改按钮样式以获得更好的UX / UI。

XML格式



  
    
  
    
  
    
  
    
  

步骤4:使用activity_main.xml文件

转到res> layout> activity_main.xml并写下以下代码。在此布局文件中,我们将创建一个多行EditText视图,用于从用户和Button获取数据,以将这些数据保存在内部和外部存储介质上。

XML格式



  
    

步骤5:使用MainActivity。 Java文件

在MainActivity中,我们定义了处理按钮的onClick行为的函数。然后从EditText获取数据,并将其公开和私下保存在外部存储中。我们还将显示有关数据存储路径的Toast消息。

Java

import android.Manifest;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
  
public class MainActivity extends AppCompatActivity {
  
    // After API 23 the permission request for accessing external storage is changed
    // Before API 23 permission request is asked by the user during installation of app
    // After API 23 permission request is asked at runtime
    private int EXTERNAL_STORAGE_PERMISSION_CODE = 23;
    EditText editText;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
          
        // findViewById return a view, we need to cast it to EditText View
        editText = (EditText) findViewById(R.id.editText_data);
    }
  
    public void savePublicly(View view) {
        // Requesting Permission to access External Storage
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 
                EXTERNAL_STORAGE_PERMISSION_CODE);
        String editTextData = editText.getText().toString();
          
        // getExternalStoragePublicDirectory() represents root of external storage, we are using DOWNLOADS
        // We can use following directories: MUSIC, PODCASTS, ALARMS, RINGTONES, NOTIFICATIONS, PICTURES, MOVIES
        File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
          
        // Storing the data in file with name as geeksData.txt
        File file = new File(folder, "geeksData.txt");
        writeTextData(file, editTextData);
        editText.setText("");
    }
  
    public void savePrivately(View view) {
        String editTextData = editText.getText().toString();
          
        // Creating folder with name GeekForGeeks
        File folder = getExternalFilesDir("GeeksForGeeks");
          
        // Creating file with name gfg.txt
        File file = new File(folder, "gfg.txt");
        writeTextData(file, editTextData);
        editText.setText("");
    }
  
    public void viewInformation(View view) {
        // Creating an intent to start a new activity
        Intent intent = new Intent(MainActivity.this, ViewInformationActivity.class);
        startActivity(intent);
    }
  
    // writeTextData() method save the data into the file in byte format
    // It also toast a message "Done/filepath_where_the_file_is_saved"
    private void writeTextData(File file, String data) {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(data.getBytes());
            Toast.makeText(this, "Done" + file.getAbsolutePath(), Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

步骤6:建立新的空白活动

我们将创建一个新活动并将其命名为ViewInformationActivity 。我们使用此活动来显示外部存储器中保存的数据。因此,首先,我们为此活动创建一个与MainActivity布局相似的布局。 activity_view_information.xml布局代码段:

XML格式



  
    

现在,我们将为ViewInformationActivity创建一个相应的Java代码。在此,我们在按钮上定义了showPublicData()showPrivateData()方法,这些方法将从保存到外部存储的文件中获取数据,并将数据添加到缓冲区,然后将数据填充到TextView中以显示它们。 ViewInformationAcitity。 Java代码段:

Java

import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
  
public class ViewInformationActivity extends AppCompatActivity {
  
    TextView textView;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_information);
          
        // findViewById returns a view, we need to cast it into TextView
        textView = (TextView) findViewById(R.id.textView_get_saved_data);
    }
  
    public void showPublicData(View view) {
        // Accessing the saved data from the downloads folder
        File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
          
        // geeksData represent the file data that is saved publicly
        File file = new File(folder, "geeksData.txt");
        String data = getdata(file);
        if (data != null) {
            textView.setText(data);
        } else {
            textView.setText("No Data Found");
        }
    }
  
    public void showPrivateData(View view) {
          
        // GeeksForGeeks represent the folder name to access privately saved data
        File folder = getExternalFilesDir("GeeksForGeeks");
          
        // gft.txt is the file that is saved privately
        File file = new File(folder, "gfg.txt");
        String data = getdata(file);
        if (data != null) {
            textView.setText(data);
        } else {
            textView.setText("No Data Found");
        }
    }
  
    public void back(View view) {
        Intent intent = new Intent(ViewInformationActivity.this, MainActivity.class);
        startActivity(intent);
    }
  
    // getdata() is the method which reads the data
    // the data that is saved in byte format in the file
    private String getdata(File myfile) {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(myfile);
            int i = -1;
            StringBuffer buffer = new StringBuffer();
            while ((i = fileInputStream.read()) != -1) {
                buffer.append((char) i);
            }
            return buffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

输出:在模拟器上运行

想要一个节奏更快,更具竞争性的环境来学习Android的基础知识吗?
单击此处,前往由我们的专家精心策划的指南,以使您立即做好行业准备!