So, I have android application using Sqlite Database. I has a cardview to showing the data. In the table, I have field like, name(text), cost(int) and an image(BLOB). I want to update the data. So, when I change and update the name or the cost, the image not updated and return blank or null. But when I change and update the image, it successfully updated.
First, this is my select query to showing the name, cost and image in update class
public ModelProduk getnama(int selection){
SQLiteDatabase db = this.getReadableDatabase();
String whereclause = KEY_ID_PRODUK + "=?";
String[] whereargs = new String[]{String.valueOf(selection)};
Cursor cursor = db.query(
TABLE_PRODUK,
null,
whereclause,
whereargs,
null,
null,
null
);
ModelProduk modelProduk = new ModelProduk();
if (cursor.moveToFirst()) {
modelProduk.set_id(Integer.parseInt(cursor.getString(0)));
modelProduk.set_nama(cursor.getString(1));
modelProduk.set_harga(Integer.parseInt(cursor.getString(2)));
modelProduk.set_gambar(cursor.getBlob(3));
}
cursor.close();
db.close();
return modelProduk;
}
Here's my database to update
public void update(ModelProduk modelProduk) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAMA_PRODUK, modelProduk.get_nama());
values.put(KEY_HARGA_PRODUK, modelProduk.get_harga());
values.put(KEY_GAMBAR_PRODUK, modelProduk.get_gambar());
String where = "id=?";
String[] whereArgs = new String[] {String.valueOf(modelProduk.get_id())};
// update baris
db.update(TABLE_PRODUK, values, where, whereArgs);
db.close();
}
my java class for update
private void init(){
pilih = getIntent().getIntExtra("id_produk", 0);
db = new Database(this);
modelProduk = db.getnama(pilih);
gambar_produku = (ImageView) findViewById(R.id.pilihgambaru);
tambahgambaru = (Button) findViewById(R.id.btaddu);
simpandatau = (Button) findViewById(R.id.btsimpanu);
deskripsiu = (EditText) findViewById(R.id.etdesku);
harga_produku = (EditText) findViewById(R.id.ethargau);
kembaliu = (Button) findViewById(R.id.btkembaliu);
deskripsiu.setText(modelProduk.get_nama());
harga_produku.setText(String.valueOf(modelProduk.get_harga()));
if (modelProduk.get_gambar() != null) {
gambar_produku.setImageBitmap(bitmap(modelProduk.get_gambar()));
}
}
public void showFileChooser() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Pilih Gambar"), 1);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == RESULT_OK && data != null && data.getData() != null) {
filePath = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
gambar_produku.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public byte[] getImageByte(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
byte imageInByte[]=null;
if(bitmap!=null) {
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream);
imageInByte=stream.toByteArray();
}
return imageInByte;
}
public Bitmap bitmap (byte[] byteImage){
byte[] outImage = byteImage;
Bitmap image ;
if (outImage != null){
ByteArrayInputStream imageStream = new ByteArrayInputStream(outImage);
image = BitmapFactory.decodeStream(imageStream);
}else {
image= null;
}
return image;
}
my onclick to save the update
simpandatau.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
modelProduk.set_nama(deskripsiu.getText().toString());
modelProduk.set_harga(Integer.parseInt(harga_produku.getText().toString()));
modelProduk.set_gambar(getImageByte(bitmap));
db.update(modelProduk);
Toast.makeText(getApplicationContext(), "Data Berhasil Diubah!", Toast.LENGTH_SHORT).show();
}
});
Please Help! I have read many solutions but it's not same to my problems.
Thank you!
You could try the following. This will attempt to get the row that is to be updated before updating. However, rather than return blank or null or update successful it returns an integer which can be -1, 0 or 1 which indicates three possible outcomes.
If the row doesn't exist then it will return -1 (NOTUPDATED).
Otherwise it will then compare the stored image against the image passed.
If the images are different then it will add the new image to values and set the value to be returned to 1 (IMAGEUPDATED).
Otherwise the new image is not added to the values and the value to be returned will remain as 0 (IMAGENOTUPDATED). By not adding the image to values the gambar column will not be included in the SET clause of the SQL generated by the update method.
:-
public int update(ModelProduk modelProduk) {
final int NOTUPDATED = -1;
final int IMAGENOTUPDATED = 0;
final int IMAGEUPDATED = 1;
String where = "id=?";
String[] whereArgs = new String[] {String.valueOf(modelProduk.get_id())};
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
// get the current row from the database (return -1 if it doesn't exist)
Cursor before_update = db.query(TABLE_PRODUK,null,where,whereArgs,null,null,null);
if (!before_update.moveToFirst) {
before_update.close();
return NOTUPDATED;
}
// Default value to return
rv = IMAGENOTUPDATED;
// Compare the store image against the new image, if not the same
// then include the image in the update
if (!Arrays.equals(before_update.getBlob(3),modelProduk.get_gambar)) {
values.put(KEY_GAMBAR_PRODUK, modelProduk.get_gambar());
rv = IMAGEUPDATED;
}
before_update.close();
values.put(KEY_NAMA_PRODUK, modelProduk.get_nama());
values.put(KEY_HARGA_PRODUK, modelProduk.get_harga());
// Update baris checking to see if an update occurred, if not
// then set return value to -1 (could be a different status code)
if (db.update(TABLE_PRODUK, values, where, whereArgs) = 0) {
rv = NOTUPDATED;
}
db.close();
before_update.close();
return rv;
}
Note the above is in-principle code, it has not been tested and therefore may contain errors.
You may wish to define NOTUPDATED, IMAGENOTUPDATED and IMAGEUPDATED elsewhere with greater scope.
Related
I'm working on a feature where the user can take a picture and choose from the gallery. This is basically where it starts and goes on to save the images in db.
private void showPictureDialog(){
AlertDialog.Builder pictureDialog = new AlertDialog.Builder(this);
pictureDialog.setTitle("Select Action");
String[] pictureDialogItems = {
"Select photo from gallery",
"Capture photo from camera" };
pictureDialog.setItems(pictureDialogItems,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
choosePhotoFromGallary();
break;
case 1:
takePhotoFromCamera();
break;
}
}
});
pictureDialog.show();
}
However, I want to make the user experience better. I want to skip the dialog where the user selects one of the options (from gallery or camera) and instead show the gallery in camera intent. Something similar to this:
I hope you get my point. Thanks :)
Get all image
public List<File> getAllShownImagesPath(Context context) {
//get all images
String[] columns = {MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_ADDED, MediaStore.Images.Media.SIZE};
List<File> result = new ArrayList<>();
File f = null;
final Cursor cursor = context.getContentResolver().
query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, // Specify the provider
columns, // The columns we're interested in
null, // A WHERE-filter query
null, // The arguments for the filter-query
MediaStore.Images.Media.DATE_ADDED + " DESC"
);
if (cursor != null) {
cursor.moveToFirst();
for (int r = 0; r < cursor.getCount(); r++, cursor.moveToNext()) {
int i = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE));
//int l = cursor.getString(1).length();
final int image_path_col = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
if (i > 0) {
f = new File(cursor.getString(image_path_col));
if (f.length() > 0) {
result.add(f);
}
}
}
cursor.close();
}
return result;
}
Add all image into recyclerview or listview
I am really stuck as I have a cursor that retrieves values from the database but the cursor only returns the last value. I need the cursor to retrieve all values so I can display them all later on. Is there any way as I can return all the data stored through the cursor?
An Example as to whats happening. Eg Click on Button 1 and stores 1 perfectly but once I click on Button 2 and add 1. Button 1 data is not return or retrieved.
Any help would be greatly appreciated.
Execute
The first Cursor is goes through to check all the stored items.
public void exectute() {
AsyncTask.execute(new Runnable() {
#Override
public void run() {
Cursor c = TrackerDb.getStoredItems(getApplicationContext());
if (c != null) {
if (c.moveToFirst()) {
WorkoutDetails details = null;
//if (details != null) mWorkoutDetailsList.add(details);
do {
//if (details != null) mWorkoutDetailsList.add(details);
WorkoutDetails temp = getWorkoutFromCursor(c);
//if (details != null) mWorkoutDetailsList.add(details);
if (details == null) {
details = temp;
continue;
}
//if (details != null) mWorkoutDetailsList.add(details);
if (isSameDay(details.getWorkoutDate(), temp.getWorkoutDate())) {
//if (details != null) mWorkoutDetailsList.add(details);
if (DBG) Log.d(LOG_TAG, "isSameDay().. true");
//details.add(temp);
} else {
mWorkoutDetailsList.add(details);
details = temp;
}
// if (details != null) mWorkoutDetailsList.add(details);
} while (c.moveToNext());
if (details != null) mWorkoutDetailsList.add(details);
if (DBG)
Log.d(LOG_TAG, "AsyncTask: list size " + mWorkoutDetailsList.size());
runOnUiThread(new Runnable() {
#Override
public void run() {
mWorkoutsAdapter.updateList(mWorkoutDetailsList);
}
});
}
c.close();
}
}
});
}
Get Stored Items Code
This is the code which the excute class calls and where the cursor only returns one value.
public static Cursor getStoredItems(Context context) {
DBHelper dbHelper = new DBHelper(context);
SQLiteDatabase db = dbHelper.getWritableDatabase();
String[] projection = {ID, TIME, TYPE, DURATION, DATE, POINT};
String orderBy = TIME + " DESC";
Cursor cursor = db.query(TABLE_NAME, projection, null, null, null, null, orderBy);
return cursor;
}
Array
This is the array code where i want the cursor to store its values based on type.
private WorkoutDetails getWorkoutFromCursor(Cursor c) {
long time = c.getLong(c.getColumnIndex(TrackerDb.TIME));
int type = c.getInt(c.getColumnIndex(TrackerDb.TYPE));
int duration = c.getInt(c.getColumnIndex(TrackerDb.DURATION));
int point = c.getInt(c.getColumnIndex(TrackerDb.POINT));
int totalMoney = MoneyActivity.Money.values().length;
int[] points = new int[totalMoney];
int totalActivities = MeditationTrackerActivity.ACTIVITIES.values().length;
int[] durations = new int[totalActivities];
if (type < totalActivities) {
durations[type] = duration;
}
if( type == 0) {
for (int i = 0; i < totalMoney; i++) {
points[type] = point;
}
}
else if ( type == 1) {
for ( int ii = 0; ii < totalMoney; ii++) {
points[type] = point;
}
}
else if ( type == 2) {
for ( int iii = 0; iii < totalMoney; iii++) {
points[type] = point;
}
}
return new WorkoutDetails(time, durations, points);
}
Get Workout From Cursor Code
private static WorkoutDetails getWorkoutFromCursor(Cursor c) {
long time = c.getLong(c.getColumnIndex(TrackerDb.TIME));
int type = c.getInt(c.getColumnIndex(TrackerDb.TYPE));
int duration = c.getInt(c.getColumnIndex(TrackerDb.DURATION));
String date = c.getString(c.getColumnIndex(TrackerDb.DATE));
int point = c.getInt(c.getColumnIndex(TrackerDb.POINT));
int[] durations = new int[MeditationTrackerActivity.ACTIVITIES.values().length];
durations[type] = duration;
int[] points = new int[MoneyActivity.Money.values().length];
points[type] = point;
return new WorkoutDetails(time, durations, date, points);
}
I am aware that media artwork is stored under albums and to get them you need to have the album id to access it. I have been able to get the images for tracks and albums using the album id.
However for artists table doesn't have the album id field. Other apps such as Play Music and Poweramp are somehow able to get the track artwork and add them to the respective artists.
How do i achieve this?
The way I do it is to get all albums for an artist and then use the rnd function to return an albumid:
String artist_id = c.getString(c.getColumnIndex(MediaStore.Audio.Artists._ID));
Cursor crs = album.getArtistsAlbumcursor(mContext, artist_id);
if(crs!=null && crs.moveToFirst()) {
Random rn = new Random();
int rnd = rn.nextInt( crs.getCount());
crs.moveToPosition(rnd);
album_id = crs.getLong(crs.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
crs.close();
}
where getArtistsAlbumcursor is:
public Cursor getArtistsAlbumcursor(Context context, String artistId) {
ContentResolver cr = context.getContentResolver();
final String _id = MediaStore.Audio.Media._ID;
final String album_id = MediaStore.Audio.Media.ALBUM_ID;
final String artistid = MediaStore.Audio.Media.ARTIST_ID;
final String[] columns = { _id, album_id, artistid };
String where = artistid +" =?";
String[] aId = {artistId};
return cr.query(uri, columns, where, aId, null);
}
Once you have an albumid you can get your albumart using your original method.
Or
if you want to get the albumart from the mp3 track itself, you will need to implement a libary such as jaudiotagger or org.blinkenlights.jid3.v2.
Life gets a little more complicated but below how to get albumart from the mp3 tag using the JID3 library:
try {
bmp = getmp3AlbumArt(sourceFile);
} catch (Exception e) {
e.printStackTrace();
}
where getmp3Albumart is:
public Bitmap getmp3AlbumArt(File SourceFile) throws Exception {
Bitmap bmp = null;
arrayByte = null;
APICID3V2Frame frames[];
MediaFile MediaFile = new MP3File(SourceFile);
try {
Object obj = null;
obj = MediaFile.getID3V2Tag();
if (obj != null) {
tagImage = (org.blinkenlights.jid3.v2.ID3V2_3_0Tag) obj;
if ((tagImage != null) && (arrayByte == null) && (tagImage.getAPICFrames() != null) && (tagImage.getAPICFrames().length > 0)) {
frames = tagImage.getAPICFrames();
for (int i = 0; i < tagImage.getAPICFrames().length; i++) {
if (frames[i] != null) {
arrayByte = frames[i].getPictureData();
break;
}
}
}
}
} catch (ID3Exception | OutOfMemoryError e) {
e.printStackTrace();
}
if (arrayByte != null) {
try {
bmp = BitmapFactory.decodeByteArray(arrayByte, 0, arrayByte.length);
} catch (Exception|OutOfMemoryError e) {
e.printStackTrace();
}
}
return bmp;
}
I am creating Pdf file using PdfJet Library in Android. All the things are going good but I face some problem to draw the Image on Box . When I execute the program Pdf is created and the box is also created but the Image is not place in the Box.
Here is my code.
File file = new File(Environment.getExternalStorageDirectory(),
"Images.pdf");
FileOutputStream fos = new FileOutputStream(file);
PDF pdf = new PDF(fos);
Page page = new Page(pdf, A3.PORTRAIT);
Font f1 = new Font(pdf, CoreFont.HELVETICA);
f1.setSize(12.0f);
InputStream is = getAssets().open("myImage.jpg");
Image image1 = new Image(pdf, is, ImageType.JPG);
Box bo = new Box();
bo.setPosition(10,10);
bo.setSize(page.getWidth()-50.0f, page.getHeight()-50.0f);
image1.placeIn(bo);
bo.drawOn(page);
pdf.flush();
fos.close();
Any one with the good suggestion and answer regarding to this Question is Welcome here.
Please find the below example to get image from sdcard and past using pdfJet. Sure its helps you
public class PdfDemo extends Activity {
String exportDir;
int SELECT_PICTURE = 0;
String selectedImagePath;
#SuppressLint("SdCardPath")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
exportDir = Environment.getExternalStorageDirectory() + File.separator
+ "firstPdf.pdf";
((Button) findViewById(R.id.btnChangeDate))
.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
getImage();
}
});
((Button) findViewById(R.id.btn_gen_pdf))
.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
GeneratePdf();
}
});
}
private void GeneratePdf() {
try {
FileOutputStream fos = new FileOutputStream(exportDir);
BufferedOutputStream bos = new BufferedOutputStream(fos);
PDF pdf = new PDF(bos);
Page page = new Page(pdf, Letter.PORTRAIT);
InputStream is = new FileInputStream(selectedImagePath);
BufferedInputStream bis1 = new BufferedInputStream(is);
Image image1 = new Image(pdf, bis1, ImageType.JPG);
image1.setPosition(10, 52);
// image1.scaleBy(.4)
image1.scaleBy(0.3f, 0.4f);
// image1.setRotateCW90(true);
image1.drawOn(page);
// Adding Text View
Font f4 = new Font(pdf, CoreFont.HELVETICA_OBLIQUE);
TextLine text = new TextLine(f4);
text.setPosition(100.0, 100.0);
text.setText("Even so, unemployment has remained at less than half the EU average.");
text.setColor(Color.black);
text.drawOn(page);
Box flag = new Box();
flag.setPosition(100.0, 100.0);
flag.setSize(190.0, 100.0);
flag.setColor(Color.white);
flag.drawOn(page);
double sw = 7.69; // stripe width
Line stripe = new Line(0.0, sw / 2, 190.0, sw / 2);
stripe.setWidth(sw);
stripe.setColor(Color.oldgloryred);
for (int row = 0; row < 7; row++) {
stripe.placeIn(flag, 0.0, row * 2 * sw);
stripe.drawOn(page);
}
Box union = new Box();
union.setSize(76.0, 53.85);
union.setColor(Color.oldgloryblue);
union.setFillShape(true);
union.placeIn(flag, 0.0, 0.0);
union.drawOn(page);
double h_si = 12.6; // horizontal star interval
double v_si = 10.8; // vertical star interval
Point star = new Point(h_si / 2, v_si / 2);
star.setShape(Point.BOX);
star.setRadius(3.0);
star.setColor(Color.white);
star.setFillShape(true);
for (int row = 0; row < 6; row++) {
for (int col = 0; col < 5; col++) {
star.placeIn(union, row * h_si, col * v_si);
star.drawOn(page);
}
}
star.setPosition(h_si, v_si);
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 4; col++) {
star.placeIn(union, row * h_si, col * v_si);
star.drawOn(page);
}
}
pdf.flush();
bos.close();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "" + e, Toast.LENGTH_SHORT)
.show();
System.out.println("ERRORLOG::" + e);
e.printStackTrace();
}
}
private void getImage() {
Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, SELECT_PICTURE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SELECT_PICTURE && resultCode == RESULT_OK
&& data != null) {
Uri pickedImage = data.getData();
String[] filePath = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(pickedImage, filePath,
null, null, null);
cursor.moveToFirst();
selectedImagePath = cursor.getString(cursor
.getColumnIndex(filePath[0]));
cursor.close();
}
}
/**
*
* #param uri
* #return
*/
public String getPathBelowOs(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
/**
* Getting image from Uri
*
* #param contentUri
* #return
*/
public String getPathUpperOs(Uri contentUri) {// Will return "image:x*"
String wholeID = DocumentsContract.getDocumentId(contentUri);
// Split at colon, use second item in the array
String id = wholeID.split(":")[1];
String[] column = { MediaStore.Images.Media.DATA };
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel,
new String[] { id }, null);
String filePath = "";
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
return filePath;
}
public static InputStream bitmapToInputStream(Bitmap bitmap) {
int size = bitmap.getHeight() * bitmap.getRowBytes();
ByteBuffer buffer = ByteBuffer.allocate(size);
bitmap.copyPixelsToBuffer(buffer);
return new ByteArrayInputStream(buffer.array());
}
}
I've a problem using the ContactPicker in Android. My code is the next
public void showContacts(View v){
phoneNumber.setText("");
Intent contactPickerIntent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
startActivityForResult(contactPickerIntent, 1001);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case 1001:
Cursor cursor = null;
String[] numeros = null;
try {
Uri result = data.getData();
String id = result.getLastPathSegment();
cursor = getContentResolver().query(Phone.CONTENT_URI,
null,
Phone.CONTACT_ID + "=?", new String[] {id}, null);
int phoneIdx = cursor.getColumnIndex(Phone.NUMBER);
if(cursor.getCount() > 0){
numeros = new String[cursor.getCount()];
if (cursor.moveToFirst()) {
int cont = 0;
do{
numeros[cont] = cursor.getString(phoneIdx);
cont++;
}while(cursor.moveToNext());
}
}
} catch (Exception e) {
Log.e("Exception", "Failed to get email data", e);
} finally {
if (cursor != null) {
cursor.close();
}
if(numeros != null){
if(numeros.length > 1){
showNumbers(numeros);
}else{
phoneNumber.setText(numeros[0]);
}
}
}
break;
}
}
}
private void showNumbers(final String[] numeros){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setSingleChoiceItems(numeros, -1, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogo, int item) {
phoneNumber.setText(numeros[item]);
dialogo.cancel();
}
});
builder.create().show();
}
Basically in the first method I call the ContactPicker, in the second I receive the answer of this, I process that and validate if the user have more than one phone.
The problem is, the algorithm return me six times the numbers. I don't know why occur that.