I am currently making an Adroid Studio app for school, and in the sign up form I have an image upload feature. It was working up until recently until I fixed my validation, and now it always returns an error (unrelated to the validation file) instead of properly saving the image on the device.
The code of the camera launcher:
//Inside OnCreate
camera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(!CheckPermission(RegisterActivity.this))
RequestPermission(RegisterActivity.this);
else {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "New Picture");
values.put(MediaStore.Images.Media.DESCRIPTION, "From Camera");
cameraUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri);
StartCamera.launch(cameraIntent);
}
}
});
//Outside of OnCreate
ActivityResultLauncher<Intent> StartCamera = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
#Override
public void onActivityResult(ActivityResult result) {
if(result.getResultCode() == RESULT_OK){
try {
cameraBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), cameraUri);
photo.setImageBitmap(cameraBitmap);
photoError.setError(null);
}catch (IOException e){
e.printStackTrace();
}
}
}
});
The code of the gallery launcher:
//Inside OnCreate
gallery.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(!CheckPermission(RegisterActivity.this))
RequestPermission(RegisterActivity.this);
else
StartGallery.launch("image/*");
}
});
//Outside of OnCreate
ActivityResultLauncher<String> StartGallery = registerForActivityResult(new ActivityResultContracts.GetContent(), new ActivityResultCallback<Uri>() {
#Override
public void onActivityResult(Uri result) {
try{
if(result!=null) {
cameraBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), result);
photo.setImageBitmap(cameraBitmap);
photoError.setError(null);
}
}catch (IOException e){
e.printStackTrace();
}
}
});
The code of the bitmap saving function:
//Outside of OnCreate
public boolean SaveBitmapInFolder(Bitmap bitmap){
photoName = new SimpleDateFormat("yyMMdd-HHmmss").format(new Date()) + ".jpg";
File dir = new File(Environment.getExternalStorageDirectory(), "/MyPhoto");
if(!dir.exists())
dir.mkdirs();
File dest = new File(dir, photoName);
try{
FileOutputStream out = new FileOutputStream(dest);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
return true;
}catch (Exception e){
photoError.setError("An unexpected error has occurred.");
e.printStackTrace();
}
return false;
}
I have tried to rebuild the project in the build tab (It solves some issues occasionally) and clean up the code of the launchers and saving functions. In the case that the SaveBitmapInFolder function returns a false value, I have a toast that shows that an error has occurred, and this is always the result, no matter if the picture was uploaded from the gallery or taken by the camera.
Does anyone know a fix to this issue? There aren't any errors in the project logs, it just immediately goes to the catch and returns false.
Related
I have a button in my MainActivity I wanna call it in my SecondActivity inside another button basically both button does the same thing
MainActivity
share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Drawable myDrawable = scannedImageView.getDrawable();
Bitmap bitmap = ((BitmapDrawable)myDrawable).getBitmap();
try{
File file = new File(MainActivity.this.getExternalCacheDir(), "myImage.png");
FileOutputStream fOut = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 80, fOut);
fOut.flush();
fOut.close();
file.setReadable(true, false);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.setType("image/png");
startActivity(Intent.createChooser(intent, "Share Image Via"));
}catch (FileNotFoundException e){
e.printStackTrace();
Toast.makeText(MainActivity.this, "File not found", Toast.LENGTH_SHORT).show();
}catch (IOException e){
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
}
});
SecondActivity
share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Calling button from MainActivity
}
});
create a static method in a utils class for exemple that return a OnClickListener
public static View.OnClickListener getShareButtonClickListener(Activity activity) {
return new View.OnClickListener() {
#Override
public void onClick(View v) {
Drawable myDrawable = scannedImageView.getDrawable();
Bitmap bitmap = ((BitmapDrawable)myDrawable).getBitmap();
try{
File file = new File(activity, "myImage.png");
FileOutputStream fOut = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 80, fOut);
fOut.flush();
fOut.close();
file.setReadable(true, false);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.setType("image/png");
activity.startActivity(Intent.createChooser(intent, "Share Image Via"));
}catch (FileNotFoundException e){
e.printStackTrace();
Toast.makeText(activity, "File not found", Toast.LENGTH_SHORT).show();
}catch (IOException e){
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
}
};
}
and in both activities
share.setOnCLickListener(MyUtilsClass.getShareButtonClickListener(this))
but i agree with #Abbas it's better to separate your view (activity/fragments) and your business logic
It's taking the screenshot but not showing in gallery when I check the device storage there are screenshot files but when I try to click them it says unable to find app to open this file.
I have to share the ui of my application as an image
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
Bitmap bitmap = getScreenShot(rootView);
store(bitmap,"share_image");
}
});
public static Bitmap getScreenShot(View view) {
View screenView = view.getRootView();
screenView.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(screenView.getDrawingCache());
screenView.setDrawingCacheEnabled(false);
return bitmap;
}
public void store(Bitmap bm, String fileName){
dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Screenshots";
File dir = new File(dirPath);
if(!dir.exists())
dir.mkdirs();
File file = new File(dirPath, fileName);
try {
FileOutputStream fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 85, fOut);
fOut.flush();
fOut.close();
shareImage(file);
} catch (Exception e) {
e.printStackTrace();
}
}
private void shareImage(File file){
Uri uri = Uri.fromFile(file);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("image/*");
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "");
intent.putExtra(android.content.Intent.EXTRA_TEXT, "");
intent.putExtra(Intent.EXTRA_STREAM, uri);
try {
startActivity(Intent.createChooser(intent, "Share Screenshot"));
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(), "No App Available", Toast.LENGTH_SHORT).show();
}
}
You are calling your file share_image. It has no extension, so the system will treat it as a blank, basic file.
As you are using png compression, add ".png" to the file name.
store(bitmap,"share_image.png");
code with debug app In my app I would like to create a file but I get the error No such file or directory in the Android Studio emulator. I added the Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE and Manifest.permission.READ_EXTERNAL_STORAGE as you can see in the code. But when I do this on my own phone this is working and creating the image. Anyone know this issue?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_input_screen);
takePhoto = findViewById(R.id.add_photoWarranty);
cancelInput = findViewById(R.id.cancel_input);
//check camera permission
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE }, 100);
}
//Cancel button
cancelInput.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
finish();
}
});
//take picture button
takePhoto.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
// Create an image file name
String imageFileName = "JPEG_timeStamp_";
File dir = new File(Environment.getExternalStorageDirectory() + "/MyWarranty");
if(!dir.isDirectory()) {
dir.mkdir();
}
File image = File.createTempFile(
imageFileName, // prefix
".jpg", // suffix
dir // directory
);
photoFile = image;
} catch (IOException ex) {
// Error occurred while creating the File
Log.i("Error", ex.toString());
}
// Continue only if the File was successfully created
if (photoFile != null) {
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(cameraIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
});
}
}
Problem is here:
if(!dir.isDirectory()) {
dir.mkdir();
}
dir is a directory, and so dir.mkdir() is never called, and so the directory is never created.
Remove this if condition, it's not even necessary, since it's a hardcoded value and you know it's a directory.
Wassup Guys, i'm doing a college project, and my app is a meme generator. After the text plotted, i'm trying to save the image pushing the button. The toast appears, but, it takes more than an hour to the pic show on the gallery. How can i make this thing save immediately?
So there are my codes to create the button listener and the store function
save.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
View content = findViewById(R.id.lay);
Bitmap bitmap = getScreenShot(content);
currentImage = "meme" + System.currentTimeMillis() + ".png";
store(bitmap, currentImage);
share.setEnabled(true);
}
});
public void store(Bitmap bm, String fileName){
String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Memes";
File dir = new File(dirPath);
if(!dir.exists()){
dir.mkdir();
}
File file = new File(dirPath, fileName);
try{
FileOutputStream fos = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
Toast.makeText(this, "SALVOU ARROMBADO", Toast.LENGTH_SHORT).show();
}catch (Exception e){
Toast.makeText(this, "DEU RUIM VACILĂO", Toast.LENGTH_SHORT).show();
}
}
You have to use MediaScannerConnection like below .Create a method refreshMedia() -
public void refreshMedia(){
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
MediaScannerConnection.scanFile(ApplicationContext.context, new String[] { imageFile.getPath() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
//gallery refreshed.
Log.i(TAG, "Scanned " + path);
}
});
}
}, 1500); //this is to refresh media after 1.5 second delay
}
Here imageFile.getPath() is path for your image.
Use it as below-
save.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
store(bitmap, currentImage);
//after saving image call refreshmedia()
refreshMedia();
}
After I take a picture I store the picture into ImageView, So if anyone has an idea or suggestion in how to store the picture after it shown on the ImageView into phone stage without user interaction
Thanks in advance
public class MainActivity extends Activity {
ImageView viewpict;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewpict=(ImageView) findViewById(R.id.pict_result);
Button btn= (Button)findViewById(R.id.camera);
btn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
Intent intent = new Intent (android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
// Intent intent = new Intent (getApplicationContext(),MainActivity2.class);
//startActivity(intent);
startActivityForResult(intent,0);
}
});
}
protected void onActivityResult( int requestCode, int resultCode,Intent data)
{
if (requestCode==0)
{
Bitmap theimage = (Bitmap) data.getExtras().get("data");
viewpict.setImageBitmap(theimage);
}
}
}
Try:
viewpict.buildDrawingCache();
Bitmap bm=viewpict.getDrawingCache();
And save:
OutputStream fOut = null;
Uri outputFileUri;
try {
File root = new File(Environment.getExternalStorageDirectory()
+ File.separator + "folder_name" + File.separator);
root.mkdirs();
File sdImageMainDirectory = new File(root, "myPicName.jpg");
outputFileUri = Uri.fromFile(sdImageMainDirectory);
fOut = new FileOutputStream(sdImageMainDirectory);
} catch (Exception e) {
Toast.makeText(this, "Error occured. Please try again later.",
Toast.LENGTH_SHORT).show();
}
try {
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (Exception e) {
}
And permission in AndroidManifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />