如何保存SQLite图像的路径然后检索它?

时间:2018-04-17 20:42:33

标签: android sql

我有这个类捕获图像,然后将其保存在SQLite中,但从我的理解,它保存为blob,(我在互联网上发现这个代码并重用了一部分),我想实际保存路径然后检索它,因为它的质量下降了很多。

public class fotos extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>{

    static final int CAPTURE_PHOTO = 2;

    private FloatingActionButton add;
    private ProgressDialog progressBar;
    private int progressBarStatus = 0;
    private Handler progressBarHandler = new Handler();
    DbHelper dbHelper;

    boolean active = false;

    Bitmap thumbnail;

    ///////////////////////////////////////////////
    ImagesAdapter imagesAdapter;
    RecyclerView mRecyclerView;

    private static final int IMAGES_LOADER = 0;

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

        add = findViewById(R.id.add);
        mRecyclerView = findViewById(R.id.recyclerView);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        imagesAdapter = new ImagesAdapter(this);
        mRecyclerView.setAdapter(imagesAdapter);

        getLoaderManager().initLoader(IMAGES_LOADER, null, this);

        if(ContextCompat.checkSelfPermission(fotos.this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(fotos.this, new String[]{android.Manifest.permission.CAMERA, android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }else{
           active = true;
        }

        dbHelper = new DbHelper(this);
    }

    public void takePicture(View view) {
        Intent it = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(it, CAPTURE_PHOTO);
    }

    public void setProgressBar(){
        progressBar = new ProgressDialog(this);
        progressBar.setCancelable(true);
        progressBar.setMessage("Espera, por favor...");
        progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progressBar.setProgress(0);
        progressBar.setMax(100);
        progressBar.show();
        progressBarStatus = 0;
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(progressBarStatus < 100){
                    progressBarStatus += 30;

                    try{
                        Thread.sleep(1000);
                    } catch (InterruptedException e){
                        e.printStackTrace();
                    }

                    progressBarHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            progressBar.setProgress(progressBarStatus);
                        }
                    });
                }
                if(progressBarStatus >= 100){
                    try{
                        Thread.sleep(2000);
                    } catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    progressBar.dismiss();
                }
            }
        }).start();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == CAPTURE_PHOTO && resultCode == RESULT_OK){
            onCaptureImageResult(data);
        }
    }

    private void onCaptureImageResult(Intent data) {
        //thumbnail = (Bitmap) data.getExtras().get("data");
        setProgressBar();
        thumbnail = (Bitmap) data.getExtras().get("data");
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        byte[] date = baos.toByteArray();
        dbHelper.addToDb(date);
        Toast.makeText(fotos.this, "Imagem salva com sucesso!", Toast.LENGTH_SHORT).show();
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        String[] projetion = {
                DbHelper.COLUMN_NAME,
        };

        return new CursorLoader(this,
                ImagesProvider.CONTENT_URI,
                projetion,
                null,
                null,
                null);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        imagesAdapter.swapCursor(data);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        imagesAdapter.swapCursor(null);
    }
}

Db的:

public class DbHelper extends SQLiteOpenHelper{
    private static final String TAG = DbHelper.class.getSimpleName();

    private static final String DATABASE_NAME = "image.db";
    private static final int DATABAS_VERSION = 1;
    Context context;
    SQLiteDatabase db;
    ContentResolver mContentResolver;

    public final static String COLUMN_NAME = "imagename";
    public final static String TABLE_NAME = "imagetable";


    public DbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABAS_VERSION);

        mContentResolver = context.getContentResolver();
        db = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        final String SQL_CREATE_IMAGE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" +
                _ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + COLUMN_NAME + " BLOB NOT NULL " + " );";

        db.execSQL(SQL_CREATE_IMAGE_TABLE);
        Log.d(TAG, "Database criado com sucesso!");
    }

    public void addToDb(byte[] date) {
        ContentValues cv = new ContentValues();
        cv.put(COLUMN_NAME, date);
        db.insert(TABLE_NAME, null, cv);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }
}

在清单

 <application>
  ...
 <activity android:name=".activitys.info_sinistro.midia.fotos" >
            <meta-data
                android:name=".activitys.info_sinistro.midia.fotos"
                android:value=".activitys.info_sinistro.midia.fotos"/>

        </activity>

        <provider
            android:name=".activitys.info_sinistro.Provider.ImagesProvider"
            android:authorities="insidetechnology.studio.ostdor.xiope"
            android:exported="true"/>
      ...
      </application>

在API 24中我知道你需要这个提供者,所以这是正确的吗?

1 个答案:

答案 0 :(得分:1)

我在我的应用程序中使用相同的原理,我使用内置摄像头捕获图像并在数据库中保存它的路径。
基本上,一旦你点击相机按钮就会发出你已经知道的意图,但我会分享它的完整性:

private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
        // Create the File where the photo should go
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            Log.e(TAG, "Error while creating the file");
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            mFile = photoFile;
            Uri photoURI = FileProvider.getUriForFile(getActivity(), "com.yourpackage.fileprovider", photoFile);
            //Uri photoURI = Uri.fromFile(photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }
    }
}              

我认为为了使FileProvider能够正常工作,您需要将其包含在<application>标记内的清单文件中:

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.yourpackage.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths">
        </meta-data>
    </provider>

@xml/file_paths

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="my_images" path="." />
</paths>

最后在您的dispatchTakePictureIntent()中,您还可以使用createImageFile()创建一个文件:

private File createImageFile() throws IOException {
    File path = new File(Util.getFileDirectory(getActivity()), "FOLDER_NAME");
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
    String imageFileName = "FileName_" + timeStamp + ".jpg";

    if(path.mkdirs()) {
        Log.v(TAG, "Directory created");
    } else {
        Log.d(TAG, "Directory is already present");
    }

    return new File(path, imageFileName);
}

最后,您将获得onActivityResult()中的图片:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE) {
        if (resultCode == RESULT_OK) {
            // you got the photo
            String imagePath = mImage.getAbsolutePath() 
            // you can save this path to the database
        } else if (resultCode != RESULT_CANCELED) {
            Log.e(TAG, "Error while taking a photo. Error " + resultCode);
        }
    }
}

这会有效,但是FileProvider可能会有一些额外的不必要的步骤,如果我错了,请有人纠正我。但是这段代码正在运作。