简体   繁体   中英

Android SQLite : Take and Save Photo to DB as Base64 string… Then retrieve

I would like to develop a full-proof solution to a common problem for new android developers. I want to create a tutorial and example (for myself and others to follow) to taking a photo witin an app and then saving it to base64 string within a SQLite android database. Then I will be able to upload this string to an online database at a later stage, rather than the JPG image I originally took.

So to re-iterate it must...

  • Open Camera,
  • Take Image
  • Save as Base64 String to SQLite DB

(the reason that I need it to be stored in the DB as a string, is due to the fact that this will be uploaded to a central document system at some point in the future, and large JPG images will be slow and not ideal, hence why a Base64 string in the DB would be better. I also want to limit the possibility that users can delete the images they take which would be referenced in the DB should be just refrence the path to the file (which is the alternative - although I believe a less suitable one))

Thanks, I really look forward to working on this and developing a great solution that others will be able to follow.

MY EFFORTS SO FAR...

I have spent a number of days looking into this, and at the moment I am more confused than at the start. There seems to be so much outthere about this, but nothing with step by step sections to follow, about what line does what, where it comes from, what its doing etc. So to start with, I think I may need to break this down into two tasks now...

Taking an image using the camera and giving the file as an output somehow...then saving this as a base64 string to the DB or something like this.

I appreciate that usually storing binary data to the DB can cause slow and painful queries, however due to the face that only a few images will ever be displayed at once, we shouldn't have too much of an issue here, and the SQLite queries are small.

So to start with I was following Android: how to take picture with camera and convert bitmap to byte array and save to sqlite db? however the instructions to save images locally and reference the file path, really don't work. and so I was back to square one almost...

I have been reading through http://developer.android.com/guide/topics/media/camera.html to learn about the camera... confused.com !!!

To be fair, I have read so much, and now understand so little, I need a dummies guide to this now. Wish I could unlearn all the useless crap which I have read about this and start from scratch... Where is Format /F for your brain?

OK so i started again... Things are going a lot better for me now, I have even added audio, but I won't get into that. My app at the moment, takes a photo, previews it (using the standard camera intent) and then on clicking save, displays it locally on the app. Instead of it displaying the image, on clicking save, I need it to save to a database as a blob/bit64

Here is my code so you can see where I am at...

trying to use this as the call to take the image...

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<ScrollView 
     android:layout_height="fill_parent"
android:layout_width="fill_parent" 
>

<LinearLayout 
android:layout_height="fill_parent"
android:layout_width="fill_parent" 
android:orientation="vertical">
>
<TextView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="Inspection ID" />

<EditText
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/txtName"
android:inputType="number"
android:maxLength="5"
android:digits="0123456789"
android:singleLine="true"
/>

<TextView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="Text1" />

<EditText
  android:id="@+id/txt1"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:autoText="false"
  android:gravity="top|left"
  android:lines="4"
  android:maxLines="4"
  android:minLines="4"
  android:scrollbars="vertical"
  android:singleLine="false"
  android:width="0dip" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Project Ref"

/>
<EditText
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/txtAge"
android:inputType="number"
android:maxLength="5"
android:digits="0123456789"
android:singleLine="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Drop Down"
/>

<Spinner
  android:id="@+id/spinDept"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content" />

<Button
  android:id="@+id/btnPhotoCamera"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_marginTop="10dp"
  android:text="camera" />

<Button
  android:id="@+id/btnPhotoGallery"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_marginTop="10dp"
  android:text="gallery" />


    <TextView
        android:id="@+id/lblDisplayImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnCancel"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:text="below_this_text_image_will_be_displayed"
        android:textSize="13dp" />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_below="@+id/lblDisplayImage"
        android:layout_centerInParent="true"
        android:layout_marginTop="10dp"
        android:gravity="bottom" >
        <!--
             <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
        -->
        <ImageView
            android:id="@+id/imgDisplayImage"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:contentDescription="area_where_image_is_to_be_displayed" />
        <!-- </ScrollView> -->
    </RelativeLayout>

<Button
  android:id="@+id/btnAudio"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:onClick="btnAudio"
  android:text="Audio" />

<Button
  android:id="@+id/btnAdd"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:onClick="btnAddEmp_Click"
  android:text="Save Inspection" />

<Button
        android:id="@+id/btnCancel"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnPhotoGallery"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="19dp"
        android:text="Reset/Clear Form Data" />

<TextView
  android:id="@+id/txtEmps"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="Number of Inspections on Device " />
</LinearLayout>
</ScrollView>
</LinearLayout>

with the following .java

package mina.android.DatabaseDemo;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.Spannable;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.SimpleCursorAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.AdapterView.OnItemSelectedListener;
import com.AssentApp.V100.R;

public class AddEmployee extends Activity {
    EditText txtName;
    EditText txtAge;
    TextView txtEmps;
    DatabaseHelper dbHelper;
    Spinner spinDept;

   /** The Constant PICK_IMAGE. */
private static final int PICK_IMAGE = 0;

/** The Constant PICK_IMAGE_FROM_GALLERY. */
private static final int PICK_IMAGE_FROM_GALLERY = 1;

/** The btn cancel. */
private Button btnPhotoCamera,btnPhotoGallery,btnCancel;

/** The img view. */
private ImageView imgView;

/** The u. */
private Uri u;

/* (non-Javadoc)
 * @see android.app.Activity#onCreate(android.os.Bundle)
 */
@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.addemployee);

    txtName=(EditText)findViewById(R.id.txtName);
    txtAge=(EditText)findViewById(R.id.txtAge);
    txtEmps=(TextView)findViewById(R.id.txtEmps);
    spinDept=(Spinner)findViewById(R.id.spinDept);

    imgView=(ImageView)findViewById(R.id.imgDisplayImage);
    btnPhotoCamera=(Button)findViewById(R.id.btnPhotoCamera);
    btnPhotoGallery=(Button)findViewById(R.id.btnPhotoGallery);
    btnCancel=(Button)findViewById(R.id.btnCancel);

    btnPhotoCamera.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {

            Intent camera=new Intent();
            camera.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
            camera.putExtra("crop", "false");

            File f=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);

            u = Uri.fromFile(new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"myFile.jpg"));
            camera.putExtra(MediaStore.EXTRA_OUTPUT, u);
            startActivityForResult(camera, PICK_IMAGE);
        }
    });

    btnPhotoGallery.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {

            Intent intent = new Intent(Intent.ACTION_PICK);
            intent.setType("image/*");
            startActivityForResult(intent, PICK_IMAGE_FROM_GALLERY);
        }
    });

    btnCancel.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {

            Intent goStartUp=new Intent(AddEmployee.this, AddEmployee.class);
            goStartUp.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(goStartUp);
            finish();
        }
    });
}

/* (non-Javadoc)
 * @see android.app.Activity#onActivityResult(int, int, android.content.Intent)
 */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    if (resultCode==RESULT_OK )
    {
        if(requestCode == PICK_IMAGE) {

            InputStream is=null;
            try {
                is = this.getContentResolver().openInputStream(u);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            Bitmap bmp=BitmapFactory.decodeStream(is);
            imgView.setImageBitmap(bmp);
            Log.i("Inside", "PICK_IMAGE");
        }

        if (requestCode == PICK_IMAGE_FROM_GALLERY) {
            Uri selectedImage = data.getData();
            String[] filePathColumn = { MediaStore.Images.Media.DATA };
            Log.d("data",filePathColumn[0]);
            Cursor cursor = getContentResolver().query(selectedImage,filePathColumn, null, null, null);
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String picturePath = cursor.getString(columnIndex);
            cursor.close();
            imgView.setImageBitmap(BitmapFactory.decodeFile(picturePath));
            Log.i("Inside", "PICK_IMAGE_FROM_GALLERY");
        }
    }
}




public void onStart()
{
    try
    {
    super.onStart();
    dbHelper=new DatabaseHelper(this);
    txtEmps.setText(txtEmps.getText()+String.valueOf(dbHelper.getEmployeeCount()));

    Cursor c=dbHelper.getAllDepts();
    startManagingCursor(c);



    //SimpleCursorAdapter ca=new SimpleCursorAdapter(this,android.R.layout.simple_spinner_item, c, new String [] {DatabaseHelper.colDeptName}, new int []{android.R.id.text1});
    SimpleCursorAdapter ca=new SimpleCursorAdapter(this,R.layout.deptspinnerrow, c, new String [] {DatabaseHelper.colDeptName,"_id"}, new int []{R.id.txtDeptName});
    //ca.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinDept.setAdapter(ca);
    spinDept.setOnItemSelectedListener(new OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> parent, View selectedView,
                int position, long id) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {
            // TODO Auto-generated method stub

        }
    });


    //never close cursor
    }
    catch(Exception ex)
    {
        CatchError(ex.toString());
    }
}

public void btnAddEmp_Click(View view)
{
    boolean ok=true;
    try
    {
        Spannable spn=txtAge.getText();
        String name=txtName.getText().toString();
        int age=Integer.valueOf(spn.toString());
        int deptID=Integer.valueOf((int)spinDept.getSelectedItemId());
        Employee emp=new Employee(name,age,deptID);

        dbHelper.AddEmployee(emp);

    }
    catch(Exception ex)
    {
        ok=false;
        CatchError(ex.toString());
    }
    finally
    {
        if(ok)
        {
            //NotifyEmpAdded();
            Alerts.ShowEmpAddedAlert(this);
            txtEmps.setText("Number of Inspections on Device "+String.valueOf(dbHelper.getEmployeeCount()));
        }
    }
}

void CatchError(String Exception)
{
    Dialog diag=new Dialog(this);
    diag.setTitle("Adding new Inspection");
    TextView txt=new TextView(this);
    txt.setText(Exception);
    diag.setContentView(txt);
    diag.show();
}

void NotifyEmpAdded()
{
    Dialog diag=new Dialog(this);
    diag.setTitle("Success");
    TextView txt=new TextView(this);
    txt.setText("Inspection Added Successfully");
    diag.setContentView(txt);
    diag.show();
    try {
        diag.wait(1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        CatchError(e.toString());
    }
    diag.notify();
    diag.dismiss();
}


public void btnAudio(View view) 
{
Intent intent = new Intent(AddEmployee.this, AudioRecordTest.class);
startActivity(intent);
}

}

seems to do the trick, but now I need to edit it for the DB section. I need to save it "by converting image into Byte[] then save as Blob in sqlite" - or so I believe ... Whats my first step in doing this? Note, I don't want it to display the image view anymore, but instead save to DB with unique ID/Integer.

any pointers would be great !!

我不认为您可以使用base64做到这一点,但是是的,您可以通过将图像转换为Byte []然后将其另存为sqlite来实现。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM