Im trying to convert an audio file to byte array. where the audio file is fetch through attach file so its in an Uri
ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileInputStream fis;
try {
//FileInputStream = reading the file
fis = new FileInputStream(new File(audioFxUri.getPath()));
byte[] buf = new byte[1024];
int n;
while (-1 != (n = fis.read(buf)))
baos.write(buf, 0, n);
} catch (Exception e) {
e.printStackTrace();
}
byte[] bbytes = baos.toByteArray();
i followed that code from this one but once i ran. It gave me an error
W/System.err: java.io.FileNotFoundException: /external/audio/media/646818: open failed: ENOENT (No such file or directory)
I also tried to play it with a MediaPlayer and place Uri as its Source
MediaPlayer player = new MediaPlayer();
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource(AttachAudio.this,audioFxUri.toString());
player.prepare();
player.start();
to make sure if the audio file is working or not. Ps. it worked.
Is there something wrong im doing as to why it didnt convert to byte array?
The File Uri you have /external/audio/media/646818 is not an actual File Path, hence it is giving FileNotFoundException.
You need to get absolute path from the URI and then read the file accordingly.
You can either use below code:
public String getRealPathFromURI(Uri contentUri)
{
String[] proj = { MediaStore.Audio.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
or Refer this or this SO link for other options/methods
Related
I am storing video in internal storage but the saved video is not showing up in gallery. To see that first i have to open my file manager then come back to gallery. I stored the same video in android Q using media store but in
ContentResolver contentResolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "videoFileName");
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_MOVIES);
Uri finalUriPath = contentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, contentValues);
File sourceLocation = new File(finalUri.getPath());
InputStream in = new FileInputStream(sourceLocation);
FileOutputStream out = new FileOutputStream(String.valueOf(finalUriPath));
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
contentValues.clear();
contentValues.put(MediaStore.Video.Media.IS_PENDING, 0);
StatusShowerActivity.this.getContentResolver().update(finalUriPath, contentValues, null, null);
Toast.makeText(StatusShowerActivity.this, "Saved", Toast.LENGTH_SHORT).show();
Exception got from Catch in android 9
java.io.FileNotFoundException: null (Read-only file system)
I have tried many different ways or solutions and none of them seems to work. I have tried a few specific solutions which returns me a string and a context but i do not know what to do with the context even if I set the receiver of the context as null the app returns an error. What I want to do is, to be able to upload an image file for that I need the file path, a Uri or a content Uri gives me addresses like this
Content://something_something/304:
But i need something like this "
storage/sdcard/something_something/304.jpg"
how do it get that in KITKAT?
This is the code/method that I use for getting the path to the selected user Image.
public String getPath(Uri uri)
{
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
hope i provided enough details. Thank you for any help.
KITKAT does not provide the actual image path for security purpose.
if (Build.VERSION.SDK_INT >19){
InputStream imInputStream = getContentResolver().openInputStream(data.getData());
Bitmap bitmap = BitmapFactory.decodeStream(imInputStream);
String imagePath = saveGalaryImageOnKitkat(bitmap);
}
///After use you can delete the bitmap.
private String saveGalaryImageOnKitkat(Bitmap bitmap){
try{
File cacheDir;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
cacheDir=new File(Environment.getExternalStorageDirectory(),getResources().getString(R.string.app_name));
else
cacheDir=getExternalFilesDir(Environment.DIRECTORY_PICTURES);
if(!cacheDir.exists())
cacheDir.mkdirs();
String filename=java.lang.System.currentTimeMillis()+".png";
File file = new File(cacheDir, filename);
file.createNewFile();
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
return file.getAbsolutePath();
}catch(Exception e){
e.printStackTrace();
}
return null;
}
I've got an Image Uri, retrieved using the following:
public Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
This works just amazing for Intents that require an Image URI, etc (so I know for sure the URI is valid).
But now I want to save this Image URI to a file on the SDCARD. This is more difficult because the URI does not really point at a file on the SDCARD or the app.
Will I have to create a bitmap from the URI first, and then save the Bitmap on the SDCARD or is there a quicker way (preferable one that does not require the conversion to a bitmap first).
(I've had a look at this answer, but it returns file not found - https://stackoverflow.com/a/13133974/1683141)
The problem is that the Uri you've been given by Images.Media.insertImage() isn't to an image file, per se. It is to a database entry in the Gallery. So what you need to do is read the data from that Uri and write it out to a new file in the external storage using this answer https://stackoverflow.com/a/8664605/772095
This doesn't require creating a Bitmap, just duplicating the data linked to the Uri into a new file.
You can get the data using an InputStream using code like:
InputStream in = getContentResolver().openInputStream(imgUri);
Update
This is completely untested code, but you should be able to do something like this:
Uri imgUri = getImageUri(this, bitmap); // I'll assume this is a Context and bitmap is a Bitmap
final int chunkSize = 1024; // We'll read in one kB at a time
byte[] imageData = new byte[chunkSize];
try {
InputStream in = getContentResolver().openInputStream(imgUri);
OutputStream out = new FileOutputStream(file); // I'm assuming you already have the File object for where you're writing to
int bytesRead;
while ((bytesRead = in.read(imageData)) > 0) {
out.write(Arrays.copyOfRange(imageData, 0, Math.max(0, bytesRead)));
}
} catch (Exception ex) {
Log.e("Something went wrong.", ex);
} finally {
in.close();
out.close();
}
Official facebook App has a bug, when you try to share an image with share intent, the image gets deleted from the sdcard. This is the way you have to pass the image to facebook app using the uri of the image:
File myFile= new File(Environment.getExternalStorageDirectory(), "car.jpg");
Uri uri = Uri.fromFile(myFile);
i.putExtra(Intent.EXTRA_STREAM, uri);
Then, suppose that if i create a copy from the original myFile object, and i pass the uri of the copy to facebook app, then, my original image will not be deleted.
I tried with this code, but it doesn't work, the original image file is still getting deleted:
File myFile= new File(Environment.getExternalStorageDirectory(), "car.jpg");
File auxFile=myFile.getAbsoluteFile();
Uri uri = Uri.fromFile(auxFile);
Can someone tell me how to do a exact copy of a file that doesn't redirect to the original File?
Please check: Android file copy
The file is copied byte by byte so no reference to the old file is maintained.
Here, this should be able to create a copy of your file:
private void CopyFile() {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(<file path>);
out = new FileOutputStream(<output path>);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch(Exception e) {
Log.e("tag", e.getMessage());
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
I've read the Android SDK and I've found that the MediaRecorder class can take input from a Camera, Audio or other source and compress it. Through the setOutputFile method you can specify where you want the data to be stored (File or URI), but what if I want to store that data in a memory buffer and send it over a connection? Or process it before sending it? I mean is there a way not to create a file but to use a memory buffer only?
You can of course read the file in later and do whatever you want with it in the way of processing. Assuming that u holds the Uri to the resulting audio file, here is a code snippet that reads it into a byte array and then deletes the file.
String audioUri = u.getPath();
InputStream in = new BufferedInputStream(this.getContentResolver().openInputStream(u));
byte[] b = new byte[BUFSIZE];
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(mFileName/*mFilePath*/)));
int byteCnt = 0;
while (0 <= (byteCnt = in.read(b, 0, BUFSIZE)))
out.write(b, 0, byteCnt);
out.flush();
out.close();
// try to delete media file
try {
// Delete media file pointed to by Uri
new File(getRealPathFromURI(u)).delete();
} catch (Exception ex) {}
public String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}