android 登录保存密码
2015-05-26 19:00:34 wlwh90 阅读数 3943

Android登录记住密码,最常见的方式是用SharedPreferences。

SharedPreference是Android提供的一种轻量级的数据存储方式,主要用来存储一些简单的配置信息,例如,默认欢迎语,登录用户名和密码等。其以键值对的方式存储,使得我们能很方便进行读取和存入。

文章中的记住密码功能,也是用的SharedPreference实现的,其中保存的密码用AES算法加密。不多说,页面如下图:


先来看布局文件,布局中有很多string资源和drawable资源的引用,可在完整代码文件中找到。

<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:padding="@dimen/padding1"
    android:gravity="center"
    android:orientation="vertical"
    android:background="@color/login_bg"
    tools:context="com.example.remenberpassword.MainActivity" >
    
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        android:orientation="vertical">

        <LinearLayout
	        android:layout_width="fill_parent"
	        android:layout_height="wrap_content"
	        android:orientation="horizontal"
	        android:padding="@dimen/padding2"
	        android:gravity="center_vertical">

            <ImageView
                android:id="@+id/img_username"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:src="@drawable/username" />

            <EditText
                android:id="@+id/edit_username"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/margin1"
                android:layout_weight="7"
                android:hint="@string/username"
                android:background="@null"/>
	        
	    </LinearLayout>
    
        <View 
            android:layout_width="fill_parent"
            android:layout_height="1dp"
            android:background="@color/gainsboro"/>
        
        <LinearLayout
	        android:layout_width="fill_parent"
	        android:layout_height="wrap_content"
	        android:orientation="horizontal"
	        android:padding="@dimen/padding2"
	        android:gravity="center_vertical">

            <ImageView
                android:id="@+id/img_password"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:src="@drawable/password" />

            <EditText
                android:id="@+id/edit_password"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="7"
                android:layout_marginLeft="@dimen/margin1"
                android:inputType="textPassword"
                android:hint="@string/password"
                android:background="@null"/>
            
	    </LinearLayout> 
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginTop="@dimen/margin1"
        android:gravity="center_vertical">
        
	    <CheckBox
	        android:id="@+id/check_remenber_password"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:textColor="@color/white"
	        android:checked="true"
	        android:text="@string/remember_password" />
    </LinearLayout>

    <Button
        android:id="@+id/btn_login"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/margin1"
        android:textSize="@dimen/btn_textsize1"
        android:textColor="@color/white"
        android:background="@drawable/btn_selector"
        android:text="@string/login" />

</LinearLayout>


下面是Activity代码。

package com.example.remenberpassword;

import com.example.common.CommonUtils;
import com.example.common.EncrypAES;
import com.example.common.User;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;

public class MainActivity extends ActionBarActivity {
	/**
	 * 用了保存用户名和密码的文件名,文件是xml文件,但是不用加后缀,系统会自动加上。。
	 */
	private static final String USER_INFO="User_Info";
	
	/**
	 * 文件中记录用户名的关键字。
	 */
	private static final String USER_NAME="User_Name";
	
	/**
	 * 文件中记录密码的关键字。
	 */
	private static final String PASSWORD="Password";
	
	/**
	 * 文件中记录是否选择记住密码功能的关键字
	 */
	private static final String IS_REMENBER_PASSWORD="Is_Remenber_Password";
	
	private User mUser;
	
	private EditText editUsername;
	private EditText editPassword;
	private CheckBox checkRememberPassword;
	private Button btnLogin;
	private SharedPreferences mSharedPreferences;
	
	/**
	 *对用户名和密码进行加解密 
	 */
	private EncrypAES mAes;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        
        InitData();
        InitWidget();
    }

	public void InitData(){
    	mUser=new User();
    	
    	//取得保存用户名和密码的xml文件,如果文件不存在,系统会自动创建
    	mSharedPreferences=getSharedPreferences(USER_INFO, Context.MODE_PRIVATE);
    	
		mAes=new EncrypAES();
	}
    
    public void InitWidget(){
    	editUsername=(EditText)findViewById(R.id.edit_username);
    	editPassword=(EditText)findViewById(R.id.edit_password);
    	checkRememberPassword=(CheckBox)findViewById(R.id.check_remenber_password);
    	btnLogin=(Button)findViewById(R.id.btn_login);
    	
    	//如果选中了记住密码,则从记住的密码中获取用户名和密码
    	if(mSharedPreferences.getBoolean(IS_REMENBER_PASSWORD, true)){
    		editUsername.setText(mSharedPreferences.getString(USER_NAME, ""));
    		
    		//对读取到的密码进行解密 
    		String password=mSharedPreferences.getString(PASSWORD, "");
    		if(0!=password.length()){
    			password=mAes.DecryptorString(password);
    		}
    		editPassword.setText(password);
    	}
    	
    	//记住密码CheckBox监听函数
    	checkRememberPassword.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
				mSharedPreferences.edit().putBoolean(IS_REMENBER_PASSWORD, isChecked).commit();
			}
		});
    	
    	//登录按钮监听函数
    	btnLogin.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				//判断是否打开网络连接
				if(!CommonUtils.CheckNetwork(MainActivity.this)){
					CommonUtils.ShowToast(MainActivity.this, R.string.network_hint);
					return ;
				}
				
				if(!CheckUserInfoInput()){
					return ;
				}
				
				savaUserNameAndPassword(mUser);
				
				Intent intent=new Intent(MainActivity.this,SecondActivity.class);
				startActivity(intent);
			}
		});
    }
    
    
    /**
     * 检查用户名和密码输入
     * @return
     */
    public boolean CheckUserInfoInput(){
    	String strUserName;
    	String strPassword;
    	
    	strUserName=editUsername.getText().toString();
    	strPassword=editPassword.getText().toString();
    	if(0==strUserName.length() | 0==strPassword.length()){
    		CommonUtils.ShowToast(MainActivity.this,R.string.username_password_inputhint);
    		return false;
    	}
    	
    	//设置用户名和密码
    	mUser.setUserName(strUserName);
    	mUser.setPassword(strPassword);

    	return true;
    }

	/**
	 * 如果选中了“记住密码”功能,则保存用户名和密码
	 * @param user 包含了用户名和密码
	 */
	public void savaUserNameAndPassword(User user){
		if(checkRememberPassword.isChecked()){
			Editor editor=mSharedPreferences.edit();
			editor.putBoolean(IS_REMENBER_PASSWORD, true);
			editor.putString(USER_NAME, user.getUserName());
			
			//对密码进行加密保存
			String password=mAes.EncryptorString(user.getPassword());
			editor.putString(PASSWORD, password);
			editor.commit();
		}
	}
 
}


接下来是AES算法加密代码。

代码中,SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");这一条语句是需要特别注意的,在代码中有详细的说明。

另外,用c.doFinal(buff)函数加解密得到的结果都是byte[]型的,不能对加密得到的byte[]型结果直接new String(byte[]);保存,然后在解密时用str.getBytes();转换。

所以,借用了网上其他网友的方法,有toHex、fromHex、toByte、toHex、appendHex。可以确保byte[]和String之间的转换不出问题。

package com.example.common;
import java.security.InvalidKeyException;
import java.security.SecureRandom;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import android.util.Log;

/**
 * AES算法加密类
 * @author Administrator
 *
 */
public class EncrypAES {
	private static final String TAG="EncryAES";

	/**
	 * Cipher负责完成加密或解密工作
	 */
	private Cipher c;
	
	/**
	 * 该字节数组负责保存加密的结果
	 */
	private byte[] cipherByte;
	
	/**
	 * 用于生产密钥
	 */
	private static final String SECRETKET="AESDemo";
	private SecretKeySpec deskey;
	
	public EncrypAES(){
		Security.addProvider(new com.sun.crypto.provider.SunJCE());
		
		try {
			deskey = new SecretKeySpec(getRawKey(SECRETKET.getBytes()),"AES");
			
			//生成Cipher对象,指定其支持的DES算法
			c = Cipher.getInstance("AES");
		} catch (Exception e) {
			Log.e(TAG, "EnrypAES construct failed.",e);
		}
	}
	
	/**
	 * 对字符串加密
	 * 
	 * @param str
	 * @return
	 * @throws InvalidKeyException
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 */
	private byte[] Encrytor(String str) throws InvalidKeyException,
			IllegalBlockSizeException, BadPaddingException {
		
		// 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式
		c.init(Cipher.ENCRYPT_MODE, deskey);
		byte[] src = str.getBytes();
		
		cipherByte = c.doFinal(src);		// 加密,结果保存进cipherByte
		return cipherByte;
	}

	/**
	 * 对字符串解密
	 * 
	 * @param buff
	 * @return
	 * @throws InvalidKeyException
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 */
	private byte[] Decryptor(byte[] buff) throws InvalidKeyException,
			IllegalBlockSizeException, BadPaddingException {
		
		// 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式
		c.init(Cipher.DECRYPT_MODE, deskey);
		cipherByte = c.doFinal(buff);
		
		return cipherByte;
	}
	
	/**
	 * 对字符串进行加密
	 * @param string 要加密的字符串
	 * @return 加密后的字符串
	 */
	public String EncryptorString(String string){
		String result =null;
		byte[] encontent;
		try {
			encontent = Encrytor(string);
			result=toHex(encontent);
		} catch (InvalidKeyException e) {
			Log.e(TAG, "EncryptorString",e);
		} catch (IllegalBlockSizeException e) {
			Log.e(TAG, "EncryptorString",e);
		} catch (BadPaddingException e) {
			Log.e(TAG, "EncryptorString",e);
		}
		
		return result;
	}
	
	/**
	 * 对字符串进行解密
	 * @param string 要解密的字符串
	 * @return 解密后的字符串
	 */
	public String DecryptorString(String string){
		byte[] cryptcontent=toByte(string);
		byte[] decontent;
		String result=null;
		
		try {
			decontent=Decryptor(cryptcontent);
			result=new String(decontent);
			
		} catch (InvalidKeyException e) {
			Log.e(TAG,"DecryptorString failed.",e);
		} catch (IllegalBlockSizeException e) {
			Log.e(TAG,"DecryptorString failed.",e);
		} catch (BadPaddingException e) {
			Log.e(TAG,"DecryptorString failed.",e);
		}
		
		return result;
	}

	private static byte[] getRawKey(byte[] seed) throws Exception {
		KeyGenerator kgen = KeyGenerator.getInstance("AES");
		
		/**
		 * 这一句很关键。
		 * <br>网上有的代码是这一句SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
		 * <br>在getInstance函数中少了一个String参数。
		 * 这个参数是不能少的,因为如果少了这个参数的话,生成的密钥是随机的,而加密和解密必须是用同样的密钥的
		 * 所以会出现不能解密的问题(总是抛出BadPaddingException异常)。而且这种方法中,对比少了一个参数的加密结果,
		 * 会发现每一次加密的结果都是不一样的。
		 * <br>而用下面的语句得到的密钥加密,同样的字符串任何时候得到的加密结果都是一样的。
		 */
		SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
		sr.setSeed(seed);
		kgen.init(128, sr); // 192 and 256 bits may not be available
		SecretKey skey = kgen.generateKey();
		byte[] raw = skey.getEncoded();
		return raw;
	}
	
	public static String toHex(String txt) {  
        return toHex(txt.getBytes());  
    }
	
    public static String fromHex(String hex) {  
        return new String(toByte(hex));  
    }  
      
    public static byte[] toByte(String hexString) {  
        int len = hexString.length()/2;  
        byte[] result = new byte[len];  
        for (int i = 0; i < len; i++)  
            result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();  
        return result;  
    }  
 
    public static String toHex(byte[] buf) {  
        if (buf == null)  
            return "";  
        StringBuffer result = new StringBuffer(2*buf.length);  
        for (int i = 0; i < buf.length; i++) {  
            appendHex(result, buf[i]);  
        }  
        return result.toString();  
    }
    
    private final static String HEX = "0123456789ABCDEF";
    private static void appendHex(StringBuffer sb, byte b) {  
        sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));  
    }
}


至于代码中其他的内容,比如把用户名和密码封装在了User对象中,大家自己去看完整的代码。

完整代码下载链接:http://download.csdn.net/detail/wlwh90/8741953

2015-05-11 15:03:54 yangxujia 阅读数 422

我们不管在开发一个项目或者使用别人的项目,都有用户登录功能,为了让用户的体验效果更好,我们通常会做一个功能,叫做保存用户,这样做的目地就是为了让用户下一次再使用该程序不会重新输入用户名和密码,这里我使用3种方式来存储用户名和密码

1、通过普通 的txt文本存储

2、通过properties属性文件进行存储

3、通过SharedPreferences工具类存储

第一种:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
     * 保存用户名和密码的业务方法
     *
     * @param username
     * @param password
     * @return
     */
    public static boolean saveUserInfo(String username, String password) {
        try {
            // 使用当前项目的绝对路径
            File file = new File("data/data/com.example.android_file_handler/info.txt");
            // 创建输出流对象
            FileOutputStream fos = new FileOutputStream(file);
            // 向文件中写入信息
            fos.write((username + "##" + password).getBytes());
            // 关闭输出流对象
            fos.close();
            return true;
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }

这里写的路径是当前项目的绝对路径,这样做是有缺陷的,比如你将项目路径改了,这里的路径就获取就失败了,所以Android提供了通过上下文一个方法获取当前项目的路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static boolean saveUserInfo(Context context, String username,
            String password) {
        try {
            // 使用Android上下问获取当前项目的路径
            File file = new File(context.getFilesDir(), "userinfo.txt");
            // 创建输出流对象
            FileOutputStream fos = new FileOutputStream(file);
            // 向文件中写入信息
            fos.write((username + "##" + password).getBytes());
            // 关闭输出流对象
            fos.close();
            return true;
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }

上面这两个方法都是存储用户名和密码,接下来是获取用户名和密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
     * 获取普通txt文件信息
     *
     * @param context
     * @return
     */
    public static Map<string, Object=""> getTxtFileInfo(Context context) {
        try {
            // 创建FIle对象
            File file = new File(context.getFilesDir(), "userinfo.txt");
            // 创建FileInputStream对象
            FileInputStream fis = new FileInputStream(file);
            // 创建BufferedReader对象
            BufferedReader br = new BufferedReader(new InputStreamReader(fis));
            // 获取文件中的内容
            String content = br.readLine();
            // 创建Map集合
            Map<string, Object=""> map = new HashMap<string, Object="">();
            // 使用保存信息使用的##将内容分割出来
            String[] contents = content.split("##");
            // 保存到map集合中
            map.put("username", contents[0]);
            map.put("password", contents[1]);
            // 关闭流对象
            fis.close();
            br.close();
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }</string,></string,></string,>

这里我将获取到的内容封装到Map集合中,其实使用普通的txt文本存储用户名和密码是有缺陷的,这里我是通过“##”来分割用户名和密码的,那么如果用户在密码中的字符又包含了“#”这个特殊符号,那么最后在获取时,则获取不倒原来保存的信息,所以个人认为dier中方法就可以解决这个问题

第二种:

使用属性文件保存用户名和密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
     * 使用属性文件保存用户的信息
     *
     * @param context 上下文
     * @param username 用户名
     * @param password  密码
     * @return
     */
    public static boolean saveProUserInfo(Context context, String username,
            String password) {
        try {
            // 使用Android上下问获取当前项目的路径
            File file = new File(context.getFilesDir(), "info.properties");
            // 创建输出流对象
            FileOutputStream fos = new FileOutputStream(file);
            // 创建属性文件对象
            Properties pro = new Properties();
            // 设置用户名或密码
            pro.setProperty("username", username);
            pro.setProperty("password", password);
            // 保存文件
            pro.store(fos, "info.properties");
            // 关闭输出流对象
            fos.close();
            return true;
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }

读取属性文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
     * 返回属性文件对象
     *
     * @param context 上下文
     * @return
     */
    public static Properties getProObject(Context context) {
        try {
            // 创建File对象
            File file = new File(context.getFilesDir(), "info.properties");
            // 创建FileIutputStream 对象
            FileInputStream fis = new FileInputStream(file);
            // 创建属性对象
            Properties pro = new Properties();
            // 加载文件
            pro.load(fis);
            // 关闭输入流对象
            fis.close();
            return pro;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


在主方法中调用即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 获取属性文件对象
         Properties pro=LoginService.readSDCard(this);
        // 获取用户名或密码
        if (null != pro) {
            String username=pro.getProperty("username");
            String password=pro.getProperty("password");
            // 如果获取到的用户名或密码不为空,则设置到文本框中
            if (!TextUtils.isEmpty(username) && !TextUtils.isEmpty(password)) {
                // 设置用户名
                etUsername.setText(username);
                // 设置密码
                etPassword.setText(password);
            }
        }

第三种:

使用SharedPreferences保存用户名和密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
     * 使用SharedPreferences保存用户登录信息
     * @param context
     * @param username
     * @param password
     */
    public static void saveLoginInfo(Context context,String username,String password){
        //获取SharedPreferences对象
        SharedPreferences sharedPre=context.getSharedPreferences("config", context.MODE_PRIVATE);
        //获取Editor对象
        Editor editor=sharedPre.edit();
        //设置参数
        editor.putString("username", username);
        editor.putString("password", password);
        //提交
        editor.commit();
    }


在主方法中读取:

1
2
3
SharedPreferences sharedPre=getSharedPreferences("config", MODE_PRIVATE);
        String username=sharedPre.getString("username", "");
        String password=sharedPre.getString("password", "");


使用普通txt文件与属性文件保存都是保存到内部存储设备中,我们也可以保存的SDCard中,使用Android提供的Environment类就可以获取到外部存储设备

1
File file=new File(Environment.getExternalStorageDirectory(),"info.properties");

如果要使用绝对路径

1
File file = new File("/sdcard/info.properties");

最后就是需要添加权限,因为获取外部存储设备是有关安全的,所以需要添加相关的权限

1
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

使用这几种方法就可以实现保存用户名和密码这个功能了,至于有没有其他的方法,我想这几种应该就够用了

2016-07-06 14:51:50 liangjiujiu 阅读数 329

本文转自:http://www.2cto.com/kf/201401/272336.html

我们不管在开发一个项目或者使用别人的项目,都有用户登录功能,为了让用户的体验效果更好,我们通常会做一个功能,叫做保存用户,这样做的目地就是为了让用户下一次再使用该程序不会重新输入用户名和密码,这里我使用3种方式来存储用户名和密码

1、通过普通 的txt文本存储

2、通过properties属性文件进行存储

3、通过SharedPreferences工具类存储

第一种:

/**
     * 保存用户名和密码的业务方法
     * 
     * @param username
     * @param password
     * @return
     */
    public static boolean saveUserInfo(String username, String password) {
        try {
            // 使用当前项目的绝对路径
            File file = new File("data/data/com.example.android_file_handler/info.txt");
            // 创建输出流对象
            FileOutputStream fos = new FileOutputStream(file);
            // 向文件中写入信息
            fos.write((username + "##" + password).getBytes());
            // 关闭输出流对象
            fos.close();
            return true;
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }

   这里写的路径是当前项目的绝对路径,这样做是有缺陷的,比如你将项目路径改了,这里的路径就获取就失败了,所以Android提供了通过上下文一个方法获取当前项目的路径

public static boolean saveUserInfo(Context context, String username,
            String password) {
        try {
            // 使用Android上下问获取当前项目的路径
            File file = new File(context.getFilesDir(), "userinfo.txt");
            // 创建输出流对象
            FileOutputStream fos = new FileOutputStream(file);
            // 向文件中写入信息
            fos.write((username + "##" + password).getBytes());
            // 关闭输出流对象
            fos.close();
            return true;
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
上面这两个方法都是存储用户名和密码,接下来是获取用户名和密码

/**
     * 获取普通txt文件信息
     * 
     * @param context
     * @return
     */
    public static Map<string, object=""> getTxtFileInfo(Context context) {
        try {
            // 创建FIle对象
            File file = new File(context.getFilesDir(), "userinfo.txt");
            // 创建FileInputStream对象
            FileInputStream fis = new FileInputStream(file);
            // 创建BufferedReader对象
            BufferedReader br = new BufferedReader(new InputStreamReader(fis));
            // 获取文件中的内容
            String content = br.readLine();
            // 创建Map集合
            Map<string, object=""> map = new HashMap<string, object="">();
            // 使用保存信息使用的##将内容分割出来
            String[] contents = content.split("##");
            // 保存到map集合中
            map.put("username", contents[0]);
            map.put("password", contents[1]);
            // 关闭流对象
            fis.close();
            br.close();
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }</string,></string,></string,>

这里我将获取到的内容封装到Map集合中,其实使用普通的txt文本存储用户名和密码是有缺陷的,这里我是通过“##”来分割用户名和密码的,那么如果用户在密码中的字符又包含了“#”这个特殊符号,那么最后在获取时,则获取不倒原来保存的信息,所以个人认为第二种方法就可以解决这个问题

第二种:

使用属性文件保存用户名和密码

/**
     * 使用属性文件保存用户的信息
     * 
     * @param context 上下文
     * @param username 用户名
     * @param password  密码
     * @return
     */
    public static boolean saveProUserInfo(Context context, String username,
            String password) {
        try {
            // 使用Android上下问获取当前项目的路径
            File file = new File(context.getFilesDir(), "info.properties");
            // 创建输出流对象
            FileOutputStream fos = new FileOutputStream(file);
            // 创建属性文件对象
            Properties pro = new Properties();
            // 设置用户名或密码
            pro.setProperty("username", username);
            pro.setProperty("password", password);
            // 保存文件
            pro.store(fos, "info.properties");
            // 关闭输出流对象
            fos.close();
            return true;
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
读取属性文件

/**
     * 返回属性文件对象
     *
     * @param context 上下文
     * @return
     */
    publicstatic Properties getProObject(Context context) {
        try{
            // 创建File对象
            File file = newFile(context.getFilesDir(), "info.properties");
            // 创建FileIutputStream 对象
            FileInputStream fis = newFileInputStream(file);
            // 创建属性对象
            Properties pro = newProperties();
            // 加载文件
            pro.load(fis);
            // 关闭输入流对象
            fis.close();
            returnpro;
        }catch(Exception e) {
            e.printStackTrace();
            returnnull;
        }
    }


在主方法中调用即可

// 获取属性文件对象
         Properties pro=LoginService.readSDCard(this);
        // 获取用户名或密码
        if (null != pro) {
            String username=pro.getProperty("username");
            String password=pro.getProperty("password");
            // 如果获取到的用户名或密码不为空,则设置到文本框中
            if (!TextUtils.isEmpty(username) && !TextUtils.isEmpty(password)) {
                // 设置用户名
                etUsername.setText(username);
                // 设置密码
                etPassword.setText(password);
            }
        }

第三种:

使用SharedPreferences保存用户名和密码

/**
     * 使用SharedPreferences保存用户登录信息
     * @param context
     * @param username
     * @param password
     */
    public static void saveLoginInfo(Context context,String username,String password){
        //获取SharedPreferences对象
        SharedPreferences sharedPre=context.getSharedPreferences("config", context.MODE_PRIVATE);
        //获取Editor对象
        Editor editor=sharedPre.edit();
        //设置参数
        editor.putString("username", username);
        editor.putString("password", password);
        //提交
        editor.commit();
    }

在主方法中读取:
SharedPreferences sharedPre=getSharedPreferences("config", MODE_PRIVATE);
        String username=sharedPre.getString("username", "");
        String password=sharedPre.getString("password", "");
使用普通txt文件与属性文件保存都是保存到内部存储设备中,我们也可以保存的SDCard中,使用Android提供的Environment类就可以获取到外部存储设备
File file=new File(Environment.getExternalStorageDirectory(),"info.properties");
如果要使用绝对路径
File file = new File("/sdcard/info.properties");
最后就是需要添加权限,因为获取外部存储设备是有关安全的,所以需要添加相关的权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
使用这几种方法就可以实现保存用户名和密码这个功能了,至于有没有其他的方法,我想这几种应该就够用了







2014-01-13 23:54:03 u011109042 阅读数 3248

我们不管在开发一个项目或者使用别人的项目,都有用户登录功能,为了让用户的体验效果更好,我们通常会做一个功能,叫做保存用户,这样做的目地就是为了让用户下一次再使用该程序不会重新输入用户名和密码,这里我使用3种方式来存储用户名和密码

1、通过普通 的txt文本存储

2、通过properties属性文件进行存储

3、通过SharedPreferences工具类存储

第一种:

/**
	 * 保存用户名和密码的业务方法
	 * 
	 * @param username
	 * @param password
	 * @return
	 */
	public static boolean saveUserInfo(String username, String password) {
		try {
			// 使用当前项目的绝对路径
			File file = new File("data/data/com.example.android_file_handler/info.txt");
			// 创建输出流对象
			FileOutputStream fos = new FileOutputStream(file);
			// 向文件中写入信息
			fos.write((username + "##" + password).getBytes());
			// 关闭输出流对象
			fos.close();
			return true;
		} catch (Exception e) {
			throw new RuntimeException();
		}
	}

这里写的路径是当前项目的绝对路径,这样做是有缺陷的,比如你将项目路径改了,这里的路径就获取就失败了,所以Android提供了通过上下文一个方法获取当前项目的路径

public static boolean saveUserInfo(Context context, String username,
			String password) {
		try {
			// 使用Android上下问获取当前项目的路径
			File file = new File(context.getFilesDir(), "userinfo.txt");
			// 创建输出流对象
			FileOutputStream fos = new FileOutputStream(file);
			// 向文件中写入信息
			fos.write((username + "##" + password).getBytes());
			// 关闭输出流对象
			fos.close();
			return true;
		} catch (Exception e) {
			throw new RuntimeException();
		}
	}

上面这两个方法都是存储用户名和密码,接下来是获取用户名和密码

/**
	 * 获取普通txt文件信息
	 * 
	 * @param context
	 * @return
	 */
	public static Map<String, Object> getTxtFileInfo(Context context) {
		try {
			// 创建FIle对象
			File file = new File(context.getFilesDir(), "userinfo.txt");
			// 创建FileInputStream对象
			FileInputStream fis = new FileInputStream(file);
			// 创建BufferedReader对象
			BufferedReader br = new BufferedReader(new InputStreamReader(fis));
			// 获取文件中的内容
			String content = br.readLine();
			// 创建Map集合
			Map<String, Object> map = new HashMap<String, Object>();
			// 使用保存信息使用的##将内容分割出来
			String[] contents = content.split("##");
			// 保存到map集合中
			map.put("username", contents[0]);
			map.put("password", contents[1]);
			// 关闭流对象
			fis.close();
			br.close();
			return map;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

这里我将获取到的内容封装到Map集合中,其实使用普通的txt文本存储用户名和密码是有缺陷的,这里我是通过“##”来分割用户名和密码的,那么如果用户在密码中的字符又包含了“#”这个特殊符号,那么最后在获取时,则获取不倒原来保存的信息,所以个人认为dier中方法就可以解决这个问题

第二种:

使用属性文件保存用户名和密码

/**
	 * 使用属性文件保存用户的信息
	 * 
	 * @param context 上下文
	 * @param username 用户名
	 * @param password  密码
	 * @return
	 */
	public static boolean saveProUserInfo(Context context, String username,
			String password) {
		try {
			// 使用Android上下问获取当前项目的路径
			File file = new File(context.getFilesDir(), "info.properties");
			// 创建输出流对象
			FileOutputStream fos = new FileOutputStream(file);
			// 创建属性文件对象
			Properties pro = new Properties();
			// 设置用户名或密码
			pro.setProperty("username", username);
			pro.setProperty("password", password);
			// 保存文件
			pro.store(fos, "info.properties");
			// 关闭输出流对象
			fos.close();
			return true;
		} catch (Exception e) {
			throw new RuntimeException();
		}
	}

读取属性文件

/**
	 * 返回属性文件对象
	 * 
	 * @param context 上下文
	 * @return
	 */
	public static Properties getProObject(Context context) {
		try {
			// 创建File对象
			File file = new File(context.getFilesDir(), "info.properties");
			// 创建FileIutputStream 对象
			FileInputStream fis = new FileInputStream(file);
			// 创建属性对象
			Properties pro = new Properties();
			// 加载文件
			pro.load(fis);
			// 关闭输入流对象
			fis.close();
			return pro;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}


在主方法中调用即可

// 获取属性文件对象
		 Properties pro=LoginService.readSDCard(this);
		// 获取用户名或密码
		if (null != pro) {
			String username=pro.getProperty("username");
			String password=pro.getProperty("password");
			// 如果获取到的用户名或密码不为空,则设置到文本框中
			if (!TextUtils.isEmpty(username) && !TextUtils.isEmpty(password)) {
				// 设置用户名
				etUsername.setText(username);
				// 设置密码
				etPassword.setText(password);
			}
		}

第三种:

使用SharedPreferences保存用户名和密码

/**
	 * 使用SharedPreferences保存用户登录信息
	 * @param context
	 * @param username
	 * @param password
	 */
	public static void saveLoginInfo(Context context,String username,String password){
		//获取SharedPreferences对象
		SharedPreferences sharedPre=context.getSharedPreferences("config", context.MODE_PRIVATE);
		//获取Editor对象
		Editor editor=sharedPre.edit();
		//设置参数
		editor.putString("username", username);
		editor.putString("password", password);
		//提交
		editor.commit();
	}


在主方法中读取:

SharedPreferences sharedPre=getSharedPreferences("config", MODE_PRIVATE);
		String username=sharedPre.getString("username", "");
		String password=sharedPre.getString("password", "");


使用普通txt文件与属性文件保存都是保存到内部存储设备中,我们也可以保存的SDCard中,使用Android提供的Environment类就可以获取到外部存储设备

File file=new File(Environment.getExternalStorageDirectory(),"info.properties");

如果要使用绝对路径

File file = new File("/sdcard/info.properties");

最后就是需要添加权限,因为获取外部存储设备是有关安全的,所以需要添加相关的权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

使用这几种方法就可以实现保存用户名和密码这个功能了,至于有没有其他的方法,我想这几种应该就够用了





2019-01-07 14:08:26 qq_25652949 阅读数 642

客户端调用restful接口
登录步骤:
启动界面-登录界面,通过验证码生成接口获取验证码并显示,保存sessionid
登录时带此session进入

 InputStream is = conn.getInputStream();
 //获取session并存储到本地
 String cookieval = conn.getHeaderField("Set-Cookie");
 Log.i("info",cookieval);
 SharedPreferences sharedPreferences = getSharedPreferences("login",MODE_PRIVATE);
 SharedPreferences.Editor editor = sharedPreferences.edit();
 editor.putString("session",cookieval);
 editor.commit();
//登录时带上session登录。让服务器可以区别是同一个客户端在操作
SharedPreferences sharedPreferences = getSharedPreferences("login",MODE_PRIVATE);
String cookie = sharedPreferences.getString("session","");
conn.addRequestProperty("Cookie",cookie);

思考:我这样的做法会导致每次刷新验证码都会生成新的session,所以可以在启动的时候随便访问一个服务器接口,然后在此保存session。
这里的登录界面就账号、密码、验证码框,验证码的imageview,登录、注册按钮,比较简单所以不贴代码。

Android保存用户名和密码

阅读数 29

转自:http://www.2cto.com/kf/201401/272336.html我们不管在开发一个项目或者使用别人的项目,都有用户登录功能,为了让用户的体验效果更好,我们通常会做一个功能,叫做保存用户,这样做的目地就是为了让用户下一次再使用该程序不会重新输入用户名和密码,这里我使用3种方式来存储用户名和密码1、通过普通的txt文本存储2、通过properties属性文件进...

博文 来自: dcj3sjt126com

Android保存用户名和密码

阅读数 34

我们不管在开发一个项目或者使用别人的项目,都有用户登录功能,为了让用户的体验效果更好,我们通常会做一个功能,叫做保存用户,这样做的目地就是为了让用户下一次再使用该程序不会重新输入用户名和密码,这里我使用3种方式来存储用户名和密码1、通过普通的txt文本存储2、通过properties属性文件进行存储3、通过SharedPreferences工具类存储第一种:/** *保...

博文 来自: iteye_20659

android保存用户名密码

阅读数 21

◆getSharedPreferencespref=getSharedPreferences(VocabTestMain.PREF_APPID,0);Stringusername=pref.getString(VocabTestMain.PREF_USERNAME,"");◆putSharedPreferencespref=get...

博文 来自: lovebirdegg

Android保存用户名和密码

阅读数 231

【转自 http://www.cnblogs.com/dennytao/p/5351861.html】我们不管在开发一个项目或者使用别人的项目,都有用户登录功能,为了让用户的体验效果更好,我们通常会做一个功能,叫做保存用户,这样做的目地就是为了让用户下一次再使用该程序不会重新输入用户名和密码,这里我使用3种方式来存储用户名和密码1、通过普通的txt文本存储2

博文 来自: u012891948

Android保存用户名和密码

阅读数 375

我们不管在开发一个项目或者使用别人的项目,都有用户登录功能,为了让用户的体验效果更好,我们通常会做一个功能,叫做保存用户,这样做的目地就是为了让用户下一次再使用该程序不会重新输入用户名和密码,这里我使用3种方式来存储用户名和密码1、通过普通的txt文本存储2、通过properties属性文件进行存储3、通过SharedPreferences工具类存储第一种:/** *保存用户名和

博文 来自: fgy15
没有更多推荐了,返回首页