I'm new to programming and I don't know how to start camera intent from the adapter and to save image to a specific location for each item in the listview. I would like when I press the button takeImage to start a camera intent and to save the taken image to a specific location for each item in the list view. I defined in the Planet class an attribute
this.pathToSave = pathToSave
in order to be possible to save to a specific location but I don't know how to put all togheter.
public class MyCustomAdaptor extends ArrayAdapter<Planet> {
private ArrayList<Planet> planetsArrayList;
Context context;
public MyCustomAdaptor(ArrayList<Planet> planetsArrayList,Context context){
super(context, R.layout.item_list_layout,planetsArrayList);
this.planetsArrayList = planetsArrayList;
this.context = context;
}
private static class MyViewHolder{
TextView planetName;
ImageView planetImg;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Planet planets = getItem(position);
MyViewHolder myViewHolder;
final View result;
if(convertView == null) {
myViewHolder = new MyViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(
R.layout.item_list_layout,
parent,
false
);
myViewHolder.planetName = (TextView) convertView.findViewById(R.id.planet_name);
myViewHolder.planetImg = (ImageView) convertView.findViewById(R.id.imageView);
result = convertView;
convertView.setTag(myViewHolder);
}else{
myViewHolder = (MyViewHolder) convertView.getTag();
result = convertView;
}
myViewHolder.planetName.setText(planets.getPlanetName());
myViewHolder.planetImg.setImageResource(planets.getPlanetImage());
return result;
}
}
Then I have the Planet class:
public class Planet {
private String planetName;
private int planetImage;
private String pathToSave;
public Planet(String planetName, int planetImage, String pathToSave){
this.planetName = planetName;
this.planetImage = planetImage;
this.pathToSave = pathToSave;
}
public String getPlanetName() {
return planetName;
}
public int getPlanetImage() {
return planetImage;
}
public String getPathToSave() {
return pathToSave;
}
public void setPlanetName(String planetName) {
this.planetName = planetName;
}
public void setPlanetImage(int planetImage) {
this.planetImage = planetImage;
}
public void setPathToSave(String pathToSave) {
this.pathToSave = pathToSave;
}
}
Then I have the listView:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/imageView"
android:layout_width="110sp"
android:layout_height="110sp"
android:layout_margin="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.006"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/planet_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="16dp"
android:text="Planet Name"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/imageView"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/takeImage"
android:layout_width="110sp"
android:layout_height="40sp"
android:layout_marginTop="108dp"
android:text="Scan Doc"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.465"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
I've tried to everything but doesn't work.
First, in your Activity you need to use the:
ActivityResultLauncher
And pass it to the adapter:
public class Activity {
private ActivityResultLauncher<Intent> cameraLauncher;
MyCustomAdaptor adapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
setupCameraLauncher();
// This on onCreate or after retrieve the planetsArrayList data
adapter = new MyCustomAdaptor (planetsArrayList, context, cameraLauncher);
}
public void setupCameraLauncher() {
cameraLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
Uri imageUri = adapterStructures.getCapturedImageUri();
String cameraUriString = imageUri.toString(); // Here is your LOCAL IMAGE
Planet planet = new Planet();
planet.setPlanetName("The Planet"); // Handle your value
planet.setPlanetImage(1); // Handle your value
planet.setPathToSave(cameraUriString );
planetsArrayList.add(planet);
adapter.notifyDataSetChanged();
}
)
}
}
Your adapter:
public class MyCustomAdaptor extends ArrayAdapter<Planet> {
private ArrayList<Planet> planetsArrayList;
Context context;
private final ActivityResultLauncher<Intent> cameraLauncher;
public MyCustomAdaptor(ArrayList<Planet> planetsArrayList,Context context, ActivityResultLauncher<Intent> cameraLauncher){
super(context, R.layout.item_list_layout,planetsArrayList);
this.planetsArrayList = planetsArrayList;
this.context = context;
this.cameraLauncher = cameraLauncher;
}
private static class MyViewHolder{
TextView planetName;
ImageView planetImg;
Button takeImage; // Add this
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Planet planets = getItem(position);
MyViewHolder myViewHolder;
final View result;
if(convertView == null) {
myViewHolder = new MyViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(
R.layout.item_list_layout,
parent,
false
);
myViewHolder.planetName = (TextView) convertView.findViewById(R.id.planet_name);
myViewHolder.planetImg = (ImageView) convertView.findViewById(R.id.imageView);
myViewHolder.takeImage = (Button) convertView.findViewById(R.id.takeImage);
result = convertView;
convertView.setTag(myViewHolder);
}else{
myViewHolder = (MyViewHolder) convertView.getTag();
result = convertView;
}
myViewHolder.planetName.setText(planets.getPlanetName());
myViewHolder.planetImg.setImageResource(planets.getPlanetImage());
myViewHolder.takeImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openCamera(); // THe method to open the camera
}
});
return result;
}
private void openCamera() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(context.getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException e) {
e.printStackTrace();
}
if (photoFile != null) {
// Get the URI where the image will be saved in the gallery
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "My Photo");
values.put(MediaStore.Images.Media.DESCRIPTION, "From Camera");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
capturedImageUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", photoFile);
if (capturedImageUri != null) {
Log.d("openCamera", "Photo URI saved: " + capturedImageUri);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri);
cameraLauncher.launch(takePictureIntent);
}
}
}
}
public Uri getCapturedImageUri() {
return capturedImageUri;
}
Then the method to create the unique image:
private File createImageFile() throws IOException {
Log.d("createImageFile", "Creating image file...");
currentPhotoPath = "";
// Create a unique image file name based on timestamp
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
//File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File storageDir = equipmentInfo.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
// Create the directory if it doesn't exist
if (!storageDir.exists()) {
storageDir.mkdirs();
}
Log.d("createImageFile", "Storage directory: " + storageDir.getAbsolutePath());
// Create the image file with a unique name
File imageFile = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save the file path for use with the camera intent
currentPhotoPath = imageFile.getAbsolutePath();
Log.d("createImageFile", "Image file created: " + currentPhotoPath);
return imageFile;
}