Android学习笔记-数据存储-SharedPreferences和File

Android存储数据的方式

1.Shared Preferences:用来存储“键-值”格式的数据
2.Files:通过IO流对文件进行操作
3.SQLite:标准数据库
4.NetWork:网络存储和获取数据

Shared Preferences

用来保存一些用户设置的参数。例如:可以通过它保存上一次用户所做的修改或者自定义参数设定,重新启动程序后依然保持原有设置
数据以XML文件形式保存,我的Android4.4.2在目录/data/data/PACKAGE_NAME /shared_prefs下。( PACKAGE_NAME为AndroidManifast.xml中的Package
注*:Shared Preferences只能保存基本数据类型,默认情况下,仅在本APP中使用。

使用getPreferences方法创建文件的模式:
Activity.MODE_PRIVATE:默认模式,只能由应用程序调用,私有,每次回重新创建文件
Activity.MODE_APPEND:文件存在,数据写入,不覆盖,可以理解为添加
Activity.MODE_WORLE_READABLE:允许其他应用程序有读取和创建文件的权限
Activity.MODE_WORLE_WRITEABLE:允许其他应用程序有写入、访问和创建的文件权限

对象获取:
Context.getSharedPreferences(String name,int mode) *推荐*
 Activity.getPreferences(int mode)

下面为一个小Demo,用来记住用户姓名:
流程为:
1.WelcomeActivity,欢迎界面,等待三秒中
2.LoginActivity,登录界面,是否记住用户名
3.MainActivity,主界面,退出,销毁所有Activity
(注*:AndroidManifast.xml文件中:
<activity
            android:name=".WelcomeActivity"
            android:label="@string/title_activity_welcome" >
            <!-- 欢迎界面设置为第一个界面 --> 
        	<intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
</activity>
WelcomeActivity:
public class WelcomeActivity extends Activity {
	
	private UserInfoService userInfoService;
	private Handler handler;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_welcome);
		
		ManagerActivities.add(this);
		userInfoService = new UserInfoService();
		
		handler = new Handler(){
			/**
			 * 捕获消息
			 */
			@Override
			public void handleMessage(Message msg) {
				//创建一个意图,用于页面跳转和数据传输
				Intent intent = new Intent();
				switch (msg.what) {
				case 0:
					//设置页面跳转
					intent.setClass(WelcomeActivity.this, LoginActivity.class);
					break;
				case 1:
					intent.setClass(WelcomeActivity.this, MainActivity.class);
					String name = (String) msg.obj;
					//页面之间传输的数据
					intent.putExtra("name",name);
					break;
				}
				//启动意图
				startActivity(intent);
				super.handleMessage(msg);
			}
		};
		
		/**
		 * 睡眠三秒钟
		 */
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				//以私有的模式得到SharedPreferences
				SharedPreferences sp = getSharedPreferences(NamesInterface.FILE_NAME,
							Activity.MODE_PRIVATE);
				//获取文件中的数据
				String name = sp.getString("username", "");
				//判断用户名是否正确
				boolean flag = userInfoService.checkLogin(name);
				Message msg = new Message();
				/**
				 * 发送不同的msg
				 */
				if(flag){
					msg.what = 1;
					msg.obj = name;
				}else{
					msg.what = 0;
				}
				//发送一个消息
				handler.sendMessage(msg);;
			}
		}).start();//启动后台线程	
	}
}
LoginActivity:
package com.edu.pro1124_auto_login;

import com.edu.service.UserInfoService;
import com.edu.util.ManagerActivities;
import com.edu.util.NamesInterface;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;

public class LoginActivity extends Activity {

	private EditText etName;
	private Button btnLogin;
	private CheckBox cbSave;
	
	private UserInfoService userInfoService;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_login);
		ManagerActivities.add(this);
		etName = (EditText) findViewById(R.id.editText1);
		btnLogin = (Button) findViewById(R.id.button1);
		cbSave = (CheckBox) findViewById(R.id.checkBox1);
		this.userInfoService = new UserInfoService();
		//设置监听器
		btnLogin.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				String name = etName.getText()+"";
				//输入格式验证,在Service中验证
				boolean flag = userInfoService.checkLogin(name);
				if(flag){
					//登录成功操作
					//是否需要自动登录
					if(cbSave.isChecked()){
						//保存用户信息
						SharedPreferences sp = getSharedPreferences(NamesInterface.FILE_NAME, MODE_PRIVATE);
						SharedPreferences.Editor edit = sp.edit();
						edit.putString("username", name);
						edit.commit();
					}
					Intent intent = new Intent(LoginActivity.this,MainActivity.class);
					intent.putExtra("username", name);
					startActivity(intent);
				}else{
					//登录失败操作
				}
			}
		});	
	}
}
界面为

选中CheckBox可以记住用户名,下次不用进入登录。

MainActivity:
package com.edu.pro1124_auto_login;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;

import com.edu.util.ManagerActivities;
import com.edu.util.NamesInterface;


public class MainActivity extends Activity {

	private Button main_btn_clear;
	private Button main_btn_exit;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ManagerActivities.add(this);
        
        main_btn_clear = (Button) findViewById(R.id.main_btn_clear);
        main_btn_exit = (Button) findViewById(R.id.main_btn_exit);
        
        main_btn_clear.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				//清除数据,记得commit
				SharedPreferences sp = 
						getSharedPreferences(NamesInterface.FILE_NAME, MODE_PRIVATE);
				SharedPreferences.Editor editor = sp.edit();
				editor.clear();
				editor.commit();
			}
		});
        
        main_btn_exit.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				//退出所有Activity
				ManagerActivities.exit();
			}
		});
    }
}
界面就添加了两个按钮:
 <Button
        android:id="@+id/main_btn_exit" />

 <Button
        android:id="@+id/main_btn_clear" />

两个帮助类:
package com.edu.util;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;

/**
 * 记录所有启动的Activity,统一销毁
 * @author new
 *
 */
public class ManagerActivities {

	private static List<Activity> activities =
		new ArrayList<Activity>();
	
	public static void add(Activity activity){
		activities.add(activity);
	}
	
	public static void exit(){
		for(Activity activity : activities){
			if(activity!=null){
				//存在
				activity.finish();
			}
		}
	}
}
package com.edu.util;

public interface NamesInterface {

	//文件名
	public static String FILE_NAME = "init";
	
}

判断用户名是否正确:没有读取数据库,只是做一个测试
package com.edu.service;

public class UserInfoService {

	public boolean checkLogin(String name){
		if("abc".equals(name)){
			return true;
		}
		return false;
	}
	
}

File文件读写

Files通过 FileInputStream 和 FileOutputStream 对文件进行操作。
Android 中可以在设备本身的的存储或者外接的存储设备中创建用于保存数据的文件。同时,在默认状态下,文件是不能在不同的程序间共享的 
获取输出流 
openFileOutput(String fileName, int mode)生成的文件自动存储在/data/data/Package Name/files目录下
获取输入流
openFileInput(String fileName);
申请权限:
<!-- 在SDCard中创建与删除文件权限 -->
android.permission.MOUNT_UNMOUNT_FILESYSTEMS
<!-- 往SDCard写入数据权限 -->
android.permission.WRITE_EXTERNAL_STORAGE
存放在sdcard的文件可以被任何应用访问到的

Demo:
MainActivity:这里没有设置按钮监听器
package com.edu.pro1124_file_sdcard;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;

public class MainActivity extends Activity {

	private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
	//方法名,参数,返回值,固定
	public void write(View view){
		System.out.println("write");
		/**
		 * 如果挂载完毕的sdcard和获取的相同
		 */
		if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
			//得到sdcard文件目录
			File sdcard = Environment.getExternalStorageDirectory();
			System.out.println("sdcard:"+sdcard.getPath());
			//设置日期
			Date date = new Date();
			String strDate = "file/" + format.format(date);
			File file = new File(sdcard, strDate);
			/**
			 * 如果不存在,创建
			 */
			if(!file.exists()){
				file.mkdirs();
			}
			
			File f = new File(file, "edu.txt");
			try {
				FileOutputStream fos = 
						new FileOutputStream(f);
				//写入数据
				String str = "Hello World";
				fos.write(str.getBytes());
				fos.close();//记得关闭
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public void read(View view){
		if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
			File sdcard = Environment.getExternalStorageDirectory();
			Date date = new Date();
			String strDate = "file/" + format.format(date);
			File file = new File(sdcard, strDate);
			if(file.exists()){
				File f = new File(file, "edu.txt");
				try {
					FileInputStream fis = 
							new FileInputStream(f);
					byte[] array = new byte[fis.available()];
					//读出
					fis.read(array);
					fis.close();
					System.out.println(new String(array));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
	
}
页面:添加onClick方法
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="64dp"
        android:text="write"
        android:onClick="write" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button1"
        android:layout_below="@+id/button1"
        android:layout_marginTop="72dp"
        android:text="read" 
        android:onClick="read"/>
我的虚拟机Android4.4.2的文件写入到了storyage/sdcard/file/下的日期文件夹,真机没有测试。

总结

这两种方式都不是很安全,其他人可以访问到,不要放重要数据,如密码之类的,谨慎使用!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值