Android的数据存储:SharedPrefrence存储,手机内部文件存储,手机外部文件存储

存储方式分类

Android支持的数据存储方式:
	SharedPrefrence存储
	手机内部文件存储
	手机外部文件存储
	Sqlite数据库存储
	远程服务器存储

在这里插入图片描述

SharedPrefrence存储

介绍
SP存储专门用来存储一些单一的小数据
存储数据的类型:  boolean, float, int, long, String
数据保存的路径:  /data/data/packageName/shared_prefs/yyy.xml
可以设置数据只能是当前应用读取, 而别的应用不可以
应用卸载时会删除此数据
API
SharedPreferences: 对应sp文件的接口,是个接口
	context. getSharedPreferences (String name, int mode): 得到SP对象
		name: 文件名(不带.xml)
		mode: 生成的文件模式(是否是私有的,即其它应用是否可以访问)
	SharedPreferences可以得到这个存储的数据,
	但是不能修改它,修改操作由Editor对象来操作
	
	Editor sp.edit() : 得到Editor对象
	Xxx sp.getXxx(name,defaultValue): 根据name得到对应的数据
	
Editor : 能更新sp文件的接口
	Editor put(name, value) : 保存一个键值对, 没有真正保存到文件中
	Editor remove(name)
	commit(): 提交, 数据真正保存到文件中了
例子
package com.example.datastorage;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class SpActivity extends Activity
{
	public EditText et_sp_key;
	public EditText et_sp_value;
	
	public SharedPreferences sp;
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_sp);
		et_sp_key=(EditText) findViewById(R.id.et_sp_key);
		et_sp_value=(EditText) findViewById(R.id.et_sp_value);
		
		//1.得到sp对象
		sp=getSharedPreferences("jane", Context.MODE_PRIVATE);
	}
	public void save(View v)
	{
		//2.得到editor对象
		Editor edit = sp.edit();
		//3.得到输入的key和value
		String key=et_sp_key.getText().toString();
		String value=et_sp_value.getText().toString();
		//4.使用editor保存
		edit.putString(key, value).commit();
		Toast.makeText(this, "ok了", 0).show();
	}
	public void read(View v)
	{
		String key=et_sp_key.getText().toString();
		String value = sp.getString(key, null);
		if(value==null)
		{
			Toast.makeText(this, "没有这个值", 0).show();
		}
		else
		{
			et_sp_value.setText(value);
		}
	}
}

手机内部文件存储

介绍
应用运行需要的一些较大的数据或图片可以用文件保存的手机内部
文件类型: 任意
数据保存的路径: /data/data/projectPackage/files/
可以设置数据只能是当前应用读取, 而别的应用不可以
应用卸载时会删除此数据
API
读取文件
	FileInputStream fis = openFileInput("logo.png");
保存文件
	FileOutputStream fos = openFileOutput("logo.png", MODE_PRIVATE)
得到files文件夹对象
	File filesDir = getFilesDir();  
操作asserts下的文件
	得到AssetManager : context.getAssets();
	读取文件: InputStream open(filename);
加载图片文件
	Bitmap BitmapFactory.decodeFile(String pathName)   // .bmp/.png/.jpg
例子
package com.example.datastorage;

import java.io.FileOutputStream;
import java.io.InputStream;
import android.app.Activity;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

public class IFActivity extends Activity
{
	private ImageView iv_if;
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_if);
		iv_if=(ImageView) findViewById(R.id.iv_if);
	}
	public void save(View v) throws Exception
	{
		//1.先得到InputStream,用来读取assets下的logo.png
		//2.得到OutputStream,用来输出data/data/packageName/files/logo.png
		AssetManager manager = getAssets();
		InputStream is = manager.open("logo.png");
		
		FileOutputStream fos = openFileOutput("logo.png", Context.MODE_PRIVATE);
		
		//3.边读边写
		byte[] buffer =new byte[1024];
		int len=-1;
		while((len=is.read(buffer))!=-1)
		{
			fos.write(buffer, 0, len);
		}
		fos.close();
		is.close();
		Toast.makeText(this, "保存完成", 0).show();
	}
	public void read(View v)
	{
		//1.得到图片问价路径
		String path = getFilesDir().getAbsolutePath();
		String imagePath=path+"/logo.png";
		//2.读取加载图片文件得到bitmap对象
		Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
		//3.将它设置到imageView中显示
		iv_if.setImageBitmap(bitmap);
	}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:text="1. 将asserts下的logo.png保存到手机内部\n2. 读取手机内部图片文件显示"
        android:textColor="#ff0000"
        android:textSize="15sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/btn_if_save"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="save"
            android:text="保 存" />

        <Button
            android:id="@+id/btn_if_read"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="read"
            android:text="读 取" />
    </LinearLayout>

    <ImageView
        android:id="@+id/iv_if"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />
</LinearLayout>

手机外部文件存储

介绍
应用运行用到的数据文件(如图片)可以保存到sd卡中
文件类型: 任意
数据保存的路径: 
	路径1: /storage/sdcard/Android/data/packageName/files/
	路径2: /storage/sdcard/xxx/
路径1 :其它应用可以访问,应用卸载时删除
路径2 : 其它应用可以访问, 应用卸载时不会删除
必须保证sd卡挂载在手机上才能读写, 否则不能操作
API
Environment :  操作SD卡的工具类
	得到SD卡的状态:Environment.getExternalStorageState() 
	得到SD卡的路径:Environment.getExternalStorageDirectory()
	SD卡可读写的挂载状态值:Environment.MEDIA_MOUNTED

context. getExternalFilesDir():  
	得到/mnt/sdcard/Android/data/pageckage_name/files/xxx.txt

操作SD卡的权限:
	android.permission.WRITE_EXTERNAL_STORAGE
例子
package com.example.datastorage;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class OFActivity extends Activity
{
	private EditText et_of_name;
	private EditText et_of_content;
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_of);
		et_of_name=(EditText) findViewById(R.id.et_of_name);
		et_of_content=(EditText) findViewById(R.id.et_of_content);
	}
	public void save(View v) throws Exception
	{
		/*
		 * 1.判断sd卡的状态,如果是挂载的状态才可以继续,否则就提示
		 * 2.读取输入的文件名/没人
		 * 3.得到指定文件的OutputSteam
		 * 		1)得到sd卡下的files路径
		 * 		2)组成完整的路径
		 * 		3)创建FileOutputStream
		 * 4.写出数据
		 */
		if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
		{
			String fileName = et_of_name.getText().toString();
			String context = et_of_content.getText().toString();
			/*
		         * @param type The type of files directory to return.  May be null for
			     * the root of the files directory or one of
			     * the following Environment constants for a subdirectory:
			     * {@link android.os.Environment#DIRECTORY_MUSIC},
			     * {@link android.os.Environment#DIRECTORY_PODCASTS},
			     * {@link android.os.Environment#DIRECTORY_RINGTONES},
			     * {@link android.os.Environment#DIRECTORY_ALARMS},
			     * {@link android.os.Environment#DIRECTORY_NOTIFICATIONS},
			     * {@link android.os.Environment#DIRECTORY_PICTURES}, or
			     * {@link android.os.Environment#DIRECTORY_MOVIES}.
			    getExternalFilesDir需要一个type的参数,如果传入的是null,
			    那么就是代表外存的file根目录自己,
			    如果是DIRECTORY_MUSIC,就会在files目录下面再创建一个movies目录,
			    然后再将文件放进去
			 */
			String filesPath = getExternalFilesDir(null).getAbsolutePath();
			String filePath= filesPath +"/"+fileName;
			FileOutputStream fos =new FileOutputStream(filePath);
			fos.write(context.getBytes("UTF-8"));
			fos.close();
			Toast.makeText(this, "保存完成", 0).show();
		}
		else
		{
			Toast.makeText(this, "sd卡不存在", 0).show();			
		}
	}
	public void read(View v) throws Exception
	{
		if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
		{
			String fileName = et_of_name.getText().toString();
			String filesPath = getExternalFilesDir(null).getAbsolutePath();
			String filePath= filesPath +"/"+fileName;
			FileInputStream fis = new FileInputStream(filePath);
			
			ByteArrayOutputStream baos=new ByteArrayOutputStream();
			byte[] buffer =new byte[1024];
			int len= -1;
			while((len=fis.read(buffer))!=-1)
			{
				baos.write(buffer,0,len);
			}
			String context =baos.toString();
			et_of_content.setText(context);
		}
		else
		{
			Toast.makeText(this, "sd卡不存在", 0).show();			
		}
	}
	public void save2(View v) throws Exception
	{
		if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
		{
			String fileName = et_of_name.getText().toString();
			String context = et_of_content.getText().toString();
			
			//得到指定文件的FileOutputStream
				//1). /storage/sdcard/
				//2). /storage/sdcard/jane/(创建文件夹)
				//3). /storage/sdcard/jane/xxx.txt
			String sdpath = Environment.getExternalStorageDirectory().getAbsolutePath();
			File file = new File(sdpath+"/jane");
			if(!file.exists())
			{
				file.mkdir();
			}
			
			String filePath = sdpath+"/jane/"+fileName;
			FileOutputStream fos =new FileOutputStream(filePath);
			fos.write(context.getBytes("UTF-8"));
			fos.close();
			Toast.makeText(this, "保存完成", 0).show();
		}
		else
		{
			Toast.makeText(this, "sd卡不存在", 0).show();			
		}
	}
	public void read2(View v) throws Exception
	{
		if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
		{
			String fileName = et_of_name.getText().toString();
			String sdpath = Environment.getExternalStorageDirectory().getAbsolutePath();
			String filePath = sdpath+"/jane/"+fileName;
			
			FileInputStream fis = new FileInputStream(filePath);
			
			ByteArrayOutputStream baos=new ByteArrayOutputStream();
			byte[] buffer =new byte[1024];
			int len= -1;
			while((len=fis.read(buffer))!=-1)
			{
				baos.write(buffer,0,len);
			}
			String context =baos.toString();
			et_of_content.setText(context);
			fis.close();
		}
		else
		{
			Toast.makeText(this, "sd卡不存在", 0).show();			
		}
	}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/et_of_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="存储的文件名" />

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="save"
            android:text="保 存" />
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="read"
            android:text="读 取" />
    </LinearLayout>
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="save2"
            android:text="保 存2" />
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="read2"
            android:text="读 取2" />
    </LinearLayout>
</LinearLayout>

例子

修改应用名称
package com.example.apphouse;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.TextView;

public class MainActivity extends Activity implements OnItemLongClickListener
{
	/*
	 * 现在需要给里面的item添加长按,然后实现修改名称的功能
	 * 现在需要给gridView的item添加长按监听
	 * 在回调方法里面实现AlertDialog
	 * 然后需要处理点击修改,
	 * 		需要更新界面,
	 * 		还需要将名称保存到sp中
	 * 还需要保证退出后再进入显示的是修改过的名称
	 */
	private GridView gridView;
	private MyAdapter myAdapter;
	
	private SharedPreferences sp;
	
	String[] names = new String[] { "手机防盗", "通讯卫士", "软件管理", "流量管理", "进程管理",
			"手机杀毒", "缓存清理", "高级工具", "设置中心" };

	int[] icons = new int[] { R.drawable.widget01, R.drawable.widget02,
			R.drawable.widget03, R.drawable.widget04, R.drawable.widget05,
			R.drawable.widget06, R.drawable.widget07, R.drawable.widget08,
			R.drawable.widget09 };
	
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		gridView =(GridView) findViewById(R.id.gridView1);
		myAdapter=new MyAdapter(this, names, icons);
		
		gridView.setAdapter(myAdapter);
		
		gridView.setOnItemLongClickListener(this);
		
		sp=getSharedPreferences("jane", Context.MODE_PRIVATE);
	}

	@Override
	public boolean onItemLongClick(AdapterView<?> parent, View view,
			int position, long id)
	{
		if(position==0)
		{
			//得到当前显示的名称
			final TextView textview = (TextView) view.findViewById(R.id.name);
			String name = textview.getText().toString();
			//为dialog准备输入框对象
			final EditText editText =new EditText(this);
			editText.setHint(name);
			//显示AlertDialog
			new AlertDialog.Builder(this)
				.setTitle("修改名称")
				.setView(editText)
				.setPositiveButton("修改", new DialogInterface.OnClickListener()
				{
					@Override
					public void onClick(DialogInterface dialog, int which)
					{
						String newName = editText.getText().toString();
						//更新界面
						textview.setText(newName);
						//将名称保存到sp中,注意呀,一定要commit(),不然没法保存
						sp.edit().putString("NAME", newName).commit();
					}
				})
				.setNegativeButton("Cancel", null)
				.show();
		}
		return true;
	}
}
package com.example.apphouse;

import android.content.Context;
import android.content.SharedPreferences;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class MyAdapter extends BaseAdapter
{
	public Context context;
	public String[] names;
	public int[] icons;
	
	private SharedPreferences sp;
	
	public MyAdapter(Context context, String[] names, int[] icons)
	{
		super();
		this.context = context;
		this.names = names;
		this.icons = icons;
		sp=context.getSharedPreferences("jane", context.MODE_PRIVATE);
	}

	@Override
	public int getCount()
	{
		return names.length;
	}

	@Override
	public Object getItem(int position)
	{
		return names[position];
	}

	@Override
	public long getItemId(int position)
	{
		return 0;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent)
	{
		if(convertView==null)
		{
			convertView=View.inflate(context, R.layout.grid_view_item, null);
		}
		//然后将对应数据设置到对应的位置
		ImageView imageView = (ImageView) convertView.findViewById(R.id.icon);
		TextView textView = (TextView) convertView.findViewById(R.id.name);
		imageView.setImageResource(icons[position]);
		textView.setText(names[position]);
		
		if(position==0)
		{
			//从sp中读取保存的名称,如果存在就显示
			String saveName =sp.getString("NAME", null);
			if(saveName!=null)
			{
				textView.setText(saveName);
			}
		}
		return convertView;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReflectMirroring

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值