I currently have a app where the user click on the floating action button and selects a video file, the file is then saved to a different folder. I want to then show thumbnails of all the video's. I've seen a tutorial series where it is done with MediaStore, but then I can't set the path of the uri.
Can someone please point me in the right direction?
Here is my class to open the gallery and save the video to a different path:
public class Activity extends AppCompatActivity {
private static final int pick = 100;
Uri videoUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openGallery();
}
});
}
private void openGallery() {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, pick);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == pick) {
try
{
Log.e("videopath","videopath");
AssetFileDescriptor videoAsset = getContentResolver().openAssetFileDescriptor(data.getData(), "r");
FileInputStream fis = videoAsset.createInputStream();
File root=new File(Environment.getExternalStorageDirectory(),"MYFOLDER");
if (!root.exists()) {
root.mkdirs();
}
File file;
file=new File(root,"android_"+System.currentTimeMillis()+".mp4" );
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) > 0) {
fos.write(buf, 0, len);
}
fis.close();
fos.close();
}
catch (Exception e)
{
e.printStackTrace();
}
videoUri = data.getData();
}
}
}
You can use the ThumbnailUtils class in Android for this purpose.
public static Bitmap createVideoThumbnail (String filePath, int kind)
this method returns a bitmap of the video.
First parameter is the filepath, ie the location of the video file to be passed as String.
Second parameter is the kind of bitmap that you need, there are two types:
MediaStore.Images.Thumbnails.MICRO_KIND which generates thumbnail of size 96 x 96
MediaStore.Images.Thumbnails.MINI_KIND which generates thumbnail of size 512 x 384.
Eg:
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(filePath, Thumbnails.MINI_KIND);
Here is the API docs for further info[Here].
You can easily do it with Glide :
Glide.with(context).load(videoPath).asBitmap().into(imageView);
Related
I wanted to take a photo and save it to gallery. Then read this photo from gallery and convert it to text( using ocr)
But my app keep crashing when I try to save it with this line of code
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, pictureUri);
I debug my app and found this line is the responsible for crash. But without this line I can't save my image. How can I do that ?
package com.example.takepicture;
import ...
public class MainActivity extends AppCompatActivity {
private static final int CAMERA_REQUEST = 1888;
ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnCamera = (Button) findViewById(R.id.btnCamera);
imageView = (ImageView) findViewById(R.id.ImageView);
btnCamera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File pictureDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String pictureName = getPictureName();
File imageFile = new File(pictureDirectory,pictureName);
Uri pictureUri = Uri.fromFile(imageFile);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, pictureUri);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
//capturarFoto();
}
});
}
private String getPictureName() {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
return "Img" + timeStamp + ".jpg";
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_OK) {
if (requestCode == CAMERA_REQUEST) {
}
}
}
}
Fastest solution is adding:
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
somewhere before calling:
startActivityForResult(...)
But the correct one (for API >24) is:
creating URI via FileProvider.getUriForFile(...) and
creating provider (and adding it to Manifest file)
You can find more info there: https://stackoverflow.com/a/50265329/5529263
My app keeps resetting after I close it.
public class MainActivity extends AppCompatActivity {
public static final int FILE_REQUEST_CODE = 1;
ImageView IMG ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IMG = (ImageView) findViewById(R.id.imageView1);
Button pickBtn = (Button) findViewById(R.id.pickBtn);
pickBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
pickImg();
}
});
}
private void pickImg() {
new MaterialFilePicker()
.withActivity(this)
.withRequestCode(1)
.withFilter(Pattern.compile(".*\\.(jpg|jpeg|png)$"))
.withHiddenFiles(true)
.withTitle("Sample title")
.start();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == FILE_REQUEST_CODE && resultCode == RESULT_OK) {
String filePath = data.getStringExtra(FilePickerActivity.RESULT_FILE_PATH);
// Do anything with file
File imgFile = new File(filePath);
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
IMG.setImageBitmap(myBitmap);
}
}
}
}
My app is only filled with one button and one image default. With the button I can pick an image to replace the default image.
But when I close the app and open it again the image is back to default.
How to make it show the last picked image when I start the app??
If this app is performing simple and offline task, you could use Shared Preference to store the location of the Image. When onCreate, check whether the sharedpreference object is null or not, if not, load with the value stored.
I have searched through google and even youtube for videos. The code works perfectly when uploading and displaying the large image but crashes when sending it to the next activity. I have tried images with smaller quality or size and it worked perfectly
public class MainActivity extends AppCompatActivity {
private static final int PICK_IMAGE_REQUEST = 123;
public static Bitmap bitmap;
ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.img);
}
public void upload(View view) {
Intent intent = new Intent();
// Show only images, no videos or anything else
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
// Always show the chooser (if there are multiple options available)
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK)
switch (requestCode) {
case PICK_IMAGE_REQUEST:
Uri filePath = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
Log.i("TAG", "Some exception" + e);
}
break;
}
}
public void Submit(View view) {
Intent intent = new Intent(getApplicationContext(), Main2Activity.class);
if(bitmap !=null) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 40, stream);
byte[] byteArray = stream.toByteArray();
intent.putExtra("bitmap", byteArray);
}
startActivity(intent);
}
}
This is where the image sent from the MainActivity.java is displayed:
public class Main2Activity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
ImageView img = (ImageView) findViewById(R.id.imgg);
Bundle extras = getIntent().getExtras();
byte[] byteArray = extras.getByteArray("bitmap");
Bitmap bitmap = null;
try {
if (byteArray != null) {
bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
}
} catch (IndexOutOfBoundsException e){
e.printStackTrace();
}
img.setImageBitmap(bitmap);
}
}
Here is the error message:
java.lang.OutOfMemoryError: Failed to allocate a 3244812 byte allocation with 1765075 free bytes and 1723KB until OOM
You can't send big image via Intent, from the documentation:
When sending data via an intent, you should be careful to limit the
data size to a few KB. Sending too much data can cause the system to
throw a TransactionTooLargeException exception.
So, it's better if you send the Uri and process the Uri in the receiver Activity.
First, you need to send the Uri instead of Bitmap in the First Activity:
private Uri mFileUri;
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK)
switch (requestCode) {
case PICK_IMAGE_REQUEST:
// Save uri for submit process.
mFileUri = data.getData();
...
break;
}
}
public void Submit(View view) {
Intent intent = new Intent(this, Main2Activity.class);
intent.setData(mFileUri);
startActivity(intent);
}
Then handle it in your receiver activity:
public class Main2Activity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
ImageView img = (ImageView) findViewById(R.id.imgg);
// get the fileUri from the intent
Uri fileUri = getIntent().getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
img.setImageBitmap(bitmap);
} catch (IndexOutOfBoundsException e){
// handle the exception.
}
}
}
This:
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
This line drains memory so hard. Now you have the URI of the image right?
Uri filePath = data.getData();
Now use Picasso to load the image like below
1. If you want to send the image somewhere else:
com.squareup.picasso.Target mTarget = new com.squareup.picasso.Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
imageView.setImageBitmap(bitmap);
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
Picasso.with(mContext).load(filePath).into(mTarget);
If you want to Use the image in lower quality, Just do this:
Picasso.with(mContext).load(filePath).centerInside().resize(YourWidth,YourHeight).into(imageview);
The answers simple. Store the image in a the devices file storage, pass the Uri of the image in storage to the Intent that is launching another activity, then fetch the Uri from said intent, and load from the file.
Your Bitmap object in MainActivity is marked as static, I doubt why is that necessary.
Making it static makes Android cannot GC it when you start Main2Activity,
A potential reason of why you are running out of memory.
Try to change it to private Bitmap bitmap. It might solves your problem.
But generally passing a bitmap object over an Activity is rare.
Since you mentioned that the image is uploaded, it is much better to get an image URL from server after you have uploaded it, and then use some Image Library such as Glide or Fresco to load it from the internet.
I'm now making a simple android app. It's just allow user to take an Photo and then show it.
When i test it in Virtual device, it's ok. But when i download apk to my android device, after i take a photo in Back camera, the app has stopped and return to main menu. Just problem in Back Camera.
In addition, in virtual device, after taking photo, the photo will show successfully. But it's empty in my phone
In MainActivity, i click on "Take Photo", it will start the camera and same my image to folder. Then it send the path of Photo to the next activity and show it.
This is my MainActivity
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_ID_IMAGE_CAPTURE = 100;
Button TakePhoto, InsertPhoto, Exit;
String mCurrentPhotoPath;
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName,".jpg",storageDir);
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TakePhoto = (Button) findViewById(R.id.button);
InsertPhoto = (Button) findViewById(R.id.button3);
Exit = (Button) findViewById(R.id.button2);
//Start Camera
TakePhoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
System.out.println(ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = Uri.fromFile(photoFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(intent,REQUEST_ID_IMAGE_CAPTURE);
}
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_ID_IMAGE_CAPTURE) {
if (resultCode == RESULT_OK) {
//Bitmap bp = (Bitmap)data.getExtras().get("data");
//ByteArrayOutputStream stream = new ByteArrayOutputStream();
// bp.compress(Bitmap.CompressFormat.PNG, 100, stream);
// byte[] images = stream.toByteArray();
File imgFile = new File(mCurrentPhotoPath);
if(imgFile.exists()){
System.out.println("This is file"+mCurrentPhotoPath.toString());
Intent Show = new Intent(MainActivity.this, ShowPhoto.class);
Show.putExtra("image",imgFile);
startActivity(Show);
}
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(this, "Action canceled", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Action Failed", Toast.LENGTH_LONG).show();
}
}
}
}
This is The ShowPhoto Activity
public class ShowPhoto extends Activity {
private LinearLayout Image;
Button Back,Next;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_photo);
Image=(LinearLayout)findViewById(R.id.linearLayout);
//Get Image from previous Activity
File image = (File)getIntent().getExtras().get("image");
Bitmap bmp = BitmapFactory.decodeFile(image.getAbsolutePath());
ImageView imageView = new ImageView(getApplicationContext());
imageView.setImageBitmap(Bitmap.createScaledBitmap(bmp, bmp.getWidth()*2, bmp.getHeight()*2, true));
Image.addView(imageView);
}
}
This is what's in my logcat when i run app
enter image description here
enter image description here
Use should ask for the permission at runtime and declare the permission in Manifest
if (ContextCompat.checkSelfPermission(getContext(),
Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity)
getContext(), Manifest.permission.CAMERA)) {
} else {
ActivityCompat.requestPermissions((Activity) getContext(),
new String[]{Manifest.permission.CAMERA},
MY_PERMISSIONS_REQUEST_CAMERA);
}
}
For your Manifest
<uses-permission android:name="android.permission.CAMERA"/>
I am trying to take a photo and then upload it to a database however each time I take a photo and try to post it I get an error :
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference.
Whenever I take a photo I never see the preview in the image view.
So what I assume is I am not adding the photo to the bitmap properly for the ImageUploadImageToServerFunction() to store the image. However it makes no sense to me for it not to work.
Heres the functions I have problems with.
Button CaptureImageFromCamera,UploadImageToServer;
ImageView ImageViewHolder;
EditText imageName;
ProgressDialog progressDialog ;
Intent intent ;
public static final int RequestPermissionCode = 1 ;
Bitmap bitmap;
boolean check = true;
String GetImageNameFromEditText;
String ImageNameFieldOnServer = "image_name" ;
String ImagePathFieldOnServer = "image_path" ;
String ImageUploadPathOnSever ="https://androidjsonblog.000webhostapp.com/capture_img_upload_to_server.php" ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.photo_activity);
CaptureImageFromCamera = (Button)findViewById(R.id.mapsPicButton);
ImageViewHolder = (ImageView)findViewById(R.id.imageView);
UploadImageToServer = (Button) findViewById(R.id.postPicBtn);
imageName = (EditText)findViewById(R.id.editText);
EnableRuntimePermissionToAccessCamera();
CaptureImageFromCamera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 7);
}
});
UploadImageToServer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
GetImageNameFromEditText = imageName.getText().toString();
ImageUploadToServerFunction();
}
});
}
// Start activity for result method to Set captured image on image view after click.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 7 && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri uri = data.getData();
try {
// Adding captured image in bitmap.
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
// adding captured image in imageview.
ImageViewHolder.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Upload captured image online on server function.
public void ImageUploadToServerFunction(){
ByteArrayOutputStream byteArrayOutputStreamObject ;
byteArrayOutputStreamObject = new ByteArrayOutputStream();
// Converting bitmap image to jpeg format, so by default image will upload in jpeg format.
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStreamObject);
byte[] byteArrayVar = byteArrayOutputStreamObject.toByteArray();
final String ConvertImage = Base64.encodeToString(byteArrayVar, Base64.DEFAULT);
class AsyncTaskUploadClass extends AsyncTask<Void,Void,String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog at image upload time.
progressDialog = ProgressDialog.show(Photo.this,"Image is Uploading","Please Wait",false,false);
}
#Override
protected void onPostExecute(String string1) {
super.onPostExecute(string1);
// Dismiss the progress dialog after done uploading.
progressDialog.dismiss();
// Printing uploading success message coming from server on android app.
Toast.makeText(Photo.this,string1,Toast.LENGTH_LONG).show();
// Setting image as transparent after done uploading.
ImageViewHolder.setImageResource(android.R.color.transparent);
}
#Override
protected String doInBackground(Void... params) {
ImageProcessClass imageProcessClass = new ImageProcessClass();
HashMap<String,String> HashMapParams = new HashMap<String,String>();
HashMapParams.put(ImageNameFieldOnServer, GetImageNameFromEditText);
HashMapParams.put(ImagePathFieldOnServer, ConvertImage);
String FinalData = imageProcessClass.ImageHttpRequest(ImageUploadPathOnSever, HashMapParams);
return FinalData;
}
}
AsyncTaskUploadClass AsyncTaskUploadClassOBJ = new AsyncTaskUploadClass();
AsyncTaskUploadClassOBJ.execute();
}
You can use this library to compress your image
compile 'id.zelory:compressor:2.1.0'
Here is this link
https://android-arsenal.com/details/1/3758
You can customize quality, height, weight etc .
compressedImageBitmap = new Compressor(this).compressToBitmap(actualImageFile);
compressedImageFile = new Compressor(this).compressToFile(actualImageFile);
If you want some customization:
compressedImage = new Compressor(this)
.setMaxWidth(640)
.setMaxHeight(480)
.setQuality(75)
.setCompressFormat(Bitmap.CompressFormat.WEBP)
.setDestinationDirectoryPath(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES).getAbsolutePath())
.compressToFile(actualImage);