java - Android Studio:应用程序未保存到数据库/从数据库读取
问题描述
所以我的应用程序是一个二维码扫描仪。目前它将读取一个二维码并将其显示给用户。我想让它也将此结果保存到数据库中,然后继续从中读取。目前它没有最后两个,我正在努力找出导致问题的原因 - 保存到数据库或从数据库中读取。
我的数据库代码是这样的:
public class Database {
private static final String DATABASE_NAME = "QRCodeScanner";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "codes";
private OpenHelper mDbHelper;
private SQLiteDatabase mDb;
private final Context dbContext;
private static final String DATABASE_CREATE =
"CREATE TABLE " + TABLE_NAME + " (" +
"codeid INTEGER PRIMARY KEY AUTOINCREMENT, " +
"code TEXT NOT NULL);";
public Database(Context ctx) {
this.dbContext = ctx;
}
public Database open() throws SQLException {
mDbHelper = new OpenHelper(dbContext);
mDb = mDbHelper.getWritableDatabase();
return this;
}
public void close() {
mDbHelper.close();
}
public boolean createUser(String code) {
ContentValues initialValues = new ContentValues();
initialValues.put("codes", code);
return mDb.insert(TABLE_NAME, null, initialValues) > 0;
}
public ArrayList<String[]> fetchUser(String code) throws SQLException {
ArrayList<String[]> myArray = new ArrayList<String[]>();
int pointer = 0;
Cursor mCursor = mDb.query(TABLE_NAME, new String[] {"codeid", "code",
}, "code LIKE '%" + code + "%'", null,
null, null, null);
int codeNameColumn = mCursor.getColumnIndex("code");
if (mCursor != null){
if (mCursor.moveToFirst()){
do {
myArray.add(new String[3]);
myArray.get(pointer)[0] = mCursor.getString(codeNameColumn);
pointer++;
} while (mCursor.moveToNext());
} else {
myArray.add(new String[3]);
myArray.get(pointer)[0] = "NO RESULTS";
myArray.get(pointer)[1] = "";
}
}
return myArray;
}
public ArrayList<String[]> selectAll() {
ArrayList<String[]> results = new ArrayList<String[]>();
int counter = 0;
Cursor cursor = this.mDb.query(TABLE_NAME, new String[] { "codeid", "codes" }, null, null, null, null, "codeid");
if (cursor.moveToFirst()) {
do {
results.add(new String[3]);
results.get(counter)[0] = cursor.getString(0);
counter++;
} while (cursor.moveToNext());
}
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
return results;
}
private static class OpenHelper extends SQLiteOpenHelper {
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
}
我的主要java代码是这个。
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button Scan;
private ArrayList<String[]> viewall;
private TextView QR_output;
private IntentIntegrator ScanCode;
private ListView lv;
private ArrayList Search = new ArrayList();
ArrayList<String[]> searchResult;
Database dbh;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// this caused an error on earlier APKs which made the app switch from 17 to 27
setContentView(R.layout.activity_main);
// Defines the Scan button
Scan = findViewById(R.id.Scan);
// defines the output for text
QR_output = findViewById(R.id.QR_Output);
// looks for the user clicking "Scan"
Scan.setOnClickListener(this);
ScanCode = new IntentIntegrator(this);
// Means the scan button will actually do something
Scan.setOnClickListener(this);
lv = findViewById(R.id.list);
dbh = new Database(this);
dbh.open();
}
public void displayAll(View v){
Search.clear();
viewall = dbh.selectAll();
String surname = "", forename = "";
for (int count = 0 ; count < viewall.size() ; count++) {
code = viewall.get(count)[1];
Search.add(surname + ", " + forename);
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
Search);
lv.setAdapter(arrayAdapter);
}
// will scan the qr code and reveal its secrets
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if (result != null) {
// if an empty QR code gets scanned it returns a message to the user
if (result.getContents() == null) {
Toast.makeText(this, "This QR code is empty.", Toast.LENGTH_LONG).show();
} else try {
// converts the data so it can be displayed
JSONObject obj = new JSONObject(result.getContents());
// this line is busted and does nothing
QR_output.setText(obj.getString("result"));
} catch (JSONException e) {
e.printStackTrace();
String codes = result.getContents();
boolean success = false;
success = dbh.createUser(codes);
// outputs the data to a toast
Toast.makeText(this, result.getContents(), Toast.LENGTH_LONG).show();
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
public void onClick(View view) {
// causes the magic to happen (It initiates the scan)
ScanCode.initiateScan();
}
}
解决方案
您的问题很可能与该行有关initialValues.put("codes", code);
,因为根据您的表定义,没有称为代码的列,而是列名似乎是代码
因此,使用initialValues.put("code", code);
可以很好地解决问题。
附加的
强烈建议您在整个代码中为所有命名项(表、列、视图触发器等)定义并随后使用常量,因此值将始终相同。
例如
private static final String DATABASE_NAME = "QRCodeScanner";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "codes";
public static final String COLUMN_CODEID = "codeid"; //<<<<<<<<< example note making public allows the variable to be used elsewhere
public static final String COLUMN_CODE = "code"; //<<<<<<<<<< another example
private OpenHelper mDbHelper;
private SQLiteDatabase mDb;
private final Context dbContext;
private static final String DATABASE_CREATE =
"CREATE TABLE " + TABLE_NAME + " (" +
COLUMN_CODEID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + //<<<<<<<<<<
COLUMN_CODE + " TEXT NOT NULL);"; //<<<<<<<<<<
........ other code omitted for brevity
public boolean createUser(String code) {
ContentValues initialValues = new ContentValues();
initialValues.put(COLUMN_CODE, code); //<<<<<<<<<< CONSTANT USED
return mDb.insert(TABLE_NAME, null, initialValues) > 0;
}
在从 Cursor 提取数据时不使用硬编码的列偏移量,而是使用 Cursor getColumnIndex方法提供偏移量,您也可能会遇到更少的问题。
例如,而不是:-
results.get(counter)[0] = cursor.getString(0);
最好使用:-
results.get(counter)[0] = cursor.getString(cursor.getColumnIndex(COLUMN_CODEID));
推荐阅读
- java - 请求映射和静态字段
- android - 在 fcm 中在线后显示所有通知
- python - python multiprocessing:为每个工作人员提供一个特定的参数
- php - Visual Composer:如何在摘录字段中允许 html 标签
- django - django - apscheduler 如何在 uwsgi 重新启动时保持工作
- shell - 如果文件编码为 utf-16le,则获取垃圾字符
- c++ - 使用“shared_ptr”行为从基类转换为派生类
- next.js - Next.js api 路由解析为 404 但通过邮递员可以正常工作
- docker - Selenoid Docker ssl 证书
- python - 这个 for 循环如何在 Spacy 的自定义 NER 训练代码中工作?