Copy audio from uri to specific directory - android

I get a song from the user's library like this:
Intent selectIntent = new Intent(Intent.ACTION_GET_CONTENT);
selectIntent.setType("audio/*");
startActivityForResult(selectIntent, SONG_REQUEST_CODE);
and retrieve it like this:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SONG_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
if ((data != null) && (data.getData()!=null)) {
song = data.getData(); //song is an Uri defined previuosly
}
}
}
I need to import it into a folder I defined and created like this:
final File dir2 = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Chords/Imported Audio");
dir2.mkdirs();
I tried like this as suggested by Commonsware but the file is not created:
private void importAudio(Uri uri) {
String source = uri.getPath();
String destinationFile = dir2 + File.separator + songName;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(source));
bos = new BufferedOutputStream(new FileOutputStream(destinationFile, false));
byte[] buf = new byte[1024];
bis.read(buf);
do {
bos.write(buf);
} while (bis.read(buf) != -1);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bis != null) bis.close();
if (bos != null) bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The file is not there though. How can I fix this?

The file is not there though
Most likely, you have a stack trace in LogCat. song.getPath() is unlikely to be useful. song probably does not have a file scheme, and so getPath() is meaningless.
Use ContentResolver and openInputStream() to get an InputStream on song, then use that InputStream to copy the content.
Also:
Make sure that you have runtime permissions set up properly
Index the destination file so that it can be seen from more apps plus desktop OSes

Related

Android Studio get File from Gallery Intent

Short answer is it possible to get original file from Gallery request,and if it possible how can i do it? This code doesn't work for me.
Uri uri = data.getData();
File file = new File(uri.getPath());
And the long Answer)):
I use this code to make gallery intent
addGallery.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, GALLERY_IMAGE_REQUEST);
}
});
In mu onActivityResult i use this code
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK)
{
switch (requestCode)
{
case GALLERY_IMAGE_REQUEST:
if (data != null)
{
try
{
Uri uri = data.getData();
File file = new File(uri.getPath());
FileInputStream inputStream = new FileInputStream(file);
bitmap = BitmapFactory.decodeStream(inputStream);
imageView.setImageBitmap(bitmap);
inputStream.close();
} catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
And i cant get file.
The same code with getting bitmap from data works well but i need to get exactly file from gallery but not only Uri or Bitmap.
try
{
Uri uri = data.getData();
InputStream imageStream = getContentResolver().openInputStream(uri);
final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
imageView.setImageBitmap(selectedImage);
imageStream.close();
} catch (Exception e)
{
e.printStackTrace();
}
If you want to import a picture from gallery into your app (in a case your app own it), you need to copy it to your app data folder.
in your onActivityResult():
if (requestCode == REQUEST_TAKE_PHOTO_FROM_GALLERY && resultCode == RESULT_OK) {
try {
// Creating file
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
Log.d(TAG, "Error occurred while creating the file");
}
InputStream inputStream = getActivity().getContentResolver().openInputStream(data.getData());
FileOutputStream fileOutputStream = new FileOutputStream(photoFile);
// Copying
copyStream(inputStream, fileOutputStream);
fileOutputStream.close();
inputStream.close();
} catch (Exception e) {
Log.d(TAG, "onActivityResult: " + e.toString());
}
}
Creating the file method:
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 = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
Copy method:
public static void copyStream(InputStream input, OutputStream output) throws IOException {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
}

How to convert the uri to inputStream data and upload the stream data into server?

I am working the task in picking the file from the gallery and upload the picked file to the server.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == PICK_FILE_REQUEST) {
if (data != null) {
//no data present
Uri uri = data.getData();
String filePath = data.getData().getPath();
// String path = uri.getPath();
file = new File(filePath);
String name = getContentName(getContentResolver(), uri);
try {
InputStream inStream = getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
linearLayout.setOrientation(LinearLayout.VERTICAL);
ImageView imageView = new ImageView(this);
imageView.setImageBitmap(bitmap);
attachFile.addView(imageView);
TextView textView = new TextView(this);
textView.setText(name);
attachFile.addView(textView);
return;
}
}
}
I poicked the file by using intent
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//intent.addFlags(ST)
startActivityForResult(Intent.createChooser(intent, "Choose File to Upload.."), PICK_FILE_REQUEST);
My issue is the uri data is converted the inputStream but i am using the ion library in that inputstream files cannot be uploaded to server.
How to convert the inputStream to outputstream to save in getCacheDir().I refered this site How to get the file path for the picked files from the external storage in android?
Please help me how to upload the InputStream data into the ion library.
In the below code i have passed the uri into the inputstream and and then crated the file and inputStream data are written in outputstream.
This works 100% try this method.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == PICK_FILE_REQUEST) if (data != null) {
//no data present
Uri uri = data.getData();
String filePath = data.getData().getPath();
String name = getContentName(getContentResolver(), uri);
File file = new File(getCacheDir(),name);
int maxBufferSize = 1 * 1024 * 1024;
try {
InputStream inputStream = getContentResolver().openInputStream(uri);
Log.e("InputStream Size","Size " + inputStream);
int bytesAvailable = inputStream.available();
// int bufferSize = 1024;
int bufferSize = Math.min(bytesAvailable, maxBufferSize);
final byte[] buffers = new byte[bufferSize];
FileOutputStream outputStream = new FileOutputStream(file);
int read = 0;
while ((read = inputStream.read(buffers)) != -1) {
outputStream.write(buffers, 0, read);
}
Log.e("File Size","Size " + file.length());
inputStream.close();
outputStream.close();
file.getPath();
Log.e("File Path","Path " + file.getPath());
file.length();
Log.e("File Size","Size " + file.length());
if(file.length() > 0){
attachementImage.setVisibility(View.INVISIBLE);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
imageView.setImageBitmap(bitmap);
attachFile.addView(imageView);
attachFile.addView(textView);
return;
}
}
}

Need to select a file and Save it in given folder in android

According to my code that I can select a file after that how can I save that selected file in given directory?
Here I captured Uri but I could not save that audio file in Specific folder.
Where can be the issue?Any mistake which I have done while writing outputStream?
public class Upload extends AppCompatActivity {
File folder;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.splashscreen);
/* New Handler to start the Menu-Activity
* and close this Splash-Screen after some seconds.*/
folder = new File(Environment.getExternalStorageDirectory() + "/Audios");
File folder1 = new File(Environment.getExternalStorageDirectory() + "/");
if (!folder.exists()) {
folder.mkdir();
}
for (File f : folder.listFiles()) {
if (f.isFile()) {
String name = f.getName();
// System.out.print(name);
Toast.makeText(getApplicationContext(), name, Toast.LENGTH_SHORT).show();
}
// Do your stuff
}
Intent intent_upload = new Intent();
intent_upload.setType("audio/*");
intent_upload.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent_upload, 1);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (resultCode == RESULT_OK) {
FileInputStream fileInputStream = null;
//the selected audio.
Uri uri = data.getData();
Toast.makeText(getApplicationContext(), uri.getPath(), Toast.LENGTH_SHORT).show();
File test = new File(uri.getPath());
try {
fileInputStream = new FileInputStream(test);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
FileOutputStream outputStream = new FileOutputStream(folder, true);
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = fileInputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
super.onActivityResult(requestCode, resultCode, data);
}
}
This does not "select a file". It allows the user to choose a piece of content.
In onActivityResult(), if the result code is RESULT_OK, the Intent will have a Uri pointing to the selected piece of content. Use ContentResolver and openInputStream() to get an InputStream on that content. From there, do what you need to do, such as open a FileOutputStream to some file and then copy the bytes from the InputStream to the OutputStream.
BTW, ACTION_GET_CONTENT does not take a Uri as input. Replace setDataAndType() with setType().

Android decode and save audio stream returned from intent

I would like the user to be able to import custom sounds in my app to change the default sounds. I already have this functionality working for bitmaps, but I would like to extend to sounds as well. The crucial step I am missing is audio decoding. I do not know what format the sound will come in, so I need to decode the audio before saving it to internal storage. For bitmaps this was accomplished by the bitmapfactory and the bitmap object, but I cannot find an analogous service for audio. This is the code that I have so far. The bitmap portions work, but the audio parts are incomplete.:
private void retrievepicture() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, 1);//retrieve picture has a code of 1
}
private void retrievesound() {
Intent intent = new Intent();
intent.setType("audio/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, 2);//retrieve sound has a code of 2
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
usingintents = false;
if (requestCode == 1 && resultCode == Activity.RESULT_OK)
try {
InputStream stream = getContentResolver().openInputStream(
data.getData());
Bitmap bitmap = BitmapFactory.decodeStream(stream);
stream.close();
File deletefile = new File(savepath);
System.out.println(String.format("Replacing file %s",deletefile.getPath()));
deletefile.delete();
saveImageToInternalStorage(bitmap,savepath);
bitmap.recycle();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (requestCode == 2 && resultCode == Activity.RESULT_OK)
{
//The code for saving audio would go here
InputStream stream = getContentResolver().openInputStream(
data.getData());
}
super.onActivityResult(requestCode, resultCode, data);
}
public boolean saveImageToInternalStorage(Bitmap image, String filepath) {
try {
// Use the compress method on the Bitmap object to write image to
// the OutputStream
FileOutputStream fos = new FileOutputStream(filepath);
// Writing the bitmap to the output stream
if(image.getWidth() >480 || image.getHeight() > 480)
image = Bitmap.createScaledBitmap(image, 480, 480, false);
image.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
I got it to work by getting the file path from the intent, and copying the file as it is instead of decoding it. All the files that I looked at did not have a clear format(they weren't .wav or .mp3, there was no file type listed)
This is what my code looks like inside the onActivityResult for the sound portion
InputStream stream = getContentResolver().openInputStream(data.getData());
String FilePath = data.getData().getPath();
File original = new File(FilePath);
File deletefile = new File(savepath);
String newpath = deletefile.getParent() + "/" + original.getName();
deletefile.delete();
File newfile = new File(newpath);
FileOutputStream out = new FileOutputStream(newfile);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.close();
stream.close();
Kotlin 1.2
fun saveAudio(myAudio:Intent?):String {//TURN ON PERSMISSIONS ON THE EMULATOR IN SETTINGS
//var bytes = ByteArrayOutputStream()
val audioURI = myAudio!!.data
try {
val audioDirectory = File(
(Environment.getExternalStorageDirectory()).toString() + AUDIO_DIRECTORY)
val out = File(audioDirectory, ("fullAudio" + ".mp3"))
if (!audioDirectory.exists()){
audioDirectory.mkdirs()
}
out.createNewFile()//cressh
val file = File(audioURI.path)
val fo = FileOutputStream(out)
//val input = FileInputStream(f)
var stream = contentResolver.openInputStream(audioURI)
var read = 0
fo.write(stream.readBytes(1024))
MediaScannerConnection.scanFile(this,
arrayOf(file.getPath()),
arrayOf("audio/mpeg"),null)
fo.close()
return file.absolutePath
}catch (e1: IOException){
e1.printStackTrace()
}
return ""
}

Capture a video and store it at a specific location rather than a default location

I want to capture video and store video at specific location other than default location.
I know there is a method with MediaStore called setOutPutFile("String Location").
But it is not working properly.
I have seen many examples and performed but it stores video in default location only. Can someone help me solve this problem?
Do in this way :
Globally declare it
public static final int TAKE_PICTURE=0;
and then
Intent photoPickerIntent= new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
startActivityForResult(Intent.createChooser(photoPickerIntent,"Take Video"),TAKE_VIDEO);
In OnActivityResult Handle in this way:
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == RESULT_OK)
{
if(requestCode==TAKE_VIDEO)
{
try
{
Log.e("videopath","videopath");
AssetFileDescriptor videoAsset = getContentResolver().openAssetFileDescriptor(data.getData(), "r");
FileInputStream fis = videoAsset.createInputStream();
File root=new File(Environment.getExternalStorageDirectory(),"Directory Name");
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();
}
}
}
Use below permissions:
<uses-permission android:name="android.permission.RECORD_VIDEO"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
I wasn't happy with any of the solutions provided here. Here's an extremely simple solution that will save the video in folder of your choice.
private static final int REQUEST_VIDEO_CAPTURE = 300;
private Uri videoUri;
private void dispatchVideoIntent(){
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
File outputFile = new File("your file path goes here");
videoUri = Uri.fromFile(outputFile);
takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_VIDEO_CAPTURE && resultCode == RESULT_OK && videoUri != null) {
// do what you want with videoUri
}
}
The answer given by abhi here is correct, but i am writing a new answer to make it more easy and simple to other users.
To record a video, write this code in your onCreate method or on button click where you want to start the video recording
private static final int ACTION_TAKE_VIDEO = 3;
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
startActivityForResult(takeVideoIntent, ACTION_TAKE_VIDEO);
This code will start video recording.
Now below in your code after the onCreate method you need to override a method which name is onActivityResult.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK)
{
try
{
AssetFileDescriptor videoAsset = getContentResolver().openAssetFileDescriptor(data.getData(), "r");
FileInputStream fis = videoAsset.createInputStream();
File root=new File(Environment.getExternalStorageDirectory(),"/RecordVideo/"); //you can replace RecordVideo by the specific folder where you want to save the video
if (!root.exists()) {
System.out.println("No directory");
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();
}
}
}
Replace "RecordVideo" with the specific folder where you want to the video file on your sd card. You can also use any existing folder or directory name here.
Thanks

Categories

Resources