#database #sqlite #android-studio #authentication #android-sqlite
#База данных #sqlite #android-studio #аутентификация #android-sqlite
Вопрос:
Я работаю над Android Studio для создания приложения для входа и регистрации с использованием SQLite. Я не мог понять свою ошибку: приложение закрывается автоматически. Надеюсь, кто-нибудь может помочь мне с неизвестной ошибкой.
Упражнение 1 (Основное действие): Если данные имени пользователя и пароля указаны правильно. Он переходит к HandsOnActivity (действие 4).
Действие 2 (Действие регистрации): вводятся данные пользователя (имя пользователя, пароль, подтверждение пароля, адрес электронной почты, пароль) и кнопка регистрации. Чтобы проверить пользователя и добавить его в базу данных Sqlite. Имя пользователя, пароль, подтверждение пароля вводятся из TextInputEditText и email, номер телефона из EditText. Activity3 и Activity 4 были добавлены с помощью простого текстового поля и макетов с помощью setContentView(). Я хочу проверить как адрес электронной почты, так и имя пользователя при входе в приложение.
MainActivity.java
package com.android.loginapp;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private EditText EditTextUserName;
private EditText EditTextUserPassword;
private Button buttonLogin;
private Button buttonReset;
private Button buttonCreateUser;
LoginDatabase MyDb;
String username = EditTextUserName.getText().toString();
String password = EditTextUserPassword.getText().toString();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_activity);
EditTextUserName = findViewById(R.id.edittext_username);
EditTextUserPassword = findViewById(R.id.edittext_password);
buttonLogin = findViewById(R.id.button_login);
buttonReset = findViewById(R.id.button_reset);
buttonCreateUser = findViewById(R.id.button_createaccount);
MyDb = new LoginDatabase(this);
//Reset function
buttonReset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EditTextUserName.setText("");
EditTextUserPassword.setText("");
}
});
//Create a new user function
buttonCreateUser.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent registerIntent = new Intent(MainActivity.this,RegistrationActivity.class);
startActivity(registerIntent);
}
});
//Login button Navigation and Verification Function
buttonLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(username.isEmpty() | password.isEmpty()){
EditTextUserName.setError("Field can't be empty");
EditTextUserPassword.setError("Field can't be empty");
} else{
boolean checkUsernamePassword = MyDb.checkUsernamePassword(username, password);
if(checkUsernamePassword){
Toast.makeText(MainActivity.this,"UsernamePassword Login Successful",Toast.LENGTH_SHORT).show();
Intent intent1 = new Intent(getApplicationContext(), HandsOnActivity.class);
startActivity(intent1);
} else{
Toast.makeText(MainActivity.this,"Invalid Credentials",Toast.LENGTH_SHORT).show();
}
boolean checkEmailPassword = MyDb.checkEmailPassword(username, password);
if(checkEmailPassword){
Toast.makeText(MainActivity.this,"EmailPassword Login Successful",Toast.LENGTH_SHORT).show();
Intent intent2 = new Intent(getApplicationContext(), HandsOnActivity.class);
startActivity(intent2);
}else {
Toast.makeText(MainActivity.this,"Invalid Credentials",Toast.LENGTH_SHORT).show();
}
}
}
});
}
}
Активность регистрации. java-файл
package com.android.loginapp;
import android.content.Intent;
import android.os.Bundle;
import android.util.Patterns;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.textfield.TextInputLayout;
public class RegistrationActivity extends AppCompatActivity {
TextInputLayout textInputUserName;
TextInputLayout textInputUserPassword;
TextInputLayout textInputUserConfirmPassword;
EditText userPhoneNumber;
EditText userEmailAddress;
Button buttonRegisterUser;
String MobilePattern="[0-9]{10}";
LoginDatabase MyDb;
String usernameInput = textInputUserName.getEditText().getText().toString().trim();
String passwordInput = textInputUserPassword.getEditText().getText().toString().trim();
String confirmPasswordInput = textInputUserConfirmPassword.getEditText().getText().toString().trim();
String phoneNumberInput = userPhoneNumber.getText().toString();
String emailInput = userEmailAddress.getText().toString().trim();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.registration_activity);
textInputUserName = findViewById(R.id.text_input_username);
textInputUserPassword = findViewById(R.id.text_input_password);
textInputUserConfirmPassword = findViewById(R.id.text_input_confirmPassword);
userPhoneNumber = (EditText) findViewById(R.id.editTextPhone);
userEmailAddress = (EditText) findViewById(R.id.edittext_emailAddress);
buttonRegisterUser = (Button) findViewById(R.id.button_registerUser);
MyDb = new LoginDatabase(this);
buttonRegisterUser.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!validateEmail() | !validateUsername() | !validatePassword() | !validatePhoneNumber()) {
return;
}else if(passwordInput.equals(confirmPasswordInput)){
boolean checkUser = MyDb.checkUsername(usernameInput);
boolean checkEmail = MyDb.checkEmail(emailInput);
if(!checkUser amp; !checkEmail){
boolean insert = MyDb.insertData(usernameInput, passwordInput, phoneNumberInput, emailInput);
if (insert){
Toast.makeText(getApplicationContext(),"Registered Successfully",Toast.LENGTH_SHORT).show();
Intent intent = new Intent(RegistrationActivity.this,RegisteredActivity.class);
startActivity(intent);
}else {
Toast.makeText(RegistrationActivity.this, "Registration Failed", Toast.LENGTH_SHORT).show();
}
}else {
Toast.makeText(RegistrationActivity.this,"User already exists",Toast.LENGTH_SHORT).show();
}
}else {
Toast.makeText(getApplicationContext(),"Password doesn't match",Toast.LENGTH_SHORT).show();
}
}
});
}
private boolean validateEmail () {
if(emailInput.isEmpty()) {
userEmailAddress.setError("Field can't be empty");
return false;
} else if (!Patterns.EMAIL_ADDRESS.matcher(emailInput).matches()){
userEmailAddress.setError("Please enter a valid email address");
return false;
} else {
userEmailAddress.setError(null);
return true;
}
}
private boolean validateUsername() {
if(usernameInput.isEmpty()) {
textInputUserName.setError("Field can't be empty");
return false;
} else if(usernameInput.length()>15){
textInputUserName.setError("Username too long");
return false;
} else {
textInputUserName.setError(null);
return true;
}
}
private boolean validatePassword(){
if(passwordInput.isEmpty() | confirmPasswordInput.isEmpty()){
textInputUserPassword.setError("Field can't be empty");
textInputUserConfirmPassword.setError("Field can't be empty");
return false;
} else {
textInputUserPassword.setError(null);
textInputUserConfirmPassword.setError(null);
return true;
}
}
private boolean validatePhoneNumber(){
if(phoneNumberInput.isEmpty()){
userPhoneNumber.setError("Field can't be empty");
return false;
} else if(phoneNumberInput.matches(MobilePattern)){
return phoneNumberInput.length() > 6 amp;amp; phoneNumberInput.length() <=10;
}else{
userPhoneNumber.setError("Number invalid");
return false;
}
}
}
Database File
package com.android.loginapp;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class LoginDatabase extends SQLiteOpenHelper {
public static final String DBNAME = "Login.db";
public LoginDatabase(Context context) {
super(context, "Login.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE users(username TEXT primary key, password TEXT, phoneNumber INTEGER, email VARCHAR(320))");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE if exists users");
}
public boolean insertData(String username, String password, String phoneNumber, String email){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("username", username);
contentValues.put("password", password);
contentValues.put("phoneNumber", phoneNumber);
contentValues.put("email", email);
long result = db.insert("users", null,contentValues);
if(result == -1) return false;
else return true;
}
public boolean checkUsername(String username){
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM users WHERE username = ?", new String[] {username});
if(cursor.getCount()>0) return true; // If user exists
else return false;
}
public boolean checkUsernamePassword(String username, String password){
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM users where username = ? and password = ?", new String[] {username,password});
if(cursor.getCount()>0) return true;
else return false;
}
public boolean checkEmail(String email){
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM users WHERE email = ?",new String[] {email});
if(cursor.getCount()>0) return true;
else return false;
}
public boolean checkEmailPassword(String email, String password){
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM users WHERE email = ? and password = ?",new String[] {email, password});
if(cursor.getCount()>0) return true;
else return false;
}
}
Файл манифеста
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.loginapp">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".RegistrationActivity">
</activity>
<activity android:name=".RegisteredActivity">
</activity>
<activity android:name=".HandsOnActivity">
</activity>
</application>
</manifest>
Ошибка обнаружена после отладки:
$ adb shell am start -n "com.android.loginapp/com.android.loginapp.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -D
Waiting for application to come online: com.android.loginapp | com.android.loginapp.test
Waiting for application to come online: com.android.loginapp | com.android.loginapp.test
Connected to process 1516 on device 'samsung-sm_m307f-RZ8M92DBXEE'.
Connecting to com.android.loginapp
Connected to the target VM, address: 'localhost:8602', transport: 'socket'
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
I/ndroid.loginap: Late-enabling -Xcheck:jni
E/ndroid.loginap: Unknown bits set in runtime_flags: 0x8000
D/ActivityThread: setConscryptValidator
setConscryptValidator - put
W/ActivityThread: Application com.android.loginapp is waiting for the debugger on port 8100...
I/System.out: Sending WAIT chunk
I/System.out: Debugger has connected
I/System.out: waiting for debugger to settle...
I/chatty: uid=10111(com.android.loginapp) identical 3 lines
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: debugger has settled (1499)
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.loginapp, PID: 1516
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.android.loginapp/com.android.loginapp.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.text.Editable android.widget.EditText.getText()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3341)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2147)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7814)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1068)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.text.Editable android.widget.EditText.getText()' on a null object reference
at com.android.loginapp.MainActivity.<init>(MainActivity.java:17)
at java.lang.Class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
at android.app.Instrumentation.newActivity(Instrumentation.java:1251)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3329)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2147)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7814)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1068)
Disconnected from the target VM, address: 'localhost:8602', transport: 'socket'
Комментарии:
1. После изменения инициализации имени пользователя и пароля в Activity1 на 1. Строковое имя пользователя = EditTextUserName ! = null? EditTextUserName.getText().toString(): null; 2. Строковый пароль = EditTextUserPassword != null? EditTextUserPassword.getText().toString(): null; Приложение показывает только 1-е действие и закрывается при нажатии кнопки создать пользователя.
2. . Я опубликовал ответ ниже
Ответ №1:
Вы неправильно выполняете следующие действия
String username = EditTextUserName.getText().toString();
String password = EditTextUserPassword.getText().toString();
Два приведенных выше утверждения необходимо записать после следующих утверждений:
buttonLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(username.isEmpty() | password.isEmpty()){
EditTextUserName.setError("Field can't be empty");
EditTextUserPassword.setError("Field can't be empty");
} else{
Просто скопируйте первые 2 инструкции ниже. Причина, по которой вы получали NullPointer, заключалась в том, что вы обращались к переменным, которые даже не были инициализированы.
Итак, ваш фактический код будет выглядеть так:-
buttonLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(username.isEmpty() | password.isEmpty()){
EditTextUserName.setError("Field can't be empty");
EditTextUserPassword.setError("Field can't be empty");
} else{
username = EditTextUserName.getText().toString();
password = EditTextUserPassword.getText().toString();
boolean checkUsernamePassword = MyDb.checkUsernamePassword(username, password);
if(checkUsernamePassword){
Toast.makeText(MainActivity.this,"UsernamePassword
Login Successful",Toast.LENGTH_SHORT).show();
Intent intent1 = new Intent(getApplicationContext(),
HandsOnActivity.class);
startActivity(intent1);
} else{
Toast.makeText(MainActivity.this,"Invalid
Credentials",Toast.LENGTH_SHORT).show();
}
Комментарии:
1. Большое спасибо @Nadeem Shaikh! Спасибо за помощь. теперь код работает нормально.