I am making an application in android studio developed in java that allows to show a profile image in imageview and store the url of the location of said image in a database, besides that every time a button is pressed it can be changed the profile image and the path where the new image is located is overwritten. So far I am taking the facebook profile picture and I am storing its url in the table but when I press the button to change the image (which does good way) and try to override the url the value of the field is not modified. The idea is to override the url field of the image from the database by giving as an argument the id of the user associated with said image (which is an integer ). I hope you understand and can help me. Greetings
ConstantUser.class
public class ConstantUser {
//table user
public static final String TABLA_USUARIO="usuario";
public static final String CAMPO_ID="user_id";
public static final String CAMPO_FK_ID="id_profile";
public static final String CAMPO_PASSWORD="password";
public static final String CAMPO_USERNAME="username";
public static final String CAMPO_FIRSTNAME="first_name";
public static final String CAMPO_LASTNAME="last_name";
public static final String CAMPO_EMAIL="email";
public static final String CAMPO_DATE="date";
public static final String CAMPO_DATE_JOINED="date_joined";
//table perfil_user
public static final String TABLE_PROFILE="profile";
public static final String FIELD_ID_PROFILE="id_profile";
public static final String FIELD_ALIAS="alias";
public static final String FIELD_REPUTATION="reputation";
public static final String FIELD_IMAGE="image_perfil";
public static final String CREAR_TABLA_USUARIO="CREATE TABLE "+TABLA_USUARIO+"("+CAMPO_ID+" INTEGER PRIMARY KEY AUTOINCREMENT,"+CAMPO_PASSWORD+" TEXT,"+
CAMPO_USERNAME+" TEXT,"+CAMPO_FIRSTNAME+" TEXT,"+CAMPO_LASTNAME+" TEXT,"+CAMPO_EMAIL+" TEXT,"+CAMPO_DATE+
" TEXT,"+CAMPO_DATE_JOINED+" TEXT,"+CAMPO_FK_ID+" INTEGER,"+" FOREIGN KEY"+"("+CAMPO_FK_ID+")" +
" REFERENCES "+TABLE_PROFILE+"(id_profile)"+")";
public static final String CREATE_TABLE_PROFILE="CREATE TABLE "+TABLE_PROFILE+"("+FIELD_ID_PROFILE+" INTEGER PRIMARY KEY AUTOINCREMENT,"+FIELD_ALIAS+" TEXT,"+FIELD_REPUTATION+
" INTEGER,"+FIELD_IMAGE+" TEXT"+")";
}
sqlitehelper.class
public class ConexionSQliteHelper extends SQLiteOpenHelper {
public ConexionSQliteHelper(#Nullable Context context, #Nullable String name, #Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREAR_TABLA_USUARIO);
db.execSQL(CREATE_TABLE_PROFILE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLA_USUARIO);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_PROFILE);
}
public void insertUser(String user_name, String name, String last_name, String date, String date_joined, String alias, String email, String password,String photo) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(FIELD_ALIAS, alias);
values.put(FIELD_IMAGE,photo);
values.put(FIELD_REPUTATION, 0);
Long idresultante = db.insert(TABLE_PROFILE, null, values);
ContentValues values_2 = new ContentValues();
values_2.put(CAMPO_PASSWORD,password);
values_2.put(CAMPO_USERNAME, user_name);
values_2.put(CAMPO_FIRSTNAME, name);
values_2.put(CAMPO_LASTNAME, last_name);
values_2.put(CAMPO_EMAIL, email);
values_2.put(CAMPO_DATE, date);
values_2.put(CAMPO_DATE_JOINED, date_joined);
values_2.put(CAMPO_FK_ID, idresultante);
Long idresultante_2 = db.insert(TABLA_USUARIO, null, values_2);
db.close();
}
public int requestId(String username){
Integer id = null;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(" SELECT "+CAMPO_ID+" FROM " + TABLA_USUARIO + " WHERE " + CAMPO_USERNAME + " =? ", new String[]{username});
if (cursor != null && cursor.getCount() > 0) {
if (cursor.moveToFirst()) {
id = cursor.getInt(0);
}
}
return id;
}
public void overWriteImage(String url,String id){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(FIELD_IMAGE, stringUri);
Cursor cursor = db.rawQuery(" SELECT "+FIELD_IMAGE+" FROM " + TABLE_PROFILE + " WHERE " + FIELD_ID_PROFILE+ " =? ", new String[]{id});
long row = db.update(TABLE_PROFILE,values,FIELD_IMAGE+ " = ?", new String[]{id});
db.close();
}
}
Main.class
public class loggin extends AppCompatActivity {
Button buttonSelectImage
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.perfil_user,container,false);
buttonSelectImage=view.findViewById(R.id.change_image);
ConexionSQliteHelper conn=new ConexionSQliteHelper(getContext(),"db_testwuad_7",null,15);
AccessToken accessToken = AccessToken.getCurrentAccessToken();
buttonSelectImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent,3);
}
});
//in this part I get the name, email and profile picture from facebook
//and store it in the database structure
//mentioned above and show it in the view
if ( accessToken != null && !accessToken.isExpired()){
GraphRequest request = GraphRequest.newMeRequest(
accessToken,
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
try {
Blob my_blob= null;
facebook_firstname=object.getString("first_name");
facebook_lastname =object.getString("last_name");
facebook_user_name=object.getString("name");
email_facebook = object.getString("email");
String url_perfil_facebook=object.getJSONObject("picture").getJSONObject("data").getString("url");
Picasso.get().load(url_perfil_facebook).into(image_user);
name_user.setText(facebook_user_name);
email.setText(email_facebook);
str_datefb = date_now;
str_datejoinedfb = date_now;
tag_date.setText(str_datefb);
boolean exist_user = conn.verifyIfUserExists(email_facebook);
if (exist_user) {
alias_perfil = conn.getUserName(email_facebook);
alias_facebook = conn.requestAlias(alias_perfil);
alias.setText(alias_facebook);
String last_season = conn.getLastDateofConnection(facebook_user_name);
tag_date.setText(last_season);
conn.overwriteDate(date_now,facebook_user_name);
}
else {
alias_name= generateAliasRandom();
conn.insertUser(facebook_user_name,facebook_firstname,facebook_lastname,str_datefb,str_datejoinedfb,alias_name,email_facebook,null,url_perfil_facebook);
Toast.makeText(getContext(), "nuevo usuario creado", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields","id,first_name,last_name,name,email,link,picture.type(large)");
request.setParameters(parameters);
request.executeAsync();
}
return view
}
//here I get the url of the new image once the changeimage button is
//selected and I pass
//that value to the overwriteimage method along with the user id
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
ConexionSQliteHelper conn=new ConexionSQliteHelper(getContext(),"db_testwuad_7",null,15);
if(resultCode == RESULT_OK && data != null){
Uri selectedImage = data.getData();
image_user.setImageURI(selectedImage);
String stringUri = selectedImage.toString();
Toast.makeText(getContext(), "el valor es"+stringUri, Toast.LENGTH_LONG).show();
int id_user = conn.requestId(name_user.getText().toString());
//convert id integer to string
String id_string=Integer.toString(id_string);
conn.overWriteImage(stringUri,id_string);
}}
Related
I dont know why i have return result = -1 after execute insertGasData. In other similiar structure the result was != -1, but there is = -1.
There is DatabaseHelper class and main class
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "car.db";
public static final String TABLE_NAME2 = "car_gas_table";
public static final String COL_G_1 = "GAS_ID";
public static final String COL_G_2 = "GAS_DATE";
public static final String COL_G_3 = "GAS_MILEAGE";
public static final String COL_G_4 = "FUEL_TYPE";
public static final String COL_G_5 = "FUEL_COST";
public static final String COL_G_6 = "FUEL_VOLUME";
public DatabaseHelper(#Nullable Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("create table " + TABLE_NAME2 + " (GAS_ID INTEGER PRIMARY KEY AUTOINCREMENT, GAS_DATE TEXT, GAS_MILEAGE TEXT, FUEL_TYPE TEXT, FUEL_COST TEXT, FUEL_VOLUME TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME2);
}
public boolean insertGasData(String date, String mileage, String fuel_type, String fuel_price, String fuel_volume) {
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_G_2, date);
contentValues.put(COL_G_3, mileage);
contentValues.put(COL_G_4, fuel_type);
contentValues.put(COL_G_5, fuel_price);
contentValues.put(COL_G_6, fuel_volume);
long result = sqLiteDatabase.insert(TABLE_NAME2, null, contentValues);
if (result == -1)
return false;
else return true;
}
there is a call method
i use there Strings to eliminate other mistakes but it doesnt help
public void AddRefuelrData() {
bDodaj.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// boolean isInsert = myDb.insertGasData(eRefDate.getText().toString(), eRefMileage.getText().toString(), eRefType.getText().toString(), eRefPrice.getText().toString(), eRefVolume.getText().toString());
boolean isInsert = myDb.insertGasData("dd","mm", "tt", "pr", "vo");
if (isInsert == true)
Toast.makeText(MainActivity.this, "Data inserted", Toast.LENGTH_LONG).show();
else
Toast.makeText(MainActivity.this, "Data not inserted", Toast.LENGTH_LONG).show();
}
});
}
after call method insertGasData i have return false
enter image description here
Are you sure the table is actually created properly?
Use Device File Explorer to check if the database is created or not.
that should help with narrowing down the problem.
So my app is a QR Code scanner. Currently it will read a QR code and display it back to user. I want to get it to also save this result to a database and then proceed to read back from it. Currently it does neither of the last two and I'm struggling to figure out which is causing the issue - either saving to the database or reading back from the database.
My Database code is this:
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);
}
}
}
And my main java code is this.
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();
}
}
Your issue could well be with the line initialValues.put("codes", code); as according to your table definition there is no column called codes, rather the column name appears to be code
As such using initialValues.put("code", code); may well resolve the issue.
Addititional
It is strongly recommended that you define and subsequently use constants throughout your code for all named
items (tables, columns, views trigger etc) and thus the value will always be identical.
e.g.
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;
}
You would also likely encounter fewer issues by not using hard coded column offsets when extracting data from Cursor by rather using the Cursor getColumnIndex method to provide the offset.
e.g. instead of :-
results.get(counter)[0] = cursor.getString(0);
it would be better to use :-
results.get(counter)[0] = cursor.getString(cursor.getColumnIndex(COLUMN_CODEID));
I created an SQLite Database in my app, and I insert the data into it. And now I want to retrieve data from it but I want just insert one data and retrieve it then display it into a TextView.
public class Db_sqlit extends SQLiteOpenHelper{
String TABLE_NAME = "BallsTable";
public final static String name = "db_data";
public Db_sqlit(Context context) {
super(context, name, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table "+TABLE_NAME+" (id INTEGER PRIMARY KEY AUTOINCREMENT, ball TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
public boolean insertData(String balls){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("ball",balls);
long result = db.insert(TABLE_NAME,null,contentValues);
if(result == -1){
return false;
}
else
return true;
}
public void list_balls(TextView textView) {
Cursor res = this.getReadableDatabase().rawQuery("select ball from "+TABLE_NAME+"",null);
textView.setText("");
while (res.moveToNext()){
textView.append(res.getString(1));
}
}
}
Here is an example of how I achieved this.
In this example I will store, retrieve, update and delete a students name and age.
First create a class, I called mine
DBManager.java
public class DBManager {
private Context context;
private SQLiteDatabase database;
private SQLiteHelper dbHelper;
public DBManager(Context c) {
this.context = c;
}
public DBManager open() throws SQLException {
this.dbHelper = new SQLiteHelper(this.context);
this.database = this.dbHelper.getWritableDatabase();
return this;
}
public void close() {
this.dbHelper.close();
}
public void insert(String name, String desc) {
ContentValues contentValue = new ContentValues();
contentValue.put(SQLiteHelper.NAME, name);
contentValue.put(SQLiteHelper.AGE, desc);
this.database.insert(SQLiteHelper.TABLE_NAME_STUDENT, null, contentValue);
}
public Cursor fetch() {
Cursor cursor = this.database.query(SQLiteHelper.TABLE_NAME_STUDENT, new String[]{SQLiteHelper._ID, SQLiteHelper.NAME, SQLiteHelper.AGE}, null, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
}
return cursor;
}
public int update(long _id, String name, String desc) {
ContentValues contentValues = new ContentValues();
contentValues.put(SQLiteHelper.NAME, name);
contentValues.put(SQLiteHelper.AGE, desc);
return this.database.update(SQLiteHelper.TABLE_NAME_STUDENT, contentValues, "_id = " + _id, null);
}
public void delete(long _id) {
this.database.delete(SQLiteHelper.TABLE_NAME_STUDENT, "_id=" + _id, null);
}
}
Then create a SQLiteOpenHelper I called mine
SQLiteHelper.java
public class SQLiteHelper extends SQLiteOpenHelper {
public static final String AGE = "age";
private static final String CREATE_TABLE_STUDENT = " create table STUDENTS ( _id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL , age TEXT );";
private static final String DB_NAME = "STUDENTS.DB";
private static final int DB_VERSION = 1;
public static final String NAME = "name";
public static final String TABLE_NAME_STUDENT = "STUDENTS";
public static final String _ID = "_id";
public SQLiteHelper(Context context) {
super(context, DB_NAME, null, 1);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_STUDENT);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS STUDENTS");
onCreate(db);
}
}
TO ADD:
In this example I take the text from EditText and when the button is clicked I check if the EditText is empty or not. If it is not empty and the student doesn't already exist I insert the students name and age into the database. I display a Toast, letting the user know of the status:
btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (edtName.getText().toString().trim().length() == 0) {
Toast.makeText(getApplicationContext(), "Please provide your students name", Toast.LENGTH_SHORT).show();
} else{
try {
if (edtAge.getText().toString().trim().length() != 0) {
String name = edtName.getText().toString().trim();
String age = edtAge.getText().toString().trim();
String query = "Select * From STUDENTS where name = '"+name+"'";
if(dbManager.fetch().getCount()>0){
Toast.makeText(getApplicationContext(), "Already Exist!", Toast.LENGTH_SHORT).show();
}else{
dbManager.insert(name, age);
Toast.makeText(getApplicationContext(), "Added successfully!", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getApplicationContext(), "please provide student age!", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
TO UPDATE:
Here I take the Text in EditText and update the student when the button is clicked. You can also place the following in a try/catch to make sure it is updated successfully.
btnupdate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String name = nameText.getText().toString();
String age = ageText.getText().toString();
dbManager.update(_id, name, age);
Toast.makeText(getApplicationContext(), "Updated successfully!", Toast.LENGTH_SHORT).show();
}
});
TO DELETE:
dbManager.delete(_id);
Toast.makeText(getApplicationContext(), "Deleted successfully!", Toast.LENGTH_SHORT).show();
TO GET:
Here I get the name of the student and display it in a TextView
DBManager dbManager = new DBManager(getActivity());
dbManager.open();
Cursor cursor = dbManager.fetch();
cursor.moveToFirst();
final TextView studentName = (TextView) getActivity().findViewById(R.id.nameOfStudent);
studentName.settext(cursor.getString(0));
Then I have implement the code in main java class where I want to show using cursor.moveToNext()
searchButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Cursor result = databaseSQLite2.searchData(searchET.getText().toString());
while (result.moveToNext()){
searchresultTV.setText(result.getString(2));
}
}
});
For fetching data from sqlite I have done this method in DatabaseHelper class
public Cursor searchData(String id){
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
//String qry = "SELECT * FROM "+TABLE_NAME+" WHERE ID="+id;
Cursor cursor = sqLiteDatabase.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE ID="+id,null);
return cursor;
}
The app: I have an app that creates multiple machines with:
id, name and location
each of these machines I have to let the user input the income respectively.
The problem: I need to SUM all income(money, date, note, machines_id) inputted from each machine AND display it in a TextView in a different Activity.
My question: How do I get the data from the rawQuery of my getIncomeOfMachine method to another Activity?
What I tried: Using Bundles, Intents, SharedPreferences from the DBHelper class.
DBHelper
public class DBHelpter extends SQLiteOpenHelper {
private static final String DB_NAME = "machines.db";
private static final int DB_VERSION = 1;
public static final String TABLE_MACHINES = "machines";
public static final String MACHINES_COLUMN_NAME = "name";
public static final String MACHINES_COLUMN_LOCATION = "location";
public static final String MACHINES_ID = "id";
public static final String TABLE_INCOME = "income";
public static final String INCOME_COLUMN_MONEY = "money";
public static final String INCOME_COLUMN_DATE = "date";
public static final String INCOME_COLUMN_NOTE = "note";
public static final String INCOME_ID = "id";
public static final String INCOME_COLUMN_MACHINES_ID = "machines_id";
private Context mContext;
public DBHelpter(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String query1 = String.format("CREATE TABLE " + TABLE_MACHINES + "("
+ MACHINES_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ MACHINES_COLUMN_NAME + " TEXT NOT NULL, "
+ MACHINES_COLUMN_LOCATION + " TEXT NOT NULL)",
TABLE_MACHINES, MACHINES_COLUMN_NAME, MACHINES_COLUMN_LOCATION, MACHINES_ID);
String query2 = String.format("CREATE TABLE " + TABLE_INCOME + "("
+ INCOME_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ INCOME_COLUMN_MONEY + " REAL NOT NULL, "
+ INCOME_COLUMN_DATE + " DATE NOT NULL, "
+ INCOME_COLUMN_NOTE + " TEXT NOT NULL, "
+ INCOME_COLUMN_MACHINES_ID + " INTEGER NOT NULL)",
TABLE_INCOME, INCOME_ID, INCOME_COLUMN_MONEY, INCOME_COLUMN_DATE, INCOME_COLUMN_NOTE, INCOME_COLUMN_MACHINES_ID);
db.execSQL(query1);
db.execSQL(query2);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String query1 = String.format("DROP TABLE IF EXISTS " + TABLE_MACHINES);
String query2 = String.format("DROP TABLE IF EXISTS " + TABLE_INCOME);
db.execSQL(query1);
db.execSQL(query2);
onCreate(db);
}
public void insertNewMachine(String name, String location){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(MACHINES_COLUMN_NAME, name);
values.put(MACHINES_COLUMN_LOCATION, location);
db.insertWithOnConflict(TABLE_MACHINES, null, values, SQLiteDatabase.CONFLICT_REPLACE);
db.close();
}
public void insertNewIncome(Double money, String date, String note, long machines_id){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(INCOME_COLUMN_MONEY, money);
values.put(INCOME_COLUMN_DATE, date);
values.put(INCOME_COLUMN_NOTE, note);
values.put(INCOME_COLUMN_MACHINES_ID, machines_id);
db.insertWithOnConflict(TABLE_INCOME, null, values, SQLiteDatabase.CONFLICT_REPLACE);
db.close();
}
public void getIncomeOfMachine(long machinesId){
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT machines_id, SUM(money) AS total FROM income WHERE machines_id = "+machinesId+"", null);
while (cursor.moveToFirst()){
String totalAmount = String.valueOf(cursor.getInt(0));
SharedPreferences mSharedPreferences = mContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor mEditor = mSharedPreferences.edit();
mEditor.putString("total_amount", totalAmount);
mEditor.commit();
}
cursor.close();
db.close();
}
public ArrayList<MachinesClass> getAllMachines(){
ArrayList<MachinesClass> machinesList = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM "+ TABLE_MACHINES, null);
while (cursor.moveToNext()){
final long id = cursor.getLong(cursor.getColumnIndex(MACHINES_ID));
final String name = cursor.getString(cursor.getColumnIndex(MACHINES_COLUMN_NAME));
final String location = cursor.getString(cursor.getColumnIndex(MACHINES_COLUMN_LOCATION));
machinesList.add(new MachinesClass(id, name, location));
}
cursor.close();
db.close();
return machinesList;
}
RecyclerViewAdapter
public class MachinesAdapter extends RecyclerView.Adapter<MachinesAdapter.ViewHolder> {
private ArrayList<MachinesClass> machinesList;
private LayoutInflater mInflater;
private DBHelpter mDBHelpter;
private Context mContext;
public static final String PREFS_NAME = "MyPrefsFile";
public MachinesAdapter(Context mContext, ArrayList<MachinesClass> machinesList){
this.mContext = mContext;
this.machinesList = machinesList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.machines_list, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.mLocation.setText(machinesList.get(position).getLocation());
holder.v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences mSharedPreferences = mContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor mEditor = mSharedPreferences.edit();
mEditor.putString("location", machinesList.get(position).getLocation());
mEditor.putLong("machines_id", machinesList.get(position).getId());
mEditor.commit();
Bundle bundle = new Bundle();
bundle.putString("location", machinesList.get(position).getLocation());
Intent intent = new Intent(v.getContext(), MachineInfo.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtras(bundle);
mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return machinesList != null ? machinesList.size() : 0;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView mLocation, mMoney;
public LinearLayout mLinearLayout;
public View v;
public ViewHolder(View v) {
super(v);
mLinearLayout = (LinearLayout) v.findViewById(R.id.linearLayout);
mLocation = (TextView) v.findViewById(R.id.tvLocation);
mMoney = (TextView) v.findViewById(R.id.tvMoney);
this.v = v;
}
}
}
MachineInfo
public class MachineInfo extends AppCompatActivity {
private TextView mLocation, mMoney, mNotes;
private DBHelpter mDBHelpter;
private FloatingActionButton mFAB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_machine_info);
mDBHelpter = new DBHelpter(getApplicationContext());
mLocation = (TextView) findViewById(R.id.tvLocation);
mMoney = (TextView) findViewById(R.id.tvMoney);
mNotes = (TextView) findViewById(R.id.tvNotes);
mFAB = (FloatingActionButton) findViewById(R.id.fabAddIncome);
SharedPreferences mSharedPreferences = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
String total_amount = mSharedPreferences.getString("total_amount", null);
mMoney.setText(total_amount);
String location = mSharedPreferences.getString("location", null);
mLocation.setText(location);
mFAB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(), IncomeCreation.class);
startActivity(i);
}
});
}
}
If you need any other Activity or layout, let me know!
First, I suggest a change to getIncomeOfMachine(). Since this method is in DBHelper, it should only be responsible for interacting with the database. It should not know anything about SharedPreferences or Activity. Instead, it should return the value retrieved from the database and let the caller decide what to do with that value. Since you know there is only one row in the resulting Cursor, you do not need a loop. Just move to the first row, get the total, and return it.
Second, since you are only passing a single value to an activity, and you presumably do not need to store it permanently for later use, you should use an Intent rather than SharedPreferences. Starting Another Activity has a clear example of sending a value to another activity. If you have problems using this example in your app, feel free to post a new question showing what you did and explaining the problem you encountered.
Im having trouble getting individual items to delete in a database my application is using. I know the method gets called, but nothing in my list is ever removed. Im not getting any errors which is making it tough to track down. Assistance would be awesome.
public class MainActivity extends Activity{
//Global Variables
ListView lv;
Intent addM, viewM;
public DBAdapter movieDatabase;
String tempTitle, tempYear;
int request_Code = 1;
int request_code2 = 2;
SimpleCursorAdapter dataAdapter;
Cursor cursor;
Button addButton;
long testID;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//creates the database
movieDatabase = new DBAdapter(this);
movieDatabase.open();
//movieDatabase.deleteAllMovies();
//creates the intents to start the sub activities
addM = new Intent(this, AddMovie.class);
viewM = new Intent(this, MovieView.class);
}
//handles the return of the activity addMovie
public void onActivityResult(int requestCode, int resultCode,
Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK)
{
switch(requestCode)
{
case 1:
dbAddMovie(data.getStringExtra("title"),
data.getStringExtra("year"));
break;
case 2:
testID = data.getLongExtra("rowid", -1);
dMovie(testID);
break;
}
}
}
//adds item to the movie list
public void dbAddMovie(String mT, String mY)
{
movieDatabase.open();
movieDatabase.insertMovie(mT, mY);
Toast.makeText(this, "Movie: " + mT + " added to database",
Toast.LENGTH_SHORT).show();
}
//deletes an entry into the database
public void dMovie(long rowid)
{
//Toast.makeText(this, "Deleting: " + rowid,
Toast.LENGTH_SHORT).show();
movieDatabase.deleteMovie(rowid);
movieDatabase.getAllMovies();
}
//displays the database as a list
public void displayListView()
{
addButton = (Button) findViewById(R.id.add);
addButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivityForResult(addM, 1);
}
});
cursor = movieDatabase.getAllMovies();
//columns to use
String[] columns = new String[]
{
movieDatabase.KEY_TITLE,
};
//xml data to bind the data to
int[] to = new int[]
{
R.id.column2,
};
//adapter to display the database as a list
dataAdapter = new SimpleCursorAdapter(this,
R.layout.complexrow, cursor, columns, to, 0);
//gets the List view resource
lv = (ListView) findViewById(R.id.movielist);
//sets the list view to use the adapter
lv.setAdapter(dataAdapter);
//handles the list click events
lv.setOnItemClickListener(new
AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View
v, int position,
long id) {
Cursor cursor = (Cursor)
parent.getItemAtPosition(position);
Bundle mDet = new Bundle();
mDet.putString("title",
cursor.getString(cursor.getColumnIndex(movieDatabase.KEY_TITLE)));
mDet.putString("year",
cursor.getString(cursor.getColumnIndex(movieDatabase.KEY_YEAR)));
mDet.putInt("rId", position);
viewM.putExtras(mDet);
startActivityForResult(viewM, 2);
}
});
//dataAdapter.notifyDataSetChanged();
}
public void onResume()
{
super.onResume();
displayListView();
}
}
and my coresponding dbadapter class
public class DBAdapter {
public static final String KEY_ROWID = "_id";
public static final String KEY_TITLE = "title";
public static final String KEY_YEAR = "year";
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "MovieListDB";
private static final String DATABASE_TABLE = "MoviesTable";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE = "create table MoviesTable (_id
integer primary key autoincrement, " +
"title text not null, year not null);";
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
try{
db.execSQL(DATABASE_CREATE);
} catch (SQLException e)
{
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion +
"which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS MoviesTable");
onCreate(db);
}
}
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
public void close()
{
DBHelper.close();
}
public long insertMovie(String title, String year)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_TITLE, title);
initialValues.put(KEY_YEAR, year);
return db.insert(DATABASE_TABLE, null, initialValues);
}
public boolean deleteMovie(long rowID)
{
return db.delete(DATABASE_TABLE, KEY_ROWID + "='" + rowID+"'", null ) >-1;
}
public Cursor getAllMovies()
{
return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_TITLE,
KEY_YEAR}, null, null, null, null, null);
}
public Cursor getMovie(long rowID) throws SQLException
{
Cursor mCursor =
db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
KEY_TITLE, KEY_YEAR}, KEY_ROWID + "=" + rowID, null, null, null, null, null);
if(mCursor != null)
{
mCursor.moveToFirst();
}
return mCursor;
}
public boolean updateContact(long rowID, String title, String year)
{
ContentValues args = new ContentValues();
args.put(KEY_TITLE, title);
args.put(KEY_YEAR, year);
return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowID, null) > 0;
}
public void deleteAllMovies() {
int doneDelete = 0;
doneDelete = db.delete(DATABASE_TABLE, null, null);
}
}
You're using the position returned from your listview as the row id in your database. This won't necessarily match up with your autoincremented "_id" in your database. position is just what position in the list it is.
You might want to think about using movieDatabase.KEY_ROWID as the key for your intents. Right now I see a mix of "rowid", "rId", "_id", and KEY_ROWID. It would simplify thing to just use the same key everywhere when referring to the same thing.
It looks like you continuously add bundles to the viewM intent. Is that true? If that's not your intent, you should either create a new intent for each click, or remove the previous bundles first.
I'm assuming KEY_ROWID is actually the name of the column? Try the following:
public boolean deleteMovie(long rowID)
{
return db.delete(DATABASE_TABLE, KEY_ROWID + "=?", new String[] { String.valueOf(rowID) }) >-1;
}