I am trying to add the Image from the the Internal Memory.
I am trying to use this code for that
ImageView message_image=(ImageView)v.findViewById(R.id.message_image);
File imgFile = new File(img_db);
Log.e("img_db",img_db+"------------->");
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
message_image.setImageBitmap(myBitmap);
}
here img_db is my path that i am getting from my Sqlite table.when i log it i get the fath like this
E/img_db: file:///storage/sdcard0/download/img11024FILE.jpg------------->
I have already given this permission in my manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
For downloading image and save to the phone i am using this code
public String downloadFile(String url_i_) {
try {
URL url
= new URL(url_i_);
Log.e("url_fetch--->img", String.valueOf(url));
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
// connect
urlConnection.connect();
// set the path where we want to save the file
SDCardRoot = Environment.getExternalStorageDirectory();
// create a new file, to save the downloaded file
rand = new External_function().getnRandom();
file = new File(SDCardRoot, "/download/img" + rand+".jpg");
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();
// this is the total size of the file which we are downloading
totalSize = urlConnection.getContentLength();
// create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
// update the progressbar //
float per = ((float) downloadedSize / totalSize) * 100;
/*cur_val.setText("Downloading.... " + downloadedSize
+ "KB / " + totalSize + "KB (" + (int) per
+ "%)");*/
String i = "Downloading.... " + downloadedSize
+ "KB / " + totalSize + "KB (" + (int) per
+ "%)";
}
fileOutput.close();
file = new File(Environment.getExternalStorageDirectory() + "/download/img" + rand+".jpg"); // set your audio path
file_path= String.valueOf(Uri.fromFile(file));
} catch (final Exception e) {
Log.e("////////////////file", String.valueOf(e));
}
return file_path;
}
And inside my service class when i get the image path in return then i store it inside my sqlite table like this
String img = socketOperator.downloadFile(event_img);
localstoragehandler.insert(id, msg_user_by, msg_read_by, msg_content, msg_grp_id, msg_sent_time,type,event_time,event_lat,event_log,event_name,event_address,img);
I checked the path with image and id are same.I try this but really don't know what I am doing wrong.
You need this permission:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
READ_EXTERNAL_STORAGE not WRITE_EXTERNAL_STORAGE
#CommonsWare has already answered this. Try changing how you get your path. (Original Answer)
Why would this happen?
Because the path to external storage has changed over the years, which is why you should have never hard-coded the path in the first place.
how can I get the path directory in a more "formal and right" way
instead of hardcoding the path?
Use Environment.getExternalStorageDirectory().
On your test environment, /sdcard is a symlink or hardlink to /storage/sdcard0, as set up by the device manufacturer. However, there is no guarantee that all devices will have such an /sdcard symlink.
If that does not help you. This definitely will: Reading from internal storage.
UPDATE
Please look for all usages of this "/download/img" ...
You are missing a "/" ... Replace it with "/download/img/"
Related
i have create a modul to download file from server to my android apps like this
#Override
protected String doInBackground(String... f_url) {
int count;
try {
URL url = new URL(f_url[0]);
URLConnection connection = url.openConnection();
connection.connect();
// getting file length
int lengthOfFile = connection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
String timestamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
//Extract file name from URL
fileName = f_url[0].substring(f_url[0].lastIndexOf('/') + 1, f_url[0].length());
//Append timestamp to file name
fileName = timestamp + "_" + fileName;
//External directory path to save file
folder = Environment.getExternalStorageDirectory() + File.separator + "simpel/";
//Create androiddeft folder if it does not exist
File directory = new File(folder);
if (!directory.exists()) {
directory.mkdirs();
}
// Output stream to write file
OutputStream output = new FileOutputStream(folder + fileName);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress("" + (int) ((total * 100) / lengthOfFile));
Log.d(TAG, "Progress: " + (int) ((total * 100) / lengthOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
return "Downloaded at: " + folder + fileName;
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return "Something went wrong";
}
but when i try to download, i always get error like this
E/Error::
/storage/emulated/0/simpel/2019.07.06.18.57.51_REGISTER_TILANG.xlsx
(Permission denied)
even though I have added this to my manifest
android.permission.READ_EXTERNAL_STORAGE
android.permission.WRITE_EXTERNAL_STORAGE
i use this libary:
implementation 'pub.devrel:easypermissions:0.2.0'
I know it's been more than a year but I hope this helps someone.
I worked with your code now and I found out the mistake you might have made.
You might have added these android.permission.READ_EXTERNAL_STORAGE android.permission.WRITE_EXTERNAL_STORAGE to your manifest.xml but you need to ask for the permission in your code.
Even using the library (same I used) implementation 'pub.devrel:easypermissions:0.2.0' it seems you didn't check for both READ and WRITE permissions (something like this):
private static final int WRITE_REQUEST_CODE = 1;
if (EasyPermissions.hasPermissions(DownloadActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
//your asyncTask to download
downloadFile.execute(url);
} else {
//If permission has no be granted, request
EasyPermissions.requestPermissions(DownloadActivity.this, "This app needs access to your file storage" , WRITE_REQUEST_CODE, Manifest.permission.READ_EXTERNAL_STORAGE);
}
Notice that in the code above, only WRITE permission was checked. If there isn't, then READ permission was requested (which is kind of contradictory). The correct would be checking for both permissions then if either of them has not been granted, the system will request for thr two. Compare the following code:
private static final int REQUEST_CODE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
if (EasyPermissions.hasPermissions(DownloadActivity.this, PERMISSIONS_STORAGE)) {
//your asyncTask to download
downloadFile.execute(url);
} else {
//If permission has not been granted, request
EasyPermissions.requestPermissions(DownloadActivity.this, "This app needs access to your file storage", REQUEST_CODE, PERMISSIONS_STORAGE);
}
I had similarcode as yours and had the same error, I fixed it this way.
I'm trying to download files from Firebase storage. But when I download it, it's giving some files with .bin extension. But I want to get the original file name.
Here is my code.
try {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
int lenghtOfFile = conection.getContentLength();
InputStream input = new BufferedInputStream(url.openStream(),
8192);
OutputStream output = new FileOutputStream(Environment
.getExternalStorageDirectory().toString()
+"/Download/"+ URLUtil.guessFileName(f_url[0], null, null));
Log.i("File name",URLUtil.guessFileName(f_url[0], null, null));
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
In there f_url is the firebase download url. Thank you.
The built in way of doing this is actually quite straightforward:
StorageReference reference = storage.getReferenceFromUrl("https://firebasestorage.googleapis.com/...");
// Assuming that the file is "name.extension" in Storage
String name = reference.getName().split(".")[0]
String extension = reference.getName().split(".")[1]
File localFile = File.createTempFile(name, extension);
reference.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
// Local temp file has been created
}
});
But if you don't want to do it the easy way...
Let's take a brief look at how you're naming your file: URLUtil.guessFileName(f_url[0], null, null)
According to the URLUtil.guessFileName() docs: "Guesses canonical filename that a download would have, using the URL and contentDisposition. File extension, if not defined, is added based on the mimetype."
I'm assuming that your f_url[0] is a file with no extension, and since you provide no contentDisposition or mimetype as arguments to guessFileName, there's no way it can possibly know what file extension you want.
You can get the contentDisposition and contentType (same as mimetype) from Storage Metadata, and if you name your file in Storage with an extension, you should be good to go.
my code works fine, it downloads image to sd card, however , i get this warning where i defined my sd card path "Do not hardcode "/sdcard/"; use Environment.getExternalStorageDirectory().getPath() instead"
#Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream("/sdcard/.temp");//.temp is the image file name
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
}
return null;
}
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC", progress[0]);
}
the problem is, if i use the suggested solution, then i won't be able to give my downloaded file a new name (".temp")
When working with files and directories, it's better to work with File objects rather than with strings. Here's how you can address the warning:
File dir = Environment.getExternalStorageDirectory();
File tmpFile = new File(dir, ".temp");
OutputStream output = new FileOutputStream(tmpFile);
That creates a File object that points to a file named ".temp" in the environment's external storage directory. It then opens it for writing using a different constructor of the FileOutputStream class.
If you need the file path as a string instead (say, for printing), you can do that too:
String tmpFileString = tmpFile.getPath();
Or if you decide to use the java.nio API in the future and need a Path object:
Path tmpFilePath = tmpFile.toPath();
I have one requirement in my Android application. I need to download and save file in specific folder of SD card programmatically. I have developed source code, which is
String DownloadUrl = "http://myexample.com/android/";
String fileName = "myclock_db.db";
DownloadDatabase(DownloadUrl,fileName);
// and the method is
public void DownloadDatabase(String DownloadUrl, String fileName) {
try {
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File(root.getAbsolutePath() + "/myclock/databases");
if(dir.exists() == false){
dir.mkdirs();
}
URL url = new URL("http://myexample.com/android/");
File file = new File(dir,fileName);
long startTime = System.currentTimeMillis();
Log.d("DownloadManager" , "download url:" +url);
Log.d("DownloadManager" , "download file name:" + fileName);
URLConnection uconn = url.openConnection();
uconn.setReadTimeout(TIMEOUT_CONNECTION);
uconn.setConnectTimeout(TIMEOUT_SOCKET);
InputStream is = uconn.getInputStream();
BufferedInputStream bufferinstream = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(5000);
int current = 0;
while((current = bufferinstream.read()) != -1){
baf.append((byte) current);
}
FileOutputStream fos = new FileOutputStream( file);
fos.write(baf.toByteArray());
fos.flush();
fos.close();
Log.d("DownloadManager" , "download ready in" + ((System.currentTimeMillis() - startTime)/1000) + "sec");
int dotindex = fileName.lastIndexOf('.');
if(dotindex>=0){
fileName = fileName.substring(0,dotindex);
}
catch(IOException e) {
Log.d("DownloadManager" , "Error:" + e);
}
}
Now the issue is only empty file with filename myclock_db.db is saving in the path. but I need to download and save content of file in the specific folder. Tried several ways to get the file download, but I can't.
Your download URL is not a link to any file. It's a directory. Make sure its a file and exists. Also check your logcat window for error logs. One more suggestion, its always better to do a printStackTrace() in catch blocks instead of Logs. Its gives a more detailed view of the error.
Change this line:
URL url = new URL("http://myexample.com/android/");
to:
URL url = new URL("http://myexample.com/android/yourfilename.txt"); //some file url
Next, in catch block, add this line:
e.printStackTrace();
Also in the directory path, it should be something like this:
File dir = new File(root.getAbsolutePath() + "/mnt/sdcard/myclock/databases");
instead of
File dir = new File(root.getAbsolutePath() + "/myclock/databases");
Next, make sure you have acquired permission for writing to external storage in Android manifest.
Does anyone know how to save a file from a webserver(local host) to the sdcard through wifi?
I am doing xml parsing to my application and for that I have to download an xml file from localhost to the sdcard and then tag the parsing. I am stuck with downloading an xml file to the sd card. Please guide me on how to do this..
You can use this method to download a file from the internet to your SD card:
public void DownloadFromUrl(String DownloadUrl, String fileName) {
try {
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File (root.getAbsolutePath() + "/xmls");
if(dir.exists()==false) {
dir.mkdirs();
}
URL url = new URL(DownloadUrl); //you can write here any link
File file = new File(dir, fileName);
long startTime = System.currentTimeMillis();
Log.d("DownloadManager", "download begining");
Log.d("DownloadManager", "download url:" + url);
Log.d("DownloadManager", "downloaded file name:" + fileName);
/* Open a connection to that URL. */
URLConnection ucon = url.openConnection();
/*
* Define InputStreams to read from the URLConnection.
*/
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
/*
* Read bytes to the Buffer until there is nothing more to read(-1).
*/
ByteArrayBuffer baf = new ByteArrayBuffer(5000);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
/* Convert the Bytes read to a String. */
FileOutputStream fos = new FileOutputStream(file);
fos.write(baf.toByteArray());
fos.flush();
fos.close();
Log.d("DownloadManager", "download ready in" + ((System.currentTimeMillis() - startTime) / 1000) + " sec");
} catch (IOException e) {
Log.d("DownloadManager", "Error: " + e);
}
}
You need to add the following permissions to your AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
The Sourav's answer is OK, but for large file sizes you should implement it on a new thread; because while downloading, the main thread is busy for downloading the file. If the waiting time be more that expected the system will generate "Not responding" error.
In order to do that you can use "TaskAsync" or "IntentService"
I prefer to build soap server and make a call from app to server and by that receiving XML. Or maybe you could just make an URL which generates XML and that just parse URL directly.
Try to read more on this LINK
Hopefully I have answer the question. Otherwise would be pleased to help, but I need more detailed functionality description.