How to save audio files and send them - java

I'm trying to save an audio file to send it to whatsapp, but i am unable to save it on external storage. I am not getting where am I making mistakes.
I am using this code:
FileOutputStream outputStream;
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_RINGTONES), "FUNG");
if (!file.mkdirs()) {}
try {
outputStream = new FileOutputStream(file);
outputStream.write(R.raw.badum2);
outputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Intent shareIntent = new Intent(Intent.ACTION_SEND);
Uri uri = Uri.parse(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_RINGTONES) + "/FUNG/badum2.m4a");
shareIntent.setType("audio/m4a");
shareIntent.setPackage("com.whatsapp");
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(shareIntent);
When the file is sent to WhatsApp, it shows error like:
"fail to share, please try again"
I don't see the audio file in directory, so I guess the error is that I am making some mistakes in saving audio files on external storage.
Please help me in solving this.

I see multiple problems:
(1) if (!file.mkdirs()) {} creates a directory at the path of file, later you use that directory to open an output stream, which of course does not work.
Solution:
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_RINGTONES), "FUNG/badum2.m4a"); // assumed target file
if (!file.getParentFile().mkdirs() && !file.getParentFile().isDirectory()) {
// Abort! Directory could not be created!
}
(2) outputStream.write(R.raw.badum2); will write the int value referring
to your resource, not the resource itself.
Solution:
Use InputStream in = ctx.getResources().openRawResource(R.raw.badum2); where ctx is a Context instance (e.g. your Activity) and write its content to the file.
try {
outputStream = new FileOutputStream(file);
try {
InputStream in = ctx.getResources().openRawResource(R.raw.badum2);
byte[] buffer = new byte[4096];
int read;
while ((read = in.read(buffer, 0, buffer.length) >= 0) {
outputStream.write(buffer, 0, read);
}
in.close();
} catch (IOException ex) {
ex.printStackTrace();
}
outputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

Related

Unable to write to file - why?

I am attempting to save to long term file storage in android as well as create a new file in the process. This code keeps crashing with minimal helpful logcat.
Thanks.
public void save (String text) {
FileOutputStream fos = null;
try {
fos = openFileOutput("logfile.txt", MODE_PRIVATE);
fos.write(text.getBytes());
} catch (FileNotFoundException e)
{} catch (IOException e) {
e.printStackTrace();
} finally {
if(fos != null)
{
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I expect it to create a file called logfile.txt and print text to it but instead it crashes.
Try something alike this, in order to get a FileOutputStream from a File in tmp / private storage:
// File file = File.createTempFile("logfile", ".txt");
File file = new File(getFilesDir(), "logfile.txt");
FileOutputStream fos = new FileOutputStream(file);
The resulting path should be /data/data/tld.domain.package/files/logfile.txt.
file.getAbsolutePath() has the value.
See Save a file on internal storage.

Error when connecting to FTP using apache commons

I am using apache common library for connecting to FTP with Android app.
Now I want to upload a file from internal storage to FTP server and I get this reply from getReplyString() method.
And I get this msg
553 Can't open that file: Permission denied
//Write file to the internal storage
String path = "/sdcard/";
File file = new File(path, fileName);
FileOutputStream stream = null;
try {
stream = new FileOutputStream(file);
stream.write(jsonObject.toString().getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// Read the file from resources folder.
try {
File file1 = new File(path, fileName);
Log.d("path",file1.getPath());
BufferedInputStream in = new BufferedInputStream (new FileInputStream (file1.getPath()));
client.connect(FTPHost);
client.login(FTPUserName, FTPPassword);
client.enterLocalPassiveMode();
client.setFileType(FTP.BINARY_FILE_TYPE);
// Store file to server
Log.d("reply",client.getReplyString());
boolean res = client.storeFile("/"+fileName, in);
Log.d("reply",client.getReplyString());
Log.d("result",res+"");
client.logout();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}

Android: Saving .png from URL into app internal storage

I'm relatively new to android, and I'm trying to modify an android app such that it downloads a profile picture (preferably in PNG) from a URL, and saves it in the com.companyName.AppName.whatever/files. It should be noted that the app was initially created in Unity, and just built and exported.
Here's my initial code:
URL url = null;
try {
url = new URL(playerDO.getProfileURL());
} catch (MalformedURLException e) {
e.printStackTrace();
}
InputStream input = null;
try {
input = url.openStream();
} catch (IOException e) {
e.printStackTrace();
}
String fileName = playerDO.getId() + ".png";
FileOutputStream outputStream = null;
try {
outputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
byte[] buffer = new byte[256];
int bytesRead = 0;
while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
outputStream.write(buffer, 0, bytesRead);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
EDIT: Here's my other code, as suggested by #Ashutosh Sagar
InputStream input = null;
Bitmap image = null;
try {
input = url.openStream();
image = BitmapFactory.decodeStream(input);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
String fileName = playerDO.getId() + ".png";
FileOutputStream outputStream = null;
File myDir = getFilesDir();
try {
Log.wtf("DIRECTORY", myDir.toString());
File imageFile = new File(myDir, fileName);
if (!imageFile.exists()){
imageFile.createNewFile();
Log.wtf("ANDROID NATIVE MSG: WARN!", "File does not exist. Writing to: " + imageFile.toString());
}
outputStream = new FileOutputStream(imageFile, false);
image.compress(Bitmap.CompressFormat.PNG, 90, outputStream);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
Log.wtf("AWWW CRAP", e.toString());
}
}
(It doesn't write either).
Unfortunately, I've had several problems with this. My primary issue is that when it (on the cases that it does) runs, it actually doesn't save anything. I'll go and check com.companyName.AppName.whatever/files directory only to find no such .png file. I will also need it to overwrite any existing files of the same name, which is hard to check when it doesn't work.
My secondary issue is that it fails to take into account delays in internet connection. Although I've put in enough try-catch clauses to stop it from crashing (as it used to), the end result is that it also doesn't save.
How can I improve upon this? Anything I'm missing?
EDIT:
Printing out the directory reveals it should be in:
/data/user/0/com.appName/files/5965e9e4a0f0463853016e2b.png
However, using ES File explorer, the only thing remotely close to that is
emulated/0/Android/data/com.appName/files/
Are they the same directory?
try this first get bitmap image from url
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(url).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.d("Error", e.getStackTrace().toString());
}
and to save bitmap image please check the ans of GoCrazy
Try this
void getImage(String string_url)
{
//Generate Bitmap from URL
URL url_value = new URL(string_url);
Bitmap image =
BitmapFactory.decodeStream(url_value.openConnection().getInputStream());
//Export File to local Directory
OutputStream stream = new FileOutputStream("path/file_name.png");
/* Write bitmap to file using JPEG or PNG and 80% quality hint for JPEG. */
bitmap.compress(CompressFormat.PNG, 80, stream);
stream.close();
}

Clearing File content in Internal Storage on Android

I have a logging class for writing into a file in the app's internal storage space. Whenever the log file exceeds the size limit. For clearing the contents, I am closing the current FileOutputStream and creating a new stream with Write mode and closing it. Is there a way better way for accomplishing this:
public final void clearLog() throws IOException {
synchronized (this) {
FileOutputStream fos = null;
try {
// close the current log file stream
mFileOutputStream.close();
// create a stream in write mode
fos = mContext.openFileOutput(
LOG_FILE_NAME, Context.MODE_PRIVATE);
fos.close();
// create a new log file in append mode
createLogFile();
} catch (IOException ex) {
Log.e(THIS_FILE,
"Failed to clear log file:" + ex.getMessage());
} finally {
if (fos != null) {
fos.close();
}
}
}
}
You could also overwrite your file with nothing.
UPDATE:
There seems to be a better option with getFilesDir () Have a look at this question How to delete internal storage file in android?
Write empty data into file:
String string1 = "";
FileOutputStream fos ;
try {
fos = new FileOutputStream("/sdcard/filename.txt", false);
FileWriter fWriter;
try {
fWriter = new FileWriter(fos.getFD());
fWriter.write(string1);
fWriter.flush();
fWriter.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
fos.getFD().sync();
fos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
In this code:
fos = new FileOutputStream("/sdcard/filename.txt", false);
FALSE - for write new content. If TRUE - text append to existing file.
public void writetofile(String text){ // text is a string to be saved
try {
FileOutputStream fileout=openFileOutput("mytextfile.txt", false); //false will set the append mode to false
OutputStreamWriter outputWriter=new OutputStreamWriter(fileout);
outputWriter.write(text);
outputWriter.close();
readfromfile();
Toast.makeText(getApplicationContext(), "file saved successfully",
Toast.LENGTH_LONG).show();
}catch (Exception e) {
e.printStackTrace();
}
}

How to move/rename file from internal app storage to external storage on Android?

I am downloading files from the internet and saving the streaming data to a temp file in my app's internal storage given by getFilesDir().
Once the download is complete, I need to move the temp file to my download directory on External Memory (usually an SD Card). For some reason though, File.renameTo() isn't working for this. I'm guessing there's a problem because it's two separate file systems, but I can still download directly to the SD Card and the file URIs are correct.
Is there another simple and quick way to transfer that file from internal memory to external or do I have to do a byte stream copy and delete the original?
To copy files from internal memory to SD card and vice-versa using following piece of code:
public static void copyFile(File src, File dst) throws IOException
{
FileChannel inChannel = new FileInputStream(src).getChannel();
FileChannel outChannel = new FileOutputStream(dst).getChannel();
try
{
inChannel.transferTo(0, inChannel.size(), outChannel);
}
finally
{
if (inChannel != null)
inChannel.close();
if (outChannel != null)
outChannel.close();
}
}
And - it works...
Internal and external memory is two different file systems. Therefore renameTo() fails.
You will have to copy the file and delete the original
After you copy the file (as #barmaley's great answer shows), don't forget to expose it to the device's gallery, so the user can view it later.
The reason why it has to be done manually is that
Android runs a full media scan only on reboot and when (re)mounting
the SD card
(as this guide shows).
The easier way to do this is by sending a broadcast for the scanning to be invoked:
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(outputFile));
context.sendBroadcast(intent);
And voila! You can now view your file in the device's gallery.
An alternative to the copying using your own function is to use Apache's library's class "FileUtils" , in the function called copyFile :
FileUtils.copyFile(src, dst, true);
Did some trivial modifications to #barmaley's code
public boolean copyFile(File src, File dst) {
boolean returnValue = true;
FileChannel inChannel = null, outChannel = null;
try {
inChannel = new FileInputStream(src).getChannel();
outChannel = new FileOutputStream(dst).getChannel();
} catch (FileNotFoundException fnfe) {
Log.d(logtag, "inChannel/outChannel FileNotFoundException");
fnfe.printStackTrace();
return false;
}
try {
inChannel.transferTo(0, inChannel.size(), outChannel);
} catch (IllegalArgumentException iae) {
Log.d(logtag, "TransferTo IllegalArgumentException");
iae.printStackTrace();
returnValue = false;
} catch (NonReadableChannelException nrce) {
Log.d(logtag, "TransferTo NonReadableChannelException");
nrce.printStackTrace();
returnValue = false;
} catch (NonWritableChannelException nwce) {
Log.d(logtag, "TransferTo NonWritableChannelException");
nwce.printStackTrace();
returnValue = false;
} catch (ClosedByInterruptException cie) {
Log.d(logtag, "TransferTo ClosedByInterruptException");
cie.printStackTrace();
returnValue = false;
} catch (AsynchronousCloseException ace) {
Log.d(logtag, "TransferTo AsynchronousCloseException");
ace.printStackTrace();
returnValue = false;
} catch (ClosedChannelException cce) {
Log.d(logtag, "TransferTo ClosedChannelException");
cce.printStackTrace();
returnValue = false;
} catch (IOException ioe) {
Log.d(logtag, "TransferTo IOException");
ioe.printStackTrace();
returnValue = false;
} finally {
if (inChannel != null)
try {
inChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
if (outChannel != null)
try {
outChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return returnValue;
}
Picture that:
This is internal path : pathInternal
And this is external path :
pathExternal
Try with this code:
public void moveIn (String pathInternal, String pathExternal) {
File fInternal = new File (pathInternal);
File fExternal = new File (pathExternal);
if (fInternal.exists()) {
fInternal.renameTo(fExternal);
}
}
You can do it using operations with byte[]
define in your class:
public static final String DATA_PATH =
Environment.getExternalStorageDirectory().toString() + "/MyAppName/";
then:
AssetManager assetManager = context.getAssets();
InputStream in = assetManager.open("data/file.txt");
OutputStream out = new FileOutputStream(DATA_PATH + "data/file.txt");
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
For Move file best way is Renaming it's path with different path and name
example:
File from = new File(Environment.getExternalStorage().getAbsolutePath()+"/kaic1/imagem.jpg");
File to = new File(Environment.getExternalStorage().getAbsolutePath()+"/kaic2/imagem.jpg");
from.renameTo(to);

Categories

Resources