Android——用户登陆及用户名和密码的保存
在之前的学习过程中已经将Android学习完了,但是在后面将近一年的时间里都没有进行过Android开发,所以对Android的所有的知识点又有点忘记了,因此才会继续的学习Android,做出这个学习笔记。另外:由于在暑假的时候要开发Android项目,所以对于这些Android知识点也都要熟练的掌握。
目录
在实际开发中,开发android软件的过程需要不断地进行测试。而使用Junit测试框架,侧是正规Android开发的必用技术,在Junit中可以得到组件,可以模拟发送事件和检测程序处理的正确性。
首先建立一个新的Android项目,这里我命名为:junit,然后编写AndroidManifest.xml文件,在里面添加uses-library和instrumentation两个属性,代码如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="lq.wangzhen.junit" 4 android:versionCode="1" 5 android:versionName="1.0" > 6 7 <instrumentation 8 android:name="android.test.InstrumentationTestRunner" 9 android:label="Tests for My App" 10 android:targetPackage="lq.wangzhen.junit" /> 11 12 <uses-sdk 13 android:minSdkVersion="8" 14 android:targetSdkVersion="8" /> 15 16 <application 17 android:allowBackup="true" 18 android:icon="@drawable/ic_launcher" 19 android:label="@string/app_name" 20 android:theme="@style/AppTheme" > 21 <uses-library android:name="android.test.runner" /> 22 23 <activity 24 android:name="lq.wangzhen.junit.DemoActivity" 25 android:label="@string/app_name" > 26 <intent-filter> 27 <action android:name="android.intent.action.MAIN" /> 28 29 <category android:name="android.intent.category.LAUNCHER" /> 30 </intent-filter> 31 </activity> 32 </application> 33 34 </manifest>
其中在instrumentation中配置的targetPackage为测试类所在的包,我这里的包名为:lq.wangzhen.junit
编写完以上的代码以后,则可以在lq.wangzhen.junit包中定义一个类,这个类中包含一个Add方法,然后我们进行此方法的测试工作。代码如下:
Services.java
1 package lq.wangzhen.junit; 2 3 public class Service { 4 5 /** 6 * 提供一个方法,可以接收两个整型数据 7 * @param x 8 * @param y 9 * @return 10 */ 11 public static int add(int x,int y){ 12 return x+y; 13 } 14 }
下面编写测试类,此类命名为:TestAddService.java,此类必须要集成AndroidTestCase才能够作为测试类进行使用,代码如下:
1 package lq.wangzhen.junit; 2 3 import junit.framework.Assert; 4 import android.test.AndroidTestCase; 5 6 public class TestAddService extends AndroidTestCase { 7 8 public void testAdd(){ 9 int result = Service.add(3, 5); 10 Assert.assertEquals(8, result); 11 } 12 }
以上就是一个简单的Android测试过程
完成完以上的测试功能后,下面我们来完成一个简单的用户登陆功能,现在要求用户输入用户名和密码,并选择是否保存用户名和密码,如果保存用户名和密码的话,我们要在ROM进行保存,然后在用户下次打开此软件时会自动的从文件中提取出对应的用户名和密码,填入到登陆框中,在本节中就先对界面进行一下设计,界面设计的xml文件如下:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 7 <TextView 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content" 10 android:text="@string/username" /> 11 <EditText 12 android:id="@+id/et_username" 13 android:layout_width="fill_parent" 14 android:layout_height="wrap_content" 15 android:hint="@string/username" 16 /> 17 18 <TextView 19 android:layout_width="wrap_content" 20 android:layout_height="wrap_content" 21 android:text="@string/password" /> 22 <EditText 23 android:id="@+id/et_password" 24 android:layout_width="fill_parent" 25 android:layout_height="wrap_content" 26 android:hint="@string/password" 27 android:inputType="textPassword" 28 /> 29 30 31 <RelativeLayout 32 android:layout_width="fill_parent" 33 android:layout_height="wrap_content"> 34 <Button 35 android:id="@+id/button" 36 android:layout_width="wrap_content" 37 android:layout_height="wrap_content" 38 android:text="@string/login" 39 android:layout_alignParentLeft="true"/> 40 <CheckBox 41 android:id="@+id/cb_remember" 42 android:layout_width="wrap_content" 43 android:layout_height="wrap_content" 44 android:text="@string/remember_password" 45 android:layout_alignParentRight="true"/> 46 </RelativeLayout> 47 48 </LinearLayout>
下面开始编写MainActivity.java文件,代码如下:
1 package lq.wangzhen.file; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.text.TextUtils; 6 import android.util.Log; 7 import android.view.View; 8 import android.view.View.OnClickListener; 9 import android.widget.Button; 10 import android.widget.CheckBox; 11 import android.widget.EditText; 12 import android.widget.Toast; 13 14 public class MainActivity extends Activity implements OnClickListener { 15 16 private static final String TAG = "MainActivity"; 17 private EditText et_username; 18 private EditText et_password; 19 private Button button; 20 private CheckBox cb_remember; 21 22 @Override 23 protected void onCreate(Bundle savedInstanceState) { 24 super.onCreate(savedInstanceState); 25 setContentView(R.layout.activity_main); 26 27 et_username = (EditText) this.findViewById(R.id.et_username); 28 et_password = (EditText) this.findViewById(R.id.et_password); 29 button = (Button) this.findViewById(R.id.button); 30 cb_remember = (CheckBox) this.findViewById(R.id.cb_remember); 31 32 33 button.setOnClickListener(this); 34 35 } 36 37 @Override 38 public void onClick(View v) { 39 // TODO Auto-generated method stub 40 switch (v.getId()) { 41 case R.id.button: 42 43 String username = et_username.getText().toString().trim(); 44 String password = et_password.getText().toString().trim(); 45 46 if(TextUtils.isEmpty(username) || TextUtils.isEmpty(password)){ 47 Toast.makeText(this, R.string.error, Toast.LENGTH_SHORT).show(); 48 return; 49 } 50 if(cb_remember.isChecked()){ 51 Log.i(TAG, "保存用户名和密码,"+username+":"+password); 52 }else{ 53 Log.i(TAG, "没有保存用户名和密码,"+username+":"+password); 54 } 55 break; 56 } 57 } 58 59 60 }
以上程序所使用的strings.xml文件的内容如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 4 <string name="app_name">file</string> 5 <string name="hello_world">Hello world!</string> 6 <string name="menu_settings">Settings</string> 7 8 <string name="username">用户名</string> 9 <string name="password">密码</string> 10 <string name="login">登陆</string> 11 <string name="remember_password">记住密码</string> 12 <string name="error">用户名和密码不能为空</string> 13 14 </resources>
下面对以上的程序进行修改,加入可以将用户名和代码保存到文件中的功能,首先新建立一个Service文件,用来操作文件的保存,代码如下:
1 package lq.wangzhen.service; 2 3 import java.io.FileOutputStream; 4 5 import android.content.Context; 6 7 public class FileService { 8 9 10 private Context context; 11 12 public FileService(Context context){ 13 this.context = context; 14 } 15 /** 16 * 把用户名和密码保存到手机ROM 17 * @param password 输入要保存的密码 18 * @param username 要保存的用户名 19 * @param filename 保存到哪个文件 20 * @return 21 */ 22 public boolean saveToRom(String password,String username,String filename) throws Exception{ 23 //以私有的方式打开一个文件 24 FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE); 25 String result = username+":"+password; 26 fos.write(result.getBytes()); 27 fos.flush(); 28 fos.close(); 29 return true; 30 } 31 }
修改MainActivity.java文件,代码如下:
1 package lq.wangzhen.file; 2 3 import lq.wangzhen.service.FileService; 4 import android.app.Activity; 5 import android.os.Bundle; 6 import android.text.TextUtils; 7 import android.util.Log; 8 import android.view.View; 9 import android.view.View.OnClickListener; 10 import android.widget.Button; 11 import android.widget.CheckBox; 12 import android.widget.EditText; 13 import android.widget.Toast; 14 15 public class MainActivity extends Activity implements OnClickListener { 16 17 private static final String TAG = "MainActivity"; 18 private EditText et_username; 19 private EditText et_password; 20 private Button button; 21 private CheckBox cb_remember; 22 private FileService fileService; 23 24 @Override 25 protected void onCreate(Bundle savedInstanceState) { 26 super.onCreate(savedInstanceState); 27 setContentView(R.layout.activity_main); 28 29 et_username = (EditText) this.findViewById(R.id.et_username); 30 et_password = (EditText) this.findViewById(R.id.et_password); 31 button = (Button) this.findViewById(R.id.button); 32 cb_remember = (CheckBox) this.findViewById(R.id.cb_remember); 33 34 35 button.setOnClickListener(this); 36 37 //初始化文件服务 38 fileService = new FileService(this); 39 40 } 41 42 @Override 43 public void onClick(View v) { 44 // TODO Auto-generated method stub 45 switch (v.getId()) { 46 case R.id.button: 47 48 String username = et_username.getText().toString().trim(); 49 String password = et_password.getText().toString().trim(); 50 51 if(TextUtils.isEmpty(username) || TextUtils.isEmpty(password)){ 52 Toast.makeText(this, R.string.error, Toast.LENGTH_SHORT).show(); 53 return; 54 } 55 if(cb_remember.isChecked()){ 56 Log.i(TAG, "保存用户名和密码,"+username+":"+password); 57 try { 58 boolean result = fileService.saveToRom(password, username, "private.txt"); 59 if(result){ 60 Toast.makeText(getApplicationContext(), R.string.success, Toast.LENGTH_SHORT).show(); 61 }else{ 62 Toast.makeText(getApplicationContext(), R.string.failed, Toast.LENGTH_SHORT).show(); 63 } 64 } catch (Exception e) { 65 // TODO Auto-generated catch block 66 e.printStackTrace(); 67 Toast.makeText(getApplicationContext(), R.string.failed, Toast.LENGTH_SHORT).show(); 68 } 69 } 70 break; 71 } 72 } 73 74 75 }
在strings.xml文件中添加以下的内容:
1 <string name="success">保存成功</string> 2 <string name="failed">保存失败</string>
运行程序,即可保存成功,保存的文件默认的保存在data/data/lq.wangzhen.file/files文件夹中,其中lq.wangzhen.file表示Activity所在的包名。下面在此程序的基础上加入可以从文件中读取用户名和密码的功能,首先在FileService.java文件中添加以下的一个方法,用来从ROM中读取文件内容。
1 public Map<String,String> getUserInfo(String filename) throws Exception{ 2 File file = new File("data/data/lq.wangzhen.file/files/"+filename); 3 FileInputStream fis = new FileInputStream(file); 4 //以上的两句代码也可以通过以下的代码实现: 5 //FileInputStream fis = context.openFileInput(filename); 6 byte[] data = StreamTools.getBytes(fis); 7 String result = new String(data); 8 String results[] = result.split(":"); 9 Map<String,String> map = new HashMap<String,String>(); 10 map.put("username", results[0]); 11 map.put("password", results[1]); 12 return map; 13 }
在此方法中调用了一个StreamTools.getBytes()方法,此方法是专门用来将一个InputStream流转换为byte数组返回的,所以我们编写此方法为:
1 package lq.wangzhen.util; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.InputStream; 5 6 public class StreamTools { 7 8 /** 9 * 把InputStream中的内容读出来,放到一个byte[]中返回 10 * @param is 11 * @return 12 * @throws Exception 13 */ 14 public static byte[] getBytes(InputStream is) throws Exception{ 15 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 16 byte[] buffer = new byte[1024]; 17 int len = 0; 18 while((len=is.read(buffer)) != -1){ 19 baos.write(buffer, 0, len); 20 } 21 baos.flush(); 22 baos.close(); 23 return baos.toByteArray(); 24 } 25 }
最后再次修改MainActivity.java文件,调用编写的getUserInfo方法:
1 package lq.wangzhen.file; 2 3 import java.util.Map; 4 5 import lq.wangzhen.service.FileService; 6 import android.app.Activity; 7 import android.os.Bundle; 8 import android.text.TextUtils; 9 import android.util.Log; 10 import android.view.View; 11 import android.view.View.OnClickListener; 12 import android.widget.Button; 13 import android.widget.CheckBox; 14 import android.widget.EditText; 15 import android.widget.Toast; 16 17 public class MainActivity extends Activity implements OnClickListener { 18 19 private static final String TAG = "MainActivity"; 20 private EditText et_username; 21 private EditText et_password; 22 private Button button; 23 private CheckBox cb_remember; 24 private FileService fileService; 25 26 @Override 27 protected void onCreate(Bundle savedInstanceState) { 28 super.onCreate(savedInstanceState); 29 setContentView(R.layout.activity_main); 30 31 et_username = (EditText) this.findViewById(R.id.et_username); 32 et_password = (EditText) this.findViewById(R.id.et_password); 33 button = (Button) this.findViewById(R.id.button); 34 cb_remember = (CheckBox) this.findViewById(R.id.cb_remember); 35 36 37 button.setOnClickListener(this); 38 39 //初始化文件服务 40 fileService = new FileService(this); 41 42 try { 43 Map<String,String> map = fileService.getUserInfo("private.txt"); 44 et_username.setText(map.get("username")); 45 et_password.setText(map.get("password")); 46 } catch (Exception e) { 47 // TODO Auto-generated catch block 48 e.printStackTrace(); 49 } 50 51 52 } 53 54 @Override 55 public void onClick(View v) { 56 // TODO Auto-generated method stub 57 switch (v.getId()) { 58 case R.id.button: 59 60 String username = et_username.getText().toString().trim(); 61 String password = et_password.getText().toString().trim(); 62 63 if(TextUtils.isEmpty(username) || TextUtils.isEmpty(password)){ 64 Toast.makeText(this, R.string.error, Toast.LENGTH_SHORT).show(); 65 return; 66 } 67 if(cb_remember.isChecked()){ 68 Log.i(TAG, "保存用户名和密码,"+username+":"+password); 69 try { 70 boolean result = fileService.saveToRom(password, username, "private.txt"); 71 if(result){ 72 Toast.makeText(getApplicationContext(), R.string.success, Toast.LENGTH_SHORT).show(); 73 }else{ 74 Toast.makeText(getApplicationContext(), R.string.failed, Toast.LENGTH_SHORT).show(); 75 } 76 } catch (Exception e) { 77 // TODO Auto-generated catch block 78 e.printStackTrace(); 79 Toast.makeText(getApplicationContext(), R.string.failed, Toast.LENGTH_SHORT).show(); 80 } 81 } 82 break; 83 } 84 } 85 86 87 }
以上就是这次学习的全部内容,后面会继续的对这个程序作出休整。