Мое приложение продолжает падать, когда я перехожу на другой вид деятельности - PullRequest
0 голосов
/ 17 мая 2019

Я пытаюсь создать приложение под названием 'moviesinfo', в котором у меня есть страница входа, с опцией регистрации и забытого пароля.Когда я пытаюсь войти в систему, приложение вылетает.Я также не знаю, хранятся ли данные, введенные на странице регистрации, в базе данных или нет.

Это мой mainactivity.java

package com.example.moviesinfo;

import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    SQLiteDatabase db;
    SQLiteOpenHelper openHelper;
    private EditText user;
    private EditText password;
    private Button btn;
    private Button btn2;
    private Button forgot;
    Cursor cursor;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        forgot=findViewById(R.id.forgot);
        btn2=(Button) findViewById(R.id.signup);
        user= (EditText) findViewById(R.id.username);
        password = (EditText) findViewById(R.id.password);
        btn = (Button) findViewById(R.id.login);
        openHelper= new DatabaseHelper(this);
        db=openHelper.getReadableDatabase();

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String username1= user.getText().toString();
                String password1= password.getText().toString();

                cursor = db.rawQuery("SELECT * FROM " +DatabaseHelper.TABLENAME + " WHERE " + DatabaseHelper.COL2 + "=? AND " + DatabaseHelper.COL3+"=?", new String[]{username1,password1});

                if (cursor!=null){
                    if (cursor.getCount()>0){
                        cursor.moveToNext();
                        Intent intent = new Intent(MainActivity.this,listmenu.class);
                        startActivity(intent);
                        //Toast.makeText(getApplicationContext(),"Login Successful", Toast.LENGTH_SHORT).show();//
                    }else{
                        Toast.makeText(getApplicationContext(),"Error" , Toast.LENGTH_SHORT).show();
                    }
                }
            }
        });


        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sign_up();
            }
        });

        forgot.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                forgot();
            }
        });
    }


    private void sign_up()
    {
        Intent intent= new Intent(MainActivity.this, signup.class);
        startActivity(intent);
    }

    private void forgot()
    {
        Intent intent= new Intent(MainActivity.this, forgot.class);
        startActivity(intent);
    }
}

Это signup.java класс

package com.example.moviesinfo;

import android.content.ContentValues;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.lang.String;
import java.util.ArrayList;

public class signup extends AppCompatActivity {
    SQLiteOpenHelper openHelper;
    DatabaseHelper db;
    SQLiteDatabase db1;
    public String uname = "";
    public String pwd = "";
    public ArrayList<String> cpwd = new ArrayList<String>();

    EditText e1, e2, e3;
    Button b1,b2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_signup);
        openHelper= new DatabaseHelper(this);
        e1 = (EditText) findViewById(R.id.username);
        e2 = (EditText) findViewById(R.id.password);
        e3 = (EditText) findViewById(R.id.cpwd);
        b1 = (Button) findViewById(R.id.save);
        b2 = (Button) findViewById(R.id.login2);


        b1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            db1=openHelper.getWritableDatabase();
            String username =e1.getText().toString();
                String password =e2.getText().toString();
                String confirm_password =e3.getText().toString();
                insert_data(username,password,confirm_password);
            }
        });

        b2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(signup.this,MainActivity.class);
                startActivity(intent);
            }
        });


    }

    public void insert_data(String username, String password, String confirm_password)
    {
        ContentValues contentValues = new ContentValues();
        contentValues.put(DatabaseHelper.COL2, username);
        contentValues.put(DatabaseHelper.COL3, password);
        contentValues.put(DatabaseHelper.COL4, confirm_password);
        long id=db1.insert(DatabaseHelper.TABLENAME, null, contentValues);
    }
}

Это DatabseHelper.java класс

package com.example.moviesinfo;

import com.example.moviesinfo.signup;

import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String DATABASE_NAME="userdetails.db";
    public static final String TABLENAME="user details";
    public static final String COL1="id";
    public static final String COL2="username";
    public static final String COL3="password";
    public static final String COL4="confirmpassword";



    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null,1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + "TABLENAME(ID INTEGER PRIMARY KEY AUTOINCREMENT,USERNAME TEXT,PASSWORD TEXT,CONFIRMPASSWORD TEXT)");

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " +TABLENAME);
        onCreate(db);
    }

}

Я ожидаю, что когда я нажму кнопку входа в систему, она перейдет к следующему действию с проверкой данных для входа в базу данных.

1 Ответ

1 голос
/ 19 мая 2019

Выпуск 1

Первая проблема, с которой вы столкнетесь, заключается в том, что имя таблицы данные пользователя содержит пробел. пользователь будет извлечен в качестве идентификатора, но затем синтаксический анализатор SQL не ожидает details , это не ключевое слово или предложение и, таким образом, синтаксическая ошибка согласноСледующее, что будет найдено в журнале: -

5-19 14:09:14.335 26779-26779/s.e.so56180693anotheractivity E/AndroidRuntime: FATAL EXCEPTION: main
    Process: s.e.so56180693anotheractivity, PID: 26779
    java.lang.RuntimeException: Unable to start activity ComponentInfo{s.e.so56180693anotheractivity/s.e.so56180693anotheractivity.MainActivity}: android.database.sqlite.SQLiteException: near "details": syntax error (code 1 SQLITE_ERROR): , while compiling: CREATE TABLE IF NOT EXISTS user details(_id INTEGER PRIMARY KEY,username TEXT,password TEXT, confirmpassword TEXT)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        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:858)
     Caused by: android.database.sqlite.SQLiteException: near "details": syntax error (code 1 SQLITE_ERROR): , while compiling: CREATE TABLE IF NOT EXISTS user details(_id INTEGER PRIMARY KEY,username TEXT,password TEXT, confirmpassword TEXT)
        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:903)
        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:514)
        at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
        at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
        at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
        at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1769)
        at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1698)
        at s.e.so56180693anotheractivity.DatabaseHelper.onCreate(DatabaseHelper.java:33)
        at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:393)
        at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:322)
        at s.e.so56180693anotheractivity.MainActivity.onCreate(MainActivity.java:35)
        at android.app.Activity.performCreate(Activity.java:7136)

Обычно идентификатор может содержать недопустимые символы, напримеркак пробел, начните с числа, если оно заключено в определенные символы в соответствии с: -

Если вы хотите использовать ключевое слово в качестве имени, вам нужно заключить его в кавычки.Существует четыре способа цитирования ключевых слов в SQLite:

  • 'ключевое слово' Ключевое слово в одинарных кавычках является строковым литералом.
  • "ключевое слово" Ключевое слово в двойных кавычкахэто идентификатор.
  • [ключевое слово] Ключевое слово, заключенное в квадратные скобки, является идентификатором.Это не стандартный SQL.Этот механизм цитирования используется MS Access и SQL Server и включен в SQLite для совместимости.
  • ключевое слово Ключевое слово, заключенное в серьезные акценты (код ASCII 96), является идентификатором.Это не стандартный SQL.Этот механизм цитирования используется MySQL и включен в SQLite для совместимости.

Например, вы можете иметь: -

public static final String TABLENAME="user details"; //<<<<<<<<<< cannot have spaces in a name unless enclosed
//!!!!NOTE!!!! ONLY 1 of the below would be allowed
public static final String TABLENAME="`user details`"; //<<<<<<<<<< e.g (with space)
public static final String TABLENAME= "[user details]";
public static final String TABLENAME = "\"user details\""; 
public static final String TABLENAME = "'user details'";
public static final String TABLENAME="user_details"; //<<<<<<<<<< changed to this for testing.
  • Читать комментарии

Исправление для проблемы 1

public static final String TABLENAME="user details";

было изменено на: -

public static final String TABLENAME="user_details";

Приложение было удалено и перезапущено.


Проблема 2

Следующая проблема заключается в том, что SQL для создания таблицы не будет создавать таблицу с именем в соответствии со значением, которое имеет константа TABLENAME ( user_details после применения исправления 1).Таблица называется TABLENAME, так как слово TABLENAME заключено в кавычки.

Это приводит к исключению: -

2019-05-19 13:56:15.118 26443-26443/s.e.so56180693anotheractivity E/SQLiteLog: (1) no such table: user_details

Исправление для проблемы 2

Ниже описано, как этоБыло бы предположить, что CREATE TABLE sql настроен: -

    //Uses the identifiers (names) as per the variables
    db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLENAME + "(" +
            COL1 + " INTEGER PRIMARY KEY," + // NO NEED FOR INEFFICIENT AUTOINCREMENT
            COL2 + " TEXT  UNIQUE," + //ADDED UNIQUE so that user names are not duplicated
            COL3 + " TEXT, " +
            COL4 + " TEXT" +
            ")"
    );
  • То есть константы используются для имен.
  • ВАЖНО , так как этоизменив схему базы данных и указав, что база данных существует, вы ДОЛЖНЫ удалить ее, чтобы запустить метод DatabaseHelper onCreate .
  • Было добавлено ключевое слово UNIQUE, в противном случае можно добавить того же пользователя.несколько раз

Вопрос

Я также не знаю, хранятся ли данные, введенные на странице регистрации, в базе данных или нет.

Чтобы вы знали или нет, и, как вы теперь должны знать, просматривая журнал, внесите следующие изменения в метод insert_data, чтобы узнать, хранятся ли данные.

public long insert_data(String username, String password, String confirm_password) // Signature changed to return long (id)
{
    ContentValues contentValues = new ContentValues();
    contentValues.put(DatabaseHelper.COL2, username);
    contentValues.put(DatabaseHelper.COL3, password);
    contentValues.put(DatabaseHelper.COL4, confirm_password);
    long id=db1.insert(DatabaseHelper.TABLENAME, null, contentValues);
    //TODO REMOVE LOGGING BEFORE PUBLISHING THE APP
    if (id > 0) {
        Log.d("INSERTUSERDETAILSROW","The row was successfully inserted into the " + DatabaseHelper.TABLENAME + " table.");
    } else {
        Log.d("INSERTUSERDETAILSROW","Row not inserted!!!!!!!!!!");
    }
    return id; // Can be useful to have access to the id that was generated. Note method signature change 
}

Пример вывода: -

iВ журнале: -

D/INSERTUSERDETAILSROW: The row was successfully inserted into the user_details table.

Выпуск 4

Если значения пароля и verify_password не совпадают, строка все равно добавляется, то есть значения verify_password бесполезны.

Исправление для проблемы 4

Добавлена ​​проверка, добавляющая данные только в том случае, если совпадают значения пароля и Подтверждение пароля.Если этого не произойдет, выдается тост.

    b1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            db1=openHelper.getWritableDatabase();
            String username =e1.getText().toString();
            String password =e2.getText().toString();
            String confirm_password =e3.getText().toString();
            if (password.equals(confirm_password)) {
                insert_data(username, password, confirm_password);
            } else {
                Toast.makeText(v.getContext(),"Password and Confirm Password do not match. Data not added.",Toast.LENGTH_LONG).show();
            }
        }
    });

Выпуск 5

Хотя это не будет проблемой, вы не должны начинать действие, если хотите вернуться издеятельность как таковая уничтожит начальную деятельность и начнет другую.Правильный способ - завершить действие, и оно затем вернется к фактическому действию, с которого оно было запущено.

Исправление для проблемы 5

    b2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //Intent intent = new Intent(signup.this,MainActivity.class);
            //startActivity(intent);
            finish(); //<<<<<<<<<< Proper way to return
        }
    });

Готово

Вот и все.Приложение теперь должно быть относительно функциональным с точки зрения входа в систему и регистрации.

...