Android: я не могу получить данные из своей базы данных во втором действии, используя SQLiteOpenHelper

В настоящее время я работаю над приложением в Android Studio, и у меня возникла небольшая проблема, надеюсь, вы сможете мне помочь. Это приложение сделано с помощью Model-View-Presenter и в действии входа в систему (основное действие). Я вызываю службу REST для получения данных и сохранения их в базе данных, в классе интерактора у меня есть этот метод для сохранения данных объекта JSON в базе данных

private long insertLoginData() throws JSONException {
    HelperDB dbObj = new HelperDB(_ctx);
    ContentValues values = new ContentValues();
    String firstName = "";
    String lastName = "";

    values.put(userTableFields[1], _objJson.getString(userTableFields[1]));
    if (_objJson.has("fullName")){
        JSONObject objFullName = _objJson.getJSONObject("fullName");
        firstName = (objFullName.has(userTableFields[2]) ? objFullName.getString(userTableFields[2]) : "");
        lastName = (objFullName.has(userTableFields[3]) ? objFullName.getString(userTableFields[3]) : "");
    }
    values.put(userTableFields[2], firstName);
    values.put(userTableFields[3], lastName);
    values.put(userTableFields[4], (_objJson.has(userTableFields[4]) ? _objJson.getString(userTableFields[4]) : ""));
    values.put(userTableFields[5], true);
    values.put(userTableFields[6], _userName);
    values.put(userTableFields[7], _Password);

    long localId = dbObj.insertStatement(0, values);
    dbObj.closeDB();
    return localId;
}

_ctx — это локальная переменная Context в Presenter, она исходит из Main Activity. А массив userTableFields содержит имена полей пользователей моей таблицы и исходит из ресурса strings.

Я знаю, что это ручной способ сделать это, я мог бы использовать POJO для приведения в классы модели данных JSON, но это не проблема. Я использую консоль отладки, чтобы проверить, возвращает ли переменная localId значение, отличное от -1, поэтому запись вставляется в базу данных нормально.

После проверки пользователя и вставки пользовательских записей (информация о пользователе и его уведомления) в базу данных я открываю новое действие (второе действие), а затем вызываю метод в Presenter для получения пользовательских данных и пытаюсь показать их в этом новая деятельность.

public class Home extends AppCompatActivity implements HomeView{
private HomePresenter presenter;
private ListView lvNotifications;
private TextView tvWelcome;
private ProgressBar pbHome;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.home);

    presenter = new HomePresenterImpl(this);
    lvNotifications = (ListView)findViewById(R.id.lvNotifications);
    tvWelcome = (TextView)findViewById(R.id.tvWelcome);
    pbHome = (ProgressBar)findViewById(R.id.pbHome);
    setTitle(getResources().getString(R.string.titleHome));

    presenter.getNotificationsDataPresenter(getApplicationContext());

    lvNotifications.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            //presenter.getSelectedItem(position, _linkResource);
        }
    });
}

    @Override
public void setDataSourceListView(String[] itemArray, String[] linkResource) {
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, itemArray);
    lvNotifications.setAdapter(adapter);
}}

Проблема здесь. В Presenter второго действия я вызываю метод в базе данных для получения уведомлений пользователей, даже если я изменяю предложение непосредственно на «SELECT * FROM users», оно всегда оказывается пустым, я искал много тем об этом, но делаю не получить решения.

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

private void getNotificationsData(String query){
    HelperDB dbObj = new HelperDB(_ctx);

    Cursor cursor = dbObj.getQueryStatement(query, null);

    itemArray = new String[cursor.getCount()];
    linkResource = new String[cursor.getCount()];
    int i = 0;

    if (cursor.getCount() > 0)
    {
        cursor.moveToFirst();
        try{
            while(cursor.moveToNext()){
                itemArray[i] = cursor.getString(0);
                linkResource[i] = cursor.getString(1);
                i++;
            }
        }
        finally {
            cursor.close();
            dbObj.close();
        }
    }
}

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

Ниже приведен SQLiteOpenHelper, который я использую для подключения к базе данных.

public class HelperDB extends SQLiteOpenHelper{
private static final String DBName = "MyDb";
private static String createUserTableStatement = "";
private static String createNotificationsTableStatement = "";

String[] tableNames, userTableFields, notificationsTableFields;

public HelperDB(Context context) {
    super(context, DBName, null, 1);

    tableNames = context.getResources().getStringArray(R.array.tableNames);
    userTableFields = context.getResources().getStringArray(R.array.userTableFields);
    notificationsTableFields = context.getResources().getStringArray(R.array.notificationsTableFields);

    createUserTableStatement = "CREATE TABLE " + tableNames[0] + " (" + userTableFields[0] + " INTEGER PRIMARY KEY AUTOINCREMENT, "
            + userTableFields[1] + " TEXT, " + userTableFields[2] + " TEXT, " + userTableFields[3]
            + " TEXT, " + userTableFields[4] + " TEXT, " + userTableFields[5] + " BOOLEAN, " + userTableFields[6] + " TEXT, "
            + userTableFields[7] + " TEXT)";

    createNotificationsTableStatement = "CREATE TABLE " + tableNames[1] + " (" + notificationsTableFields[0]
            + " INTEGER PRIMARY KEY AUTOINCREMENT, " + notificationsTableFields[1] + " TEXT, "
            + notificationsTableFields[2] + " TEXT, " + notificationsTableFields[3]
            + " TEXT, " + notificationsTableFields[4] + " TEXT, " + notificationsTableFields[5] + " TEXT)";
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL(createUserTableStatement);

    db.execSQL(createNotificationsTableStatement);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    for (int i = 0; i < tableNames.length; i++)
        db.execSQL("DROP TABLE IF EXISTS " + tableNames[i]);

    onCreate(db);
}

public void closeDB() {
    SQLiteDatabase db = this.getWritableDatabase();
    if (db != null && db.isOpen())
        db.close();
}

public long insertStatement(int tableIndex, ContentValues values){
    SQLiteDatabase db = this.getWritableDatabase();
    long userId;
    try{
        db.beginTransaction();
        userId = db.insert(tableNames[tableIndex], null, values);
        db.setTransactionSuccessful();
    }
    finally {
        db.endTransaction();
        db.close();
    }
    return userId;
}

public Cursor getQueryStatement(String queryStatement, String[] fieldsArray){
    SQLiteDatabase db = this.getReadableDatabase();

    Cursor cursor = db.rawQuery(queryStatement, fieldsArray);

    return cursor;
}

}

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

Примечание. Я всегда отправляю getApplicationContext в качестве параметра Presenter, потому что методам в SqliteOpenHelper нужен контекст в конструкторе.


person London A.    schedule 27.03.2017    source источник
comment
Куда звонить getNotificationsData ?   -  person ρяσѕρєя K    schedule 27.03.2017
comment
На уровне презентатора (другой класс) Presenter.getNotificationsDataPresenter(getApplicationContext()); --› ловлю контекст и присваиваю его локальной переменной --› в переменной задаю SELECT * FROM пользователей --› getNotificationsData(String query)   -  person London A.    schedule 27.03.2017


Ответы (1)


Вы должны создать класс POJO и реализовать Parcelable, как показано ниже, просто измените свои параметры.

public class User implements Parcelable {
private Integer id;
private String userName;
private Integer age;


public User() {
}

protected User(Parcel in) {
    userName = in.readString();
    age = in.readInt();
}

public static final Creator<User> CREATOR = new Creator<User>() {
    @Override
    public User createFromParcel(Parcel in) {
        return new User(in);
    }

    @Override
    public User[] newArray(int size) {
        return new User[size];
    }
};

public Integer getId() {

    return id;
}

public Integer getAge() {
    return age;
}

public void setAge(Integer age) {
    this.age = age;
}

public void setId(Integer id) {
    this.id = id;
}

public String getUserName() {
    return userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel parcel, int i) {
    parcel.writeString(userName);
    parcel.writeInt(age);
}

Затем, используя намерение, поместите свою модель в намерение и getIntent в другом действии, где вы хотите, например:

  Intent intent = new Intent(mContext,//your activity name);
            intent.putExtra("yourModekey",userModel);
    startActivities(intent);

в другой деятельности

getIntent().getParcelableExtra("yourModelkey");
person Nikhil Sharma    schedule 27.03.2017
comment
Во втором действии getQueryStatement(String queryStatement, String[] fieldsArray) не работает, как если бы: записи в первом действии на самом деле не были вставлены, в первом действии данные были сохранены в другом контексте, и использование контекста второго действия является не то же самое, способ получения данных во второй активности неверен - person London A.; 27.03.2017