Android備考01 黑馬76期-day02數據存儲相關api

目錄

案例1:記住用戶名密碼

寫法1:純IO流方式,硬編碼

佈局:

主邏輯代碼:MainActivity.java

工具類UserInfoUtils.java

寫法2:使用上下文獲取文件錄

MainActivity.this  調用時加個參數MainActivity.this  就是context

UserInfoUtils.java  不硬編碼,改用context獲取目錄路徑

寫法3:徹底告別IO流

UserInfoUtils.java

寫法4:寫到sdcard

UserInfoUtils.java

寫法5:寫到sdcard,Environment告別硬編碼

UserInfoUtils.java

寫法6:SharedPreferences存取簡單數據★

MainActivity.java

改進:sp直接做一個成員變量

改進2:記住cb_checked選中狀態

SharedPreferences詳細學習使用

xml序列化:自定義生成xml(備份短信到xml)

小得1:

小結1:


案例1:記住用戶名密碼

寫法1:純IO流方式,硬編碼

佈局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/et_username"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="請輸入用戶名" />

    <EditText
        android:id="@+id/et_password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:password="true"
        android:hint="請輸入密碼" />

    <RelativeLayout
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <CheckBox
            android:id="@+id/cb_ischeck"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="記住密碼" />
        <Button 
            android:onClick="login"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:text="登錄"
            />
        
        
    </RelativeLayout>

</LinearLayout>

主邏輯代碼:MainActivity.java

package com.example.login;

import java.util.Map;

import android.os.Bundle;
import android.app.Activity;
import android.text.TextUtils;
import android.view.Menu;
import android.view.TextureView;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
import com.example.login2.R;

public class MainActivity extends Activity {

    private EditText et_name;
	private EditText et_pwd;
	private CheckBox cb_check;

	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        et_name = (EditText) findViewById(R.id.et_username);
        et_pwd = (EditText) findViewById(R.id.et_password);
        cb_check = (CheckBox) findViewById(R.id.cb_ischeck);
        	
        //讀取info.txt
        Map<String,String> maps=UserInfoUtils.read();
        if(maps!=null){
        	et_name.setText(maps.get("name"));
        	et_pwd.setText(maps.get("pwd"));
        	cb_check.setChecked(true);
        }
        
    }
	
	public void login(View v){
		String username = et_name.getText().toString().trim();
		String pwd = et_pwd.getText().toString().trim();
		
		if(TextUtils.isEmpty(username)||TextUtils.isEmpty(pwd)){
			Toast.makeText(this, "用戶名或密碼不能爲空!", 0).show();
		}else{
			System.out.println("連接服務器中...");
			
			if(cb_check.isChecked()){
				boolean res = UserInfoUtils.saveInfo(username, pwd);
				if(res){
					Toast.makeText(this, "保存成功!", 0).show();
				}else{
					Toast.makeText(this, "保存失敗!", 0).show();
				}
			}else{
				System.out.println("未保存密碼!");
			}
			
		}
		
	}
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
}

工具類UserInfoUtils.java

package com.example.login;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public class UserInfoUtils {
	public static boolean saveInfo(String username,String pwd) {
		try {
			String result=username+"##"+pwd;
			//創建文件(確定輸出位置)
			File file=new File("/data/data/com.example.login2/info.txt");
			//創建輸出流
			FileOutputStream fos=new FileOutputStream(file);
			//輸出(寫)文件
			fos.write(result.getBytes());
			fos.close();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	public static Map<String, String> read() {
		try {
			Map<String, String> maps=new HashMap<String, String>();
			File file=new File("/data/data/com.example.login2/info.txt");
			FileInputStream fis=new FileInputStream(file);
			BufferedReader bfr=new BufferedReader(new InputStreamReader(fis));
			String content=bfr.readLine();//讀一行
			String[] splits = content.split("##");
			maps.put("name",splits[0]);
			maps.put("pwd", splits[1]);
			fis.close();
			return maps;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}

 

第一次改進

寫法2:使用上下文獲取文件錄

上下文context就是this或者說MainActivity.this

String path = context.getFilesDir().getPath();//context就是MainActivity.this  調用此api,會自動幫我們在本項目包名目錄下創建一個專門的文件目錄files以供我們創建,存放,讀取文件到外存

MainActivity.this  調用時加個參數MainActivity.this  就是context

package com.example.login;

import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

	private EditText et_name;
	private EditText et_pwd;
	private CheckBox cb_check;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		et_name = (EditText) findViewById(R.id.et_username);
		et_pwd = (EditText) findViewById(R.id.et_password);
		cb_check = (CheckBox) findViewById(R.id.cb_ischeck);

		// 讀取info.txt
		Map<String, String> maps = UserInfoUtils.read(MainActivity.this);
		if (maps != null) {
			et_name.setText(maps.get("name"));
			et_pwd.setText(maps.get("pwd"));
			cb_check.setChecked(true);
		}

	}

	public void login(View v) {
		String username = et_name.getText().toString().trim();
		String pwd = et_pwd.getText().toString().trim();

		if (TextUtils.isEmpty(username) || TextUtils.isEmpty(pwd)) {
			Toast.makeText(this, "用戶名或密碼不能爲空!", 0).show();
		} else {
			System.out.println("連接服務器中...");

			if (cb_check.isChecked()) {
				boolean res = UserInfoUtils.saveInfo(this, username, pwd);
				if (res) {
					Toast.makeText(this, "保存成功!", 0).show();
			} else {
					Toast.makeText(this, "保存失敗!", 0).show();
				}
			} else {
				System.out.println("未保存密碼!");
			}

		}

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

UserInfoUtils.java  不硬編碼,改用context獲取目錄路徑

package com.example.login;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

import android.content.Context;
 
public class UserInfoUtils {
	public static boolean saveInfo(Context context,  String username,String pwd) {
		try {
			String path = context.getFilesDir().getPath();//幫我們在包名目錄下生成一個目錄files
			System.out.println(path);
			String result=username+"##"+pwd;
			//創建文件(確定輸出位置)
			File file=new File(path,"info.txt");
			//創建輸出流
			FileOutputStream fos=new FileOutputStream(file);
			//輸出(寫)文件
			fos.write(result.getBytes());
			fos.close();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
 
	public static Map<String, String> read(Context context) {
		try {
			Map<String, String> maps=new HashMap<String, String>();
			String path = context.getFilesDir().getPath();
			File file=new File(path,"info.txt");
			FileInputStream fis=new FileInputStream(file);
			BufferedReader bfr=new BufferedReader(new InputStreamReader(fis));
			String content=bfr.readLine();//讀一行
			String[] splits = content.split("##");
			maps.put("name",splits[0]);
			maps.put("pwd", splits[1]);
			fis.close();
			return maps;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}

 

寫法3:徹底告別IO流

String path = context.getFilesDir().getPath();
File file=new File(path,"info.txt");
FileInputStream fis=new FileInputStream(file);

上面3行可以縮減爲下面一行

FileInputStream fis = context.openFileInput("infoo.txt");

UserInfoUtils.java

package com.example.login;
 
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

import android.content.Context;
 
public class UserInfoUtils {
	public static boolean saveInfo(Context context,  String username,String pwd) {
		try {
			String result=username+"##"+pwd;
			//創建輸出流
			FileOutputStream fos=context.openFileOutput("infoo.txt",context.MODE_PRIVATE);
			//輸出(寫)文件
			fos.write(result.getBytes());
			fos.close();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
 
	public static Map<String, String> read(Context context) {
		try {
			Map<String, String> maps=new HashMap<String, String>();
			/*String path = context.getFilesDir().getPath();
			File file=new File(path,"info.txt");
			FileInputStream fis=new FileInputStream(file);*/
			//context特別強大,一下一行比上上面三行
			FileInputStream fis = context.openFileInput("infoo.txt");
			BufferedReader bfr=new BufferedReader(new InputStreamReader(fis));
			String content=bfr.readLine();//讀一行
			String[] splits = content.split("##");
			maps.put("name",splits[0]);
			maps.put("pwd", splits[1]);
			fis.close();
			return maps;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}

其他不變

 

 

 

寫法4:寫到sdcard

加權限:android.permission.WRITE_EXTERNAL_STORAGE

原始方案下修改

UserInfoUtils.java

package com.example.login;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public class UserInfoUtils {
	public static boolean saveInfo(String username,String pwd) {
		try {
			String result=username+"##"+pwd;
			//創建文件(確定輸出位置)
			File file=new File("/mnt/sdcard/info2.txt");
			//創建輸出流
			FileOutputStream fos=new FileOutputStream(file);
			//輸出(寫)文件
			fos.write(result.getBytes());
			fos.close();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	public static Map<String, String> read() {
		try {
			Map<String, String> maps=new HashMap<String, String>();
			File file=new File("/mnt/sdcard/info2.txt");
			FileInputStream fis=new FileInputStream(file);
			BufferedReader bfr=new BufferedReader(new InputStreamReader(fis));
			String content=bfr.readLine();//讀一行
			String[] splits = content.split("##");
			maps.put("name",splits[0]);
			maps.put("pwd", splits[1]);
			fis.close();
			return maps;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}

逍遙模擬器可能將sdcard砍掉了,因此eclipse裏查看不到

 

寫法5:寫到sdcard,Environment告別硬編碼

String sdpath = Environment.getExternalStorageDirectory().getPath();//獲取sdcard路徑

UserInfoUtils.java

package com.example.login;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

import android.os.Environment;

public class UserInfoUtils {
	public static boolean saveInfo(String username,String pwd) {
		try {
			String result=username+"##"+pwd;
			//創建文件(確定輸出位置)
			String sdpath = Environment.getExternalStorageDirectory().getPath();
			File file=new File(sdpath,"info2.txt");
			//創建輸出流
			FileOutputStream fos=new FileOutputStream(file);
			//輸出(寫)文件
			fos.write(result.getBytes());
			fos.close();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	public static Map<String, String> read() {
		try {
			Map<String, String> maps=new HashMap<String, String>();
			String sdpath = Environment.getExternalStorageDirectory().getPath();
			File file=new File(sdpath,"info2.txt");
			FileInputStream fis=new FileInputStream(file);
			BufferedReader bfr=new BufferedReader(new InputStreamReader(fis));
			String content=bfr.readLine();//讀一行
			String[] splits = content.split("##");
			maps.put("name",splits[0]);
			maps.put("pwd", splits[1]);
			fis.close();
			return maps;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}

 

寫法6:SharedPreferences存取簡單數據★

十分簡單,工具類沒有了,就一個MainActivity.java

MainActivity.java

package com.example.login;

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

import com.example.sp.R;

public class MainActivity extends Activity {

    private EditText et_name;
	private EditText et_pwd;
	private CheckBox cb_check;

	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        et_name = (EditText) findViewById(R.id.et_username);
        et_pwd = (EditText) findViewById(R.id.et_password);
        cb_check = (CheckBox) findViewById(R.id.cb_ischeck);
        
        //sp的xml中讀取出數據
        SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
        //讀直接取即可 不需要edit
        String name=sp.getString("name","");
        String pwd = sp.getString("pwd", "");
        //直接展示 沒有默認值都設置爲空""了嘛
        et_name.setText(name);
        et_pwd.setText(pwd);
    }
	
	public void login(View v){
		String username = et_name.getText().toString().trim();
		String pwd = et_pwd.getText().toString().trim();
		
		if(TextUtils.isEmpty(username)||TextUtils.isEmpty(pwd)){
			Toast.makeText(this, "用戶名或密碼不能爲空!", 0).show();
		}else{
			System.out.println("連接服務器中...");
			
			if(cb_check.isChecked()){
				//getSharedPreferences(name, mode);
				/**
				 * 文件以xml格式存儲
				 * name:xml文件名
				 * mode:模式 eg:MODE_PRIVATE(0) 私有的
				 */
				//獲取sp (創建xml)
				SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
				//獲取sp編輯器
				Editor edit = sp.edit();
				//利用編輯器往xml裏存值 (寫xml)
				edit.putString("name", username);
				edit.putString("pwd", pwd);
				//一定記得提交 java沒法寫得像c#那麼好,跨平臺不能寫死
				edit.commit();
				Toast.makeText(this, "保存成功!", 0).show();
			}else{
				System.out.println("未保存密碼!");
			}
		}
	}
}

改進:sp直接做一個成員變量

package com.example.login;

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

import com.example.sp.R;

public class MainActivity extends Activity {

	private EditText et_name;
	private EditText et_pwd;
	private CheckBox cb_check;
	private SharedPreferences sp;// 獲取sp (創建xml)

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//java不能寫死 設計上相比於C#就太醜了.....寫些機械冗餘的代碼
		et_name = (EditText) findViewById(R.id.et_username);
		et_pwd = (EditText) findViewById(R.id.et_password);
		cb_check = (CheckBox) findViewById(R.id.cb_ischeck);

		sp = getSharedPreferences("config", MODE_PRIVATE);
		// 讀直接取即可 不需要edit
		String name = sp.getString("name", "");
		String pwd = sp.getString("pwd", "");
		// 直接展示 沒有默認值都設置爲空""了嘛
		et_name.setText(name);
		et_pwd.setText(pwd);
		
	}

	public void login(View v) {
		String username = et_name.getText().toString().trim();
		String pwd = et_pwd.getText().toString().trim();

		if (TextUtils.isEmpty(username) || TextUtils.isEmpty(pwd)) {
			Toast.makeText(this, "用戶名或密碼不能爲空!", 0).show();
		} else {
			System.out.println("連接服務器中...");
			if (cb_check.isChecked()) {
				// 獲取sp編輯器
				Editor edit = sp.edit();
				// 利用編輯器往xml裏存值 (寫xml)
				edit.putString("name", username);
				edit.putString("pwd", pwd);
				// 一定記得提交 java沒法寫得像c#那麼好,跨平臺不能寫死
				edit.commit();
				Toast.makeText(this, "保存成功!", 0).show();
			} else {
				System.out.println("未保存密碼!");
			}
		}
	}
}

生成xml文件存儲數據

格式如下

 

改進2:記住cb_checked選中狀態

package com.example.login;

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

import com.example.sp.R;

public class MainActivity extends Activity {

	private EditText et_name;
	private EditText et_pwd;
	private CheckBox cb_check;
	private SharedPreferences sp;// 獲取sp (創建xml)

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//java不能寫死 設計上相比於C#就太醜了.....寫些機械冗餘的代碼
		et_name = (EditText) findViewById(R.id.et_username);
		et_pwd = (EditText) findViewById(R.id.et_password);
		cb_check = (CheckBox) findViewById(R.id.cb_ischeck);

		sp = getSharedPreferences("config", MODE_PRIVATE);
		// 讀直接取即可 不需要edit
		String name = sp.getString("name", "");
		String pwd = sp.getString("pwd", "");
		// 直接展示 沒有默認值都設置爲空""了嘛
		et_name.setText(name);
		et_pwd.setText(pwd);
		
		//TODO 記憶選中狀態
		cb_check.setChecked(sp.getBoolean("checked", false));
	}

	public void login(View v) {
		String username = et_name.getText().toString().trim();
		String pwd = et_pwd.getText().toString().trim();

		if (TextUtils.isEmpty(username) || TextUtils.isEmpty(pwd)) {
			Toast.makeText(this, "用戶名或密碼不能爲空!", 0).show();
		} else {
			System.out.println("連接服務器中...");
			// 獲取sp編輯器
			Editor edit = sp.edit();
			if (cb_check.isChecked()) {
				// 利用編輯器往xml裏存值 (寫xml)
				edit.putString("name", username);
				edit.putString("pwd", pwd);
				edit.putBoolean("checked", true);
				// 一定記得提交 java沒法寫得像c#那麼好,跨平臺不能寫死
				edit.commit();
				Toast.makeText(this, "保存成功!", 0).show();
			} else {
				edit.putBoolean("checked", false);
				edit.commit();
				Toast.makeText(this, "未保存密碼!", 0).show();
			}
		}
	}
}

SharedPreferences很重要:

 

SharedPreferences詳細學習使用

xml序列化:自定義生成xml(備份短信到xml)

設計備份短信xml格式如下:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<smss>
    <sms>
		<address>110</address>
		<body>你被捕了</body>
		<date>2020</date>
    </sms>
    <sms>
		<address>120</address>
		<body>來醫院一趟</body>
		<date>2019</date>
    </sms>
</smss>
 

今天暫時取不出來,學到四大組件最後一個內容提供者(content provider)才行,今天只能模擬

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

小得1:

Android四大組件分別爲activity、service、content provider、broadcast receiver。
第七章不考那麼就考最簡單的兩大組件activity和content了,前3天正好講這些

小結1:

padding : 控件內容相對於控件邊框的距離

margin:  控件之間的距離

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發佈了388 篇原創文章 · 獲贊 89 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章