本地数据存储
SharePreferernce
操作模式。存储方案
- MODE_APPEND:追加方式存储
- MODE_PRIVATE:私有方式存储,其他应用无法访问
- MODE_WORLD_PEADABLE:可被其他应用读取
- MODE_WORLD_WRITEABLE:可被其他应用写入
存储
ShareActivity
package com.example.storagedemo;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class ShareActivity extends AppCompatActivity {
private EditText pwdEdt;
private EditText accEdt;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_share);
accEdt = findViewById(R.id.edt_name);
pwdEdt = findViewById(R.id.edt_pass);
findViewById(R.id.btn_login).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获取两个输入框的内容
String account = accEdt.getText().toString();
String pwd = pwdEdt.getText().toString();
//验证(admin 123)
//存储信息到SharePreference
if("admin".equals(account) && "123".equals(pwd)){
//①获取sharepreference对象
SharedPreferences myshare = getSharedPreferences("myshare", MODE_PRIVATE);//参数1:文件名 参数2:模式
//②获取Editor对象
SharedPreferences.Editor edit = myshare.edit();
//③存储信息
edit.putString("account",account);
edit.putString("pwd",pwd);
//④执行提交操作
edit.commit();
Toast.makeText(ShareActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
}else {
//验证失败,提示用户
Toast.makeText(ShareActivity.this, "账号或密码错误", Toast.LENGTH_SHORT).show();
}
}
});
}
}
activity_share.xml
<?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"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
>
<TextView
android:textSize="25sp"
android:text="账号:"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<EditText
android:id="@+id/edt_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:textSize="25sp"
android:text="密码:"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<EditText
android:id="@+id/edt_pass"
android:inputType="textPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<Button
android:id="@+id/btn_login"
android:layout_margin="10dp"
android:text="登录"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
读取
//①获取sharepreference对象
SharedPreferences myshare = getSharedPreferences("myshare", MODE_PRIVATE);//参数1:文件名 参数2:模式
String account = myshare.getString("account", "");//参数1:key 参数2:当对应key不应存时作为内容
String pwd = myshare.getString("pwd", "");//参数1:key 参数2:当对应key不应存时作为内容
位于 data/data/包名/shard_prefs 文件夹下
外部存储ExternalStorage
- 内存 Memory 容量
- 内部存储 InternalStorage 存放的位置
- 外部存储 ExternalStorage 特殊的位置
存放在storage或者mnt文件夹
可以调用Environment.getExternalStorageDirectory()查看真实外部存储的文件夹
外部目录又分为
- 公有目录(DCIM,DOWNLOAD等)九大共有目录根据名称区分
- 私有目录 (Android/data/应用包名)
所有共有目录的操作需要开启权限
和当前应用相关的放在私有目录下,利于维护
显示路径
TAG: 路径/storage/emulated/0/ws.txt
因为使用的是模拟器所以多了/emulated
观察目录是找不到的,因为将它映射成了sdcard和self目录 self版本不同文件名不同,但是内容是一致的
文件权限
1 2-4 5-7 8-10
位数 | 1 | 2-4 | 5-7(和这个文件同组权限) | 8-10(其他用户可具备权限) |
---|---|---|---|---|
d目录 | r可读 | r可读 | r可读 | |
l映射 | w可写 | w可写 | w可写 | |
x可执行 | x可执行 | x可执行 |
读写操作
MainActivity
package com.example.storagedemo;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_in;
private Button btn_out;
private Button btn_spf;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Viewinit();
btn_spf.setOnClickListener(this);
}
private void Viewinit() {
btn_spf = findViewById(R.id.SharePreference);
btn_out = findViewById(R.id.out);
btn_in = findViewById(R.id.in);
}
@Override
public void onClick(View v) {
Intent intent=new Intent(this,ExternalActivity.class);
startActivity(intent);
}
}
avtivity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:gravity="center"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="300dp">
<Button
android:id="@+id/SharePreference"
android:text="SharePreference演示"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/out"
android:text="外部存储演示"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/in"
android:text="内部存储演示"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
ExternalActivity
package com.example.storagedemo;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class ExternalActivity extends AppCompatActivity {
private TextView txt;
private EditText infoEdt;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_external);
infoEdt = findViewById(R.id.edit_text);
txt = findViewById(R.id.textView);
}
public void opera(View view) {
//拿到根目录的绝对路径 并且在该路径下创建 ws.txt
// String path = Environment.getExternalStorageDirectory().getAbsoluteFile() + "/ws.txt";
String path = "data/data/com.example.storagedemo/ws.txt";
Log.e("TAG", "路径"+path );
//判断是否存在内存卡
/* boolean flag=Environment.getExternalStorageDirectory().equals("mounted");
if(flag){
Log.e("TAG", "存在");
}*/
switch (view.getId()){
case R.id.btn_save:
File file=new File(path);
//判断文件是否存在,不存在则创建一个新的
try {
if(!file.exists()){
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(path, true);//创建输出流写入操作 并且可追加
String ste = infoEdt.getText().toString();
fos.write(ste.getBytes());//以为字节流写入
} catch (IOException e) {
e.printStackTrace();
}
break;
case R.id.btn_read:
try {
FileInputStream fin = new FileInputStream(path);
int len=0;
byte[] bytes=new byte[1024];
if((len=fin.read(bytes))!=-1){
String s = new String(bytes, 0, len);
txt.setText(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
activity_external.xml
<?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"
android:layout_height="match_parent">
<EditText
android:hint="请输入待存储的内容。。。"
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="350dp"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="150dp">
<Button
android:onClick="opera"
android:id="@+id/btn_save"
android:layout_margin="15dp"
android:text="保存"
android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:onClick="opera"
android:id="@+id/btn_read"
android:textSize="20sp"
android:layout_margin="15dp"
android:text="读取"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="200dp"/>
</LinearLayout>
Android平台中,能操作文件夹的只有两个地方:
- sdcard
- data/data//files
一定要检测是否又内存卡,andorid的版本达到6.0以上只在xml配置权限已经不够了,这里我以为是虚拟机,没内存卡。实则是动态权限问题
外部存储动态权限
- 检查权限ContextCompat.checkSelfPermission(context,permission)
- 添加权限ActivityCompat.requestPermission(activity,permissions,code)
ExternalActivity
package com.example.storagedemo;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class ExternalActivity extends AppCompatActivity {
private TextView txt;
private EditText infoEdt;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_external);
infoEdt = findViewById(R.id.edit_text);
txt = findViewById(R.id.textView);
//判断是否有该权限
int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
//若没有被赋予该权限
if(permission!= PackageManager.PERMISSION_GRANTED){
//动态申请权限
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
}
}
//申请权限的过程中 使用code对某一权限做处理
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
public void opera(View view) {
//拿到根目录的绝对路径 并且在该路径下创建 ws.txt
String path = Environment.getExternalStorageDirectory().getAbsoluteFile() + "/ws.txt";
// String path = "data/data/com.example.storagedemo/ws.txt";
Log.e("TAG", "路径"+path );
//判断是否存在内存卡
/* boolean flag=Environment.getExternalStorageDirectory().equals("mounted");
if(flag){
Log.e("TAG", "存在");
}*/
switch (view.getId()){
case R.id.btn_save:
File file=new File(path);
//判断文件是否存在,不存在则创建一个新的
try {
if(!file.exists()){
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(path, true);//创建输出流写入操作 并且可追加
String ste = infoEdt.getText().toString();
fos.write(ste.getBytes());//以为字节流写入
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
case R.id.btn_read:
try {
FileInputStream fin = new FileInputStream(path);
int len=0;
byte[] bytes=new byte[1024];
if((len=fin.read(bytes))!=-1){
String s = new String(bytes, 0, len);
txt.setText(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
发现还是不行 原来andorid版本升级后需要在AndroidManifest.xml给application添加sd卡权限
<application android:requestLegacyExternalStorage="true">
</application>
外部存储私有目录
- Context.getExternalFilesDir(String type)
获取到SDCard/Android/data/包名/files/ 目录 长时间保存 如 应用里的清楚数据
传入的type和九大文件夹有关
- Context.getExternalCacheDir();
获取到SDCard/Android/data/包名/cache/ 目录 临时文件 如应用里的清空缓存
内部存储InternalStorage
data/ 文件夹下两个文件夹 data 和app
- Context.getFileDir()
获取/data/data/包名/files
- Context.getCacheDir()
获取/data/data/包名/cache
内外私有目录对比
目录获取方式 | 位置 | |
---|---|---|
内部存储 | Context.getFileDir() | /data/data/包名/files |
Context.getCacheDir() | /data/data/包名/cache | |
外部存储 | Context.getExternalFilesDir() | SDCard/Android/data/包名/files/ |
Context.getExternalCacheDir() | SDCard/Android/data/包名/cache/ |
操作内部存储
InternalActivity
package com.example.storagedemo;
import android.Manifest;
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 androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class InternalActivity extends AppCompatActivity {
private TextView txt;
private EditText infoEdt;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_internal);
infoEdt = findViewById(R.id.edit_text);
txt = findViewById(R.id.textView);
//判断是否有该权限
int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
//若没有被赋予该权限
if(permission!= PackageManager.PERMISSION_GRANTED){
//动态申请权限
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
}
}
//申请权限的过程中 使用code对某一权限做处理
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
public void opera(View view) {
File file=new File(getFilesDir(),"getFilesDir.txt");
switch (view.getId()){
case R.id.btn_save:
//判断文件是否存在,不存在则创建一个新的
try {
if(!file.exists()){
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(file, true);//创建输出流写入操作 并且可追加
String ste = infoEdt.getText().toString();
fos.write(ste.getBytes());//以为字节流写入
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
case R.id.btn_read:
try {
FileInputStream fin = new FileInputStream(file);
int len=0;
byte[] bytes=new byte[1024];
if((len=fin.read(bytes))!=-1){
String s = new String(bytes, 0, len);
txt.setText(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
activity_internal.xml
<?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"
android:layout_height="match_parent">
<EditText
android:hint="请输入待存储的内容。。。"
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="350dp"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="150dp">
<Button
android:onClick="opera"
android:id="@+id/btn_save"
android:layout_margin="15dp"
android:text="保存"
android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:onClick="opera"
android:id="@+id/btn_read"
android:textSize="20sp"
android:layout_margin="15dp"
android:text="读取"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="200dp"/>
</LinearLayout>
操作内部存储是不需要权限的
3.SQLite数据库存储
(4条消息) 安卓学习笔记_一切从变强开始的博客-CSDN博客