Hướng dẫn xây dựng ứng dụng sử dụng API vân tay (FINGERPRINT API) để đăng nhập, đăng ký người dùng trong Android (P1)
Trong hướng dẫn này, chúng ta sẽ học cách sử dụng API vân tay (Fingerprint API) của Android để đăng ký và đăng nhập người dùng. Ngoài ra trong hướng dẫn này cũng hướng dẫn bạn sử dụng SharedPreference, sử dụng Intent để truyền dữ liệu và chuyển activity, sử dụng Dialog, sử dụng Cipher AES để mã hóa dữ liệu...
Android Fingerprint API đã được giới thiệu trong Android 6. Vì vậy, hướng dẫn ví dụ này sẽ sử dụng android min-sdk 23.
Mục tiêu
Chúng ta sẽ tạo Trang đăng ký nơi người dùng lần đầu tiên sẽ điền một thông tin và chọn các tùy chọn về cách xác thực trong quá trình đăng nhập.
Các tùy chọn ở bên dưới.
1. Đăng nhập bằng Xác thực Vân tay
2. Đăng nhập bằng Xác thực vân tay và mật khẩu.
Nếu đăng nhập thành công, người dùng sẽ được đưa đến trang UserProfile và dữ liệu sẽ được hiển thị trong trang.
Nếu bạn chưa sử dụng Android Fingerprint API và bạn muốn tìm hiểu thêm trước khi tiếp tục với hướng dẫn này, chúng ta có thể tìm thấy tài liệu trong hướng dẫn dành cho nhà phát triển Android tại đây .
Một số ảnh chụp màn hình ứng dụng
1. TẠO MỘT ỨNG DỤNG ANDROID MỚI
Chuyển đến menu File
Click vào New
click vào Android Application
Nhập tên dự án: AndroidFingerPrint
Trọn gói: com.inducesmile.androidfingerprint
Chọn Empty Activity
Đặt tên cho activity của bạn: MainActivity
Giữ các lựa chọn mặc định khác.
Tiếp tục click vào nút Next cho đến khi kết thúc, sau đó click vào Nút Finish.
2. CẬP NHẬT BUILD.GRADLE
Chúng ta sẽ thêm một số plugin của bên thứ ba mà chúng ta sẽ sử dụng trong hướng dẫn này.
Mở gradle.build và thêm mã bên dưới.
apply plugin: 'com.android.application'
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "24.0.1"
defaultConfig {
applicationId "com.inducesmile.androidfingerprintlogin"
minSdkVersion 23
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.0.1'
compile 'com.intuit.sdp:sdp-android:1.0.3'
compile 'com.android.support:design:25.0.1'
compile 'com.google.code.gson:gson:2.6.1'
compile 'com.android.support:cardview-v7:25.0.1'
compile 'com.android.support:support-v4:25.0.1'
testCompile 'junit:junit:4.12'
}
3. CẬP NHẬT ANDROIDMANIFEST.XML
Vì chúng ta sẽ sử dụng Android Fingerprint để xác thực người dùng nên chúng ta sẽ thêm quyền của người dùng cho Android FingerPrint. Ngoài ra, chúng ta sẽ sử dụng một lớp CustomApplication sẽ mở rộng từ lớp Application. Thêm mã bên dưới vào file manifest.xml.
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
4. CẬP NHẬT STRINGS.XML
Chúng ta sẽ cập nhật file string.xml nằm trong thư mục values bên trong thư mục res. Mở file và thêm mã bên dưới đây.
<resources>
<string name="app_name">Android FingerPrint Login</string>
<string name="sign_in">SIGN IN</string>
<string name="sign_up">SIGN UP</string>
<string name="authenticate_fingerprint">Error authenticating fingerprint</string>
<string name="auth_successful">Fingerprint authentication successful</string>
<string name="Unknown_permission_request">Unrecognized permission request</string>
<string name="permission_refused">" User refused Fingerprint permission"</string>
<string name="phone_number_hint">Phone number</string>
<string name="address_hint">Address</string>
<string name="password_hint">Password</string>
<string name="email_hint">Email</string>
<string name="username_hint">Username</string>
<string name="with_fingerprint">With Fingerprint</string>
<string name="with_fingerprint_and_password">With Fingerprint and Password</string>
<string name="login_with_fingerprint">LOGIN WITH FINGERPRINT</string>
<string name="login_now">LOGIN</string>
</resources>
5. CẬP NHẬT COLORS.XML
Mở file color.xml ở cùng vị trí với file string.xml và thêm mã bên dưới.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#d69803</color>
<color name="colorPrimaryDark">#9f7102</color>
<color name="colorAccent">#857300</color>
<color name="colorBlue">#367e90</color>
<color name="colorOpposite">#60c002</color>
<color name="colorWhite">#ffffff</color>
<color name="colorBlack">#000000</color>
<color name="colorLight">#7F7F7F</color>
<color name="colorBorder">#e6e3e2</color>
</resources>
6. CẬP NHẬT file BỐ CỤC ACTIVITY_MAIN.XML
Đây là trang giới thiệu sẽ chứa hai nút widget để đăng nhập và đăng ký. Đầu tiên, mở file layout và thêm mã bên dưới.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="@drawable/bgfinger"
tools:context="com.inducesmile.androidfingerprintlogin.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:gravity="bottom">
<Button
android:id="@+id/sign_in"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginRight="@dimen/_2sdp"
android:textColor="@color/colorWhite"
android:text="@string/sign_in"
android:textSize="@dimen/_10sdp"
android:background="@color/colorAccent"/>
<Button
android:id="@+id/sign_up"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="@color/colorWhite"
android:layout_marginLeft="@dimen/_2sdp"
android:text="@string/sign_up"
android:textSize="@dimen/_10sdp"
android:background="@color/colorAccent"/>
</LinearLayout>
</RelativeLayout>
7. CẬP NHẬT MAINACTIVITY.JAVA
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
ActionBar actionBar = getSupportActionBar();
if(null != actionBar){
actionBar.hide();
}
Button signInButton = (Button)findViewById(R.id.sign_in);
signInButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent loginIntent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(loginIntent);
}
});
Button signUpButton = (Button)findViewById(R.id.sign_up);
signUpButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent signInIntent = new Intent(MainActivity.this, SignUpActivity.class);
startActivity(signInIntent);
}
});
}
}
8. TẠO VÀ CẬP NHẬT ACTIVITY_SIGN_UP.XML
Tạo một Activity mới sẽ được sử dụng để đăng ký. file layout được đặt tên như trên. Mở file khi nó đã được tạo và thêm mã bên dưới.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_sign_up"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:paddingBottom="@dimen/_4sdp"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="@color/colorBorder"
tools:context="com.inducesmile.androidfingerprintlogin.SignUpActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/login_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/_16sdp"
android:padding="@dimen/_4sdp"
android:text=""
android:textColor="@color/colorAccent" />
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
card_view:cardElevation="@dimen/_3sdp"
card_view:cardUseCompatPadding="true">
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/username_hint"
android:textColorHint="@color/colorLight"
android:inputType="text"
android:maxLines="1"
android:background="@android:color/transparent"
android:textColor="@color/colorBlack"
android:padding="@dimen/_12sdp"/>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
card_view:cardElevation="@dimen/_3sdp"
card_view:cardUseCompatPadding="true">
<EditText
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/email_hint"
android:textColorHint="@color/colorLight"
android:inputType="textEmailAddress"
android:maxLines="1"
android:background="@android:color/transparent"
android:textColor="@color/colorBlack"
android:padding="@dimen/_12sdp" />
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
card_view:cardElevation="@dimen/_3sdp"
card_view:cardUseCompatPadding="true">
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/password_hint"
android:textColorHint="@color/colorLight"
android:inputType="textPassword"
android:maxLines="1"
android:background="@android:color/transparent"
android:textColor="@color/colorBlack"
android:padding="@dimen/_12sdp" />
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
card_view:cardElevation="@dimen/_3sdp"
card_view:cardUseCompatPadding="true">
<EditText
android:id="@+id/address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/address_hint"
android:textColorHint="@color/colorLight"
android:inputType="textPostalAddress"
android:maxLines="1"
android:background="@android:color/transparent"
android:textColor="@color/colorBlack"
android:padding="@dimen/_12sdp"/>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
card_view:cardElevation="@dimen/_3sdp"
card_view:cardUseCompatPadding="true">
<EditText
android:id="@+id/phone_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/phone_number_hint"
android:inputType="phone"
android:textColorHint="@color/colorLight"
android:maxLines="1"
android:background="@android:color/transparent"
android:textColor="@color/colorBlack"
android:padding="@dimen/_12sdp"/>
</android.support.v7.widget.CardView>
<RadioGroup
android:id="@+id/radio_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="@dimen/_16sdp"
android:orientation="horizontal">
<RadioButton
android:id="@+id/with_fingerprint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/_10sdp"
android:text="@string/with_fingerprint"/>
<RadioButton
android:id="@+id/with_fingerprint_and_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/_10sdp"
android:text="@string/with_fingerprint_and_password"/>
</RadioGroup>
<Button
android:id="@+id/sign_up_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/_24sdp"
android:paddingBottom="@dimen/_16sdp"
android:paddingTop="@dimen/_16sdp"
android:text="@string/sign_up"
android:textAllCaps="true"
android:textColor="@color/colorWhite"
android:background="@color/colorAccent"
android:textStyle="bold" />
</LinearLayout>
</ScrollView>
</LinearLayout>
9. CẬP NHẬT SIGNUPACTIVITY.JAVA
Trong lớp này, tất cả các giá trị đầu vào của người dùng để đăng ký đều được lấy và lưu trữ trong shared preference.
Mở lớp và thêm mã bên dưới.
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
public class SignUpActivity extends AppCompatActivity {
private static final String TAG = SignUpActivity.class.getSimpleName();
private TextView displayError;
private EditText username;
private EditText email;
private EditText password;
private EditText address;
private EditText phoneNumber;
private RadioGroup radioGroup;
private boolean loginOption;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_up);
setTitle("Android Fingerprint Registration");
username = (EditText)findViewById(R.id.username);
email = (EditText)findViewById(R.id.email);
password = (EditText)findViewById(R.id.password);
address = (EditText)findViewById(R.id.address);
phoneNumber = (EditText)findViewById(R.id.phone_number);
radioGroup = (RadioGroup)findViewById(R.id.radio_group);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int id) {
if(id == R.id.with_fingerprint){
loginOption = false;
}
if(id == R.id.with_fingerprint_and_password){
loginOption = true;
}
}
});
Button signUpButton = (Button) findViewById(R.id.sign_up_button);
signUpButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String usernameValue = username.getText().toString();
String emailValue = email.getText().toString();
String passwordValue = password.getText().toString();
String addressValue = address.getText().toString();
String phonenumberValue = phoneNumber.getText().toString();
int selectedButtonId = radioGroup.getCheckedRadioButtonId();
if(TextUtils.isEmpty(usernameValue) || TextUtils.isEmpty(emailValue)|| TextUtils.isEmpty(passwordValue)
|| TextUtils.isEmpty(addressValue) || TextUtils.isEmpty(phonenumberValue)){
Toast.makeText(SignUpActivity.this, "All input fields must be filled", Toast.LENGTH_LONG).show();
}else if(selectedButtonId == -1){
Toast.makeText(SignUpActivity.this, "Login option must be selected", Toast.LENGTH_LONG).show();
}else{
Gson gson = ((CustomApplication)getApplication()).getGsonObject();
UserObject userData = new UserObject(usernameValue, emailValue, passwordValue, addressValue, phonenumberValue, loginOption);
String userDataString = gson.toJson(userData);
CustomSharedPreference pref = ((CustomApplication)getApplication()).getShared();
pref.setUserData(userDataString);
username.setText("");
email.setText("");
password.setText("");
address.setText("");
phoneNumber.setText("");
Intent loginIntent = new Intent(SignUpActivity.this, LoginActivity.class);
startActivity(loginIntent);
}
}
});
}
}
Ở phần tiếp theo chúng ta sẽ tiếp tục hoàn thiện ứng dụng và sử dụng API vân tay để đăng nhập.
Xem phần tiếp theo tại đây
Theo dõi VnCoder trên Facebook, để cập nhật những bài viết, tin tức và khoá học mới nhất!