首页 > 解决方案 > 如何将图像 uri 正确保存到房间数据库?

问题描述

在我的应用程序中,我有一个带有图像的回收视图,最初我希望一些照片已经存在。它们存储在 Drawable 文件夹中。用户也可以从图库中添加他自己的图像。所以我得出一个结论,我需要一个数据库来做这件事。由于可绘制文件夹中的图片只有“ resource_id ”用于将它们设置为 ImageView,而图库中的照片只有“ uri ”,因此我决定相应地制作两个变量:resource_iduri。当加载带有resource_id的图片时,它们的“ uri ”将为空,我会检查它。使用画廊中的照片 - 相同,反之亦然。

问题是,当我从gallety 中保存照片时,我看到的不是照片本身,而是一个小点,仅此而已。由于某种原因无法加载...

这是图像类:

@Entity
public class Images {

@PrimaryKey(autoGenerate = true)
int id;

int resourceId;

String url;

String type;

public Images(int resourceId, String url, String type) {
    this.resourceId = resourceId;
    this.url = url;
    this.type = type;
}

// getters and setters
}

Type变量与我的问题无关。

数据库类(已经加载了一些图像):

@Database(entities = {Images.class}, version = 1, exportSchema = false)
public abstract class ImagesDatabase extends RoomDatabase {

private static ImagesDatabase instance;

public abstract ImagesDao imagesDao();

public static synchronized ImagesDatabase getInstance(Context context) {
    if (instance == null) {
        instance = Room.databaseBuilder(context.getApplicationContext(),
                ImagesDatabase.class, "images_database")
                .fallbackToDestructiveMigration()
                .addCallback(roomCallback)
                .build();
    }
    return instance;
}

private static RoomDatabase.Callback roomCallback = new RoomDatabase.Callback(){
    @Override
    public void onCreate(@NonNull SupportSQLiteDatabase db) {
        super.onCreate(db);
        new PopulateDBAsyncTask(instance).execute();
    }
};

private static class PopulateDBAsyncTask extends AsyncTask<Void, Void, Void> {

    private ImagesDao imagesDao;

    private PopulateDBAsyncTask(ImagesDatabase db){
        imagesDao = db.imagesDao();
    }

    @Override
    protected Void doInBackground(Void... voids) {
        imagesDao.insert(new Images(R.drawable.regular1, null, "Regular"));
        imagesDao.insert(new Images(R.drawable.regular2, null, "Regular"));
        imagesDao.insert(new Images(R.drawable.regular3, null, "Regular"));
        imagesDao.insert(new Images(R.drawable.vertical2, null, "Vertical"));
        imagesDao.insert(new Images(R.drawable.vertical3, null, "Vertical"));
        imagesDao.insert(new Images(R.drawable.vertical4, null, "Vertical"));
        imagesDao.insert(new Images(R.drawable.vertical5, null, "Vertical"));
        imagesDao.insert(new Images(R.drawable.vertical6, null, "Vertical"));
        imagesDao.insert(new Images(R.drawable.vertical7, null, "Vertical"));
        imagesDao.insert(new Images(R.drawable.vertical8, null, "Vertical"));
        imagesDao.insert(new Images(R.drawable.vertical9, null, "Vertical"));
        return null;
    }
}
}

活动,我有一个recyclerView

public class FormsActivity extends AppCompatActivity {

public static final int GALLERY_OPEN = 123;

private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private FormsAdapter adapter;
private String chosenByUser;
private Intent intent;
private ImagesViewModel viewModel;
private FloatingActionButton btn_add_image;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_forms);
    setTitle("Choose the type");

    getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close);

    recyclerView = findViewById(R.id.recycler_view);
    btn_add_image = findViewById(R.id.btn_add_image);       

    layoutManager = new GridLayoutManager(this, 2);
    //layoutManager = new LinearLayoutManager(this);
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setHasFixedSize(true);

    intent = getIntent();
    chosenByUser = intent.getStringExtra("chosenByUser");

    viewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication())).get(ImagesViewModel.class);
    try {
        viewModel.getAllImagesWhereTypeIs(chosenByUser).observe(this, new Observer<List<Images>>() {
            @Override
            public void onChanged(List<Images> images) {
                adapter = new FormsAdapter(FormsActivity.this, images);
                recyclerView.setAdapter(adapter);
            }
        });
    } catch (ExecutionException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    btn_add_image.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            openGallery();
        }
    });        
}

private void openGallery() {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Pick an image"), GALLERY_OPEN);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == GALLERY_OPEN && resultCode == RESULT_OK && data != null) {
        Uri imageData = data.getData();
        viewModel.insert(new Images(0, imageData.toString(), chosenByUser));
    }
}
}

适配器类:

public class FormsAdapter extends RecyclerView.Adapter<FormsAdapter.ViewHolder>{

private List<Images> images = new ArrayList<>();
private Context mContext;

public FormsAdapter(Context context, List<Images> images2){
    mContext = context;
    images = images2;
}

@NonNull
@Override
public FormsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.each_form_layout, parent, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull FormsAdapter.ViewHolder holder, int position) {
    Images image = images.get(position);
    final String uri = image.getUrl();
    final int resourceId = image.getResourceId();
    if (uri == null && resourceId != 0){
        holder.image.setImageResource(resourceId);
    }
    else if (resourceId == 0 && uri != null){
       // holder.image.setImageURI(Uri.parse(uri));
        Picasso.get().load(Uri.parse(uri)).fit().centerInside().into(holder.image);
    }
    holder.cardView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(mContext, MakingActivity.class);
            intent.putExtra("image_id", resourceId);
            intent.putExtra("image_uri", uri);
            mContext.startActivity(intent);
        }
    });        
}

@Override
public int getItemCount() {
    return images.size();
}

public static class ViewHolder extends RecyclerView.ViewHolder{

    ImageView image;
    CardView cardView;

    public ViewHolder(@NonNull View itemView) {
        super(itemView);

        image = itemView.findViewById(R.id.my_image);
        cardView = itemView.findViewById(R.id.cardView);
    }
}
}

Adapter中有一个OnClickListener,因为当用户点击任何照片时,我想打开另一个活动并全屏显示该图片。

所以这是活动

public class MakingActivity extends AppCompatActivity {

Intent intent;
int image_id = 0;
String image_uri = null;
ImageView image;

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

    getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close);
    image = findViewById(R.id.image_make);

    intent = getIntent();
    image_id = intent.getIntExtra("image_id", R.drawable.ic_launcher_foreground);
    image_uri = intent.getStringExtra("image_uri");     
    if (image_uri == null && image_id != 0) {            
        Picasso.get()
                .load(image_id)
                .fit()
                .centerInside()
                .into(image);
    }
    else if (image_uri != null && image_id == 0){         
        Picasso.get()
                .load(image_uri)
                .fit()
                .centerInside()
                .into(image);
    }
}
}

从理论上讲,我认为这种方式应该可行。你能帮我解决这个问题吗?先感谢您。

标签: javaandroidimagestorageandroid-room

解决方案


推荐阅读