1

В течение последних трех дней я не могу понять, с какими проблемами сталкиваются. Я получаю null для некоторых переменных, а не для других, а иногда и для всех. В частности, проблема связана с устройствами Samsung, использующими Lollipop.Странные ошибки SQLite на устройствах Lollipop Samsung

В основном я занимаюсь хранением возвращаемых пользователем данных пользователем через класс SQlitehandler в моей учетной записи LoginActivity, а затем используя эти данные позже из mainactivity. Sqlitehandler возвращает случайные значения null, поэтому я не могу понять, правильно ли написано db в LoginActivity или если во время чтения есть проблема с доступом. Я размещаю соответствующие части классов LoginActivity и SqliteHandler. Пожалуйста, помогите.

@Override 
     public void onResponse(String response) { 
      Log.d(TAG, "Login Response: " + response); 
      hideDialog(); 

      try { 
       JSONObject jObj = new JSONObject(response); 
       boolean error = jObj.getBoolean("error"); 

       // Check for error node in json 
       if (!error) { 
        // user successfully logged in 
        // Create login session 


        // Now store the user in SQLite 
        String api_key = jObj.getString("api_key"); 

        //JSONObject user = jObj.getJSONObject("user"); 
        String name = jObj.getString("name"); 
        String email = jObj.getString("email"); 
        int user_id = jObj.getInt("user_id"); 

        JSONObject authorization = jObj.getJSONObject("authorizations"); 
        int pro_app = authorization.getInt("pro_app"); 

        // Inserting row in users table 
        // SQLite database handler 
        db = new SQLiteHandler(LoginActivity.this); 
        db.addUser(name, email, user_id, api_key); 
        db.addAuthorizations(pro_app); 

        // Set the log level to verbose. 

        String user_id_string = String.valueOf("user_id"); 
        String pro_app_string = String.valueOf("pro_app"); 


        session.setLogin(true); 
        Toast.makeText(LoginActivity.this, "You have successfully logged in! Please wait while application loads.", Toast.LENGTH_LONG).show(); 

        // Launch main activity 
        Intent intent = new Intent(LoginActivity.this, 
          SplashActivity.class); 
        startActivity(intent); 
        finish(); 
       } else { 
        // Error in login. Get the error message 

        String errorMsg = jObj.getString("message"); 
        if (errorMsg.equals("") || errorMsg.isEmpty()) { 
         errorMsg = "An unusual error occurred. Please try again"; 
        } 
        Toast.makeText(getApplicationContext(), 
          errorMsg, Toast.LENGTH_LONG).show(); 
       } 
      } catch (Exception e) { 
       // JSON error 
       hideDialog(); 
       e.printStackTrace(); 
       Toast.makeText(getApplicationContext(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show(); 
      } 

     } 

Ниже приводится SQLiteHandler:

public class SQLiteHandler extends SQLiteOpenHelper { 

    private static final String TAG = SQLiteHandler.class.getSimpleName(); 

    // All Static variables 
    // Database Version 
    private static final int DATABASE_VERSION = 1; 

    // Database Name 
    private static final String DATABASE_NAME = "android_api"; 

    // Login table name 
    private static final String TABLE_USER = "user"; 
    private static final String TABLE_AUTH = "authorizations"; 

    // Login Table Columns names 
    private static final String KEY_ID = "id"; 
    private static final String KEY_NAME = "name"; 
    private static final String KEY_USER_ID = "user_id"; 
    private static final String KEY_API = "api_key"; 
    private static final String KEY_PRO = "pro_app"; 


    public SQLiteHandler(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    // Creating Tables 
    @Override 
    public void onCreate(SQLiteDatabase db) { 
     String CREATE_LOGIN_TABLE = "CREATE TABLE " + TABLE_USER + "(" 
       + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT," 
       + KEY_EMAIL + " TEXT UNIQUE," + KEY_USER_ID + " INTEGER UNIQUE," + KEY_API + " TEXT" + ")"; 
     db.execSQL(CREATE_LOGIN_TABLE); 

     String CREATE_AUTH_TABLE = "CREATE TABLE " + TABLE_AUTH + "(" 
       + KEY_ID + " INTEGER PRIMARY KEY," + KEY_PRO + " INTEGER" 
       + ")"; 
     db.execSQL(CREATE_AUTH_TABLE); 

     Log.d(TAG, "Database tables created"); 
    } 

    // Upgrading database 
    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 

     Log.d(TAG, "onUpgrade() from " + oldVersion + " to " + newVersion); 

     // Drop older table if existed 
     db.execSQL("DROP TABLE IF EXISTS " + TABLE_USER); 
     db.execSQL("DROP TABLE IF EXISTS " + TABLE_AUTH); 

     // Create tables again 
     onCreate(db); 
    } 

    /** 
    * Storing user details in database 
    */ 
    public void addUser(String name, String email, int user_id, String c_code, String phone, String api_key, int status, String created_at) { 
     SQLiteDatabase db = this.getWritableDatabase(); 

     ContentValues values = new ContentValues(); 
     values.put(KEY_NAME, name); // Name 
     values.put(KEY_EMAIL, email); // Email 
     values.put(KEY_USER_ID, user_id); // Email 
     values.put(KEY_API, api_key); // API 

     // Inserting Row 
     long id = db.insert(TABLE_USER, null, values); 
     db.close(); // Closing database connection 

     Log.d(TAG, "New user inserted into sqlite: " + id); 
    } 


    public void addAuthorizations(int pro_app, int no_ads, int pro_original) { 
     SQLiteDatabase db = this.getWritableDatabase(); 

     ContentValues values = new ContentValues(); 
     values.put(KEY_PRO, pro_app); // Pro version? 

     // Inserting Row 
     long id = db.insert(TABLE_AUTH, null, values); 
     db.close(); // Closing database connection 

     Log.d(TAG, "New auth inserted into sqlite: " + id); 
    } 

    public void updateAuthorizations(int pro_app, int no_ads, int pro_original) { 
     SQLiteDatabase db = this.getWritableDatabase(); 

     ContentValues values = new ContentValues(); 
     values.put(KEY_PRO, pro_app); // Pro version? 
     values.put(KEY_ADS, no_ads); // No Ads? 
     values.put(KEY_PRO_ORIGINAL, pro_original); //pro origin 

     // Inserting Row 
     db.update(TABLE_AUTH, values, "id=1", null); 
     db.close(); // Closing database connection 

     Log.d(TAG, "New auth updated into sqlite "); 
    } 


    /** 
    * Getting user data from database 
    */ 
    public HashMap<String, Object> getUserDetails() { 
     HashMap<String, Object> user = new HashMap<String, Object>(); 
     String selectQuery = "SELECT * FROM " + TABLE_USER; 

     SQLiteDatabase db = this.getReadableDatabase(); 
     Cursor cursor = db.rawQuery(selectQuery, null); 
     // Move to first row 
     cursor.moveToFirst(); 
     if (cursor.getCount() > 0) { 
      user.put("name", cursor.getString(1)); 
      user.put("email", cursor.getString(2)); 
      user.put("user_id", cursor.getInt(3)); 
      user.put("api_key", cursor.getString(4)); 

     } 
     cursor.close(); 
     db.close(); 
     // return user 
     Log.d(TAG, "Fetching user from Sqlite: " + user.toString()); 

     return user; 
    } 

    public HashMap<String, Integer> getUserAuthorizations() throws Exception{ 
     HashMap<String, Integer> auth = new HashMap<String, Integer>(); 
     String selectQuery = "SELECT * FROM " + TABLE_AUTH; 

     SQLiteDatabase db = this.getReadableDatabase(); 
     Cursor cursor = db.rawQuery(selectQuery, null); 
     // Move to first row 
     cursor.moveToFirst(); 
     if (cursor.getCount() > 0) { 
      auth.put("pro_app", cursor.getInt(1)); 
     } 
     cursor.close(); 
     db.close(); 
     // return user 
     try { 
      int authINT = auth.get("pro_app"); 
     } catch (Exception e){ 
      Crashlytics.log("this is what is throwing the error"); 
      Crashlytics.logException(e); 
     } 
     int authINTNEXT = auth.get("pro_app"); 


     return auth; 
    } 

    /** 
    * Re crate database Delete all tables and create them again 
    */ 
    public void deleteUsers() { 
     SQLiteDatabase db = this.getWritableDatabase(); 
     // Delete All Rows 
     db.delete(TABLE_USER, null, null); 
     db.delete(TABLE_AUTH, null, null); 
     db.close(); 

     Log.d(TAG, "Deleted all user info from sqlite"); 
    } 


} 

Ошибка я получаю в Crashlytics:

Non-fatal Exception: java.lang.NullPointerException 
Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference 
raw 
com.blueinklabs.investifystocks.helper.SQLiteHandler.getUserAuthorizations (SourceFile:198) 
com.blueinklabs.investifystocks.StorageMethod.loadDatabaseData (SourceFile:65) 
com.blueinklabs.investifystocks.MainActivity.onCreate (SourceFile:183) 
android.app.Activity.performCreate (Activity.java:5993) 
android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1111) 
android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2418) 
android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2530) 
android.app.ActivityThread.access$900 (ActivityThread.java:163) 
android.app.ActivityThread$H.handleMessage (ActivityThread.java:1358) 
android.os.Handler.dispatchMessage (Handler.java:102) 
android.os.Looper.loop (Looper.java:135) 
android.app.ActivityThread.main (ActivityThread.java:5536) 
java.lang.reflect.Method.invoke (Method.java) 
java.lang.reflect.Method.invoke (Method.java:372) 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1397) 
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1192) 
+1

В чем проблема? –

+0

getUserDetails() & getUserAuthorizations() случайным образом предоставляют исключения с нулевым указателем. Я даже видел случай, когда полномочия вернули целое число правильно, но вернули null в поле электронной почты. ошеломляющий. Не могу даже воссоздать себя, поскольку это встречается на очень немногих галактических леденежных устройствах (у меня нет доступа к одному). – dejavu89

+0

Где находится лодка? –

ответ

2

На самом деле проблема в том, что Cursor является возвращение данных из позиции 0, так что означает, что вы получен запись 0,1,2 .. способ. Проверьте мю-код

/** 
* Getting user data from database 
*/ 
public HashMap<String, Object> getUserDetails() { 
    HashMap<String, Object> user = new HashMap<String, Object>(); 
    String selectQuery = "SELECT * FROM " + TABLE_USER; 

    SQLiteDatabase db = this.getReadableDatabase(); 
    Cursor cursor = db.rawQuery(selectQuery, null); 
    // Move to first row 
    cursor.moveToFirst(); 
    if (cursor.getCount() > 0) { 
     user.put("name", cursor.getString(0)); 
     user.put("email", cursor.getString(1)); 
     user.put("user_id", cursor.getInt(2)); 
     user.put("api_key", cursor.getString(3)); 

    } 
    cursor.close(); 
    db.close(); 
    // return user 
    Log.d(TAG, "Fetching user from Sqlite: " + user.toString()); 

    return user; 
} 

public HashMap<String, Integer> getUserAuthorizations() throws Exception{ 
    HashMap<String, Integer> auth = new HashMap<String, Integer>(); 
    String selectQuery = "SELECT * FROM " + TABLE_AUTH; 

    SQLiteDatabase db = this.getReadableDatabase(); 
    Cursor cursor = db.rawQuery(selectQuery, null); 
    // Move to first row 
    cursor.moveToFirst(); 
    if (cursor.getCount() > 0) { 
     auth.put("pro_app", cursor.getInt(0)); 
    } 
    cursor.close(); 
    db.close(); 
    // return user 
    try { 
     int authINT = auth.get("pro_app"); 
    } catch (Exception e){ 
     Crashlytics.log("this is what is throwing the error"); 
     Crashlytics.logException(e); 
    } 
    int authINTNEXT = auth.get("pro_app"); 


    return auth; 
} 

Или у меня есть еще один способ, чтобы получить запись на основе окнеИМЯстолбец согласно ниже код

public static String getString(Cursor cursor, String fieldName, String nullValue) { 
    int column = cursor.getColumnIndex(fieldName); 

    if (cursor.isNull(column)) 
     return nullValue; 
    else 
     return cursor.getString(column); 
} 

public static int getInt(Cursor cursor, String fieldName, int nullValue) { 
    int column = cursor.getColumnIndex(fieldName); 

    if (cursor.isNull(column)) 
     return nullValue; 
    else 
     return cursor.getInt(column); 
} 

и реализовать как

public HashMap<String, Object> getUserDetails() { 
    HashMap<String, Object> user = new HashMap<String, Object>(); 
    String selectQuery = "SELECT * FROM " + TABLE_USER; 

    SQLiteDatabase db = this.getReadableDatabase(); 
    Cursor cursor = db.rawQuery(selectQuery, null); 
    // Move to first row 
    cursor.moveToFirst(); 
    if (cursor.getCount() > 0) { 
     user.put("name", getString(cursor , NAME_COLUMN, "")); 
     user.put("email", getString(cursor , EMAIL_COLUMN, "")); 
     user.put("user_id", getInt(cursor ,USER_ID_COLUMN,0)); 
     user.put("api_key",getString(cursor , API_KEY_COLUMN, "")); 

    } 
    cursor.close(); 
    db.close(); 
    // return user 
    Log.d(TAG, "Fetching user from Sqlite: " + user.toString()); 

    return user; 
} 

и сделать для других метод

+0

На самом деле 0 для ключа первичного идентификатора, который я не использую как таковой. Однако я просто понял, что я не инициировал таблицу, чтобы автоинкремент первичный ключ, и я не ставил значение первичного ключа во время добавления пользователя или авторизации. Можете ли вы прокомментировать, если это может быть так. спасибо за руководство. – dejavu89

+1

@ dejavu89 Хорошо, тогда вы должны изменить 'String selectQuery = SELECT COLUMN Имя, которое вы хотите FROM «+ TABLE_AUTH;' никогда не используйте '*' каждый раз, когда он получит всю запись и займет несколько раз –

+1

Спасибо, я буду помнить об этом. Но вы думаете, что не инициировать первичный ключ является существенной проблемой здесь (я не добавлял автоинкремент, и я не добавляю th e первичный ключ при создании строки) – dejavu89