I am trying to download a jar file from my server and put it into the AVD internal memory but it's not working. I tried this code in Java and it's working perfectly.
try
{
URL url = new URL(host);
URLConnection connection = url.openConnection();
int fileLength = connection.getContentLength();
if (fileLength == -1)
{
return;
}
input = connection.getInputStream();
String fileName = url.getFile().substring(url.getFile().lastIndexOf('/') + 1);
writeFile = new FileOutputStream(fileName);
byte[] buffer = new byte[1024];
int read;
while ((read = input.read(buffer)) > 0)
writeFile.write(buffer, 0, read);
writeFile.flush();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
writeFile.close();
input.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
I add the following permission into my manifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
But on connection.getContentLength();, I got a NullPointerException return
I tried with HttpURLConnection and JarURLConnection, add a connection.connect() just after openConnection(), using DownloadManager but it can only download into external storage.
Maybe with HttpClient ? AndroidHttpClient ? But Android support recommend using HttpURLConnection for applications targeted at Gingerbread and higher.
There's a cumbersome but straightforward approach:
1. Use DownloadManager to get a JAR you need (store it in external storage);
2. Move that JAR from external storage to internal one.
Related
For some time I've been trying to implement the functionality of sending an audio file from my app through WhatsApp. When debugging everything seems to work correctly in the application, the audio file is generated and saved correctly in the external storage of the device, the WhatsApp window opens and allows me to select the chat to which I want to send the audio. The problem is that when I press the send button, WhatsApp returns the message "Failed to share. Please try again" (I leave a screenshot of the error so that it can be better viewed, in addition to the code used to implement the functionality).
Capture of the error shown on the screen by WhatsApp when trying to share the audio:
enter image description here
Code used:
//////Boton//////
btn1.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
try {
String mediaPath = copyFiletoExternalStorage(R.raw.audio1, "audio1.mp3");
File myFile = new File(mediaPath);
Uri newUri = getUriForFile(wspActivity.this, "com.restart.shareaudiofiles.fileprovider", myFile);
Intent compartirAudio = new Intent(android.content.Intent.ACTION_SEND);
compartirAudio.setType("com.whatsapp");
compartirAudio.setType("audio/mp3");
compartirAudio.putExtra(Intent.EXTRA_STREAM,newUri);
startActivity(Intent.createChooser(compartirAudio, "Compartir vía"));
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Whatsapp no se encuentra instalado", Toast.LENGTH_LONG).show();
}
}
});
/////funcion auxiliar/////
private String copyFiletoExternalStorage(int resourceId, String resourceName){
String pathi= Environment.getExternalStorageDirectory() + "/Android/data/myProject/";
boolean exists = (new File(pathi)).exists();
if (!exists) {
new File(pathi).mkdirs();
}
String pathSDCard = Environment.getExternalStorageDirectory() + "/Android/data/TeLoResumoBotonera/" + resourceName;
try{
InputStream in = getResources().openRawResource(resourceId);
FileOutputStream out = null;
out = new FileOutputStream(pathSDCard);
byte[] buff = new byte[1024];
int read = 0;
try {
while ((read = in.read(buff)) > 0) {
out.write(buff, 0, read);
}
} finally {
in.close();
out.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return pathSDCard;
}
/////Elementos agregados al manifest/////
<queries>
<package android:name="com.whatsapp" />
<package android:name="com.whatsapp.w4b" />
</queries>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.restart.shareaudiofiles.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
I researched and implemented various resources to the manifest such as the fileprovider and queries with specific packages for WhatsApp (as can be seen in the code). However, the app still doesn't work. This makes me think that the problem could be in the mobile device that I am using to test the application (I would like to use another one to rule out this option, but I don't have an extra one). Another factor that I think may be causing problems is the version of Android (Android 11 in this case). This is because similar codes worked correctly in previous versions. If the device has nothing to do with it, then clearly there is a bug in my code. Due to this, in case someone manages to identify the improvement that could make the application work correctly, I would be very grateful if you can share it with me, or at least give me an idea of where to address the problem.
Thank you very much for your time,
Regards!
As I see your error in the storage path. here is my code that useful to you.
If I am correct, the problem is that you declared the storage path incorrectly:
The path you declared: Environment.getExternalStorageDirectory() + "/Android/data/myProject/"
updated path: context.getExternalFilesDir("MyProject")
The context.getExternalFilesDir("MyProject") method will return the same path as you did.
first change your copyFiletoExternalStorage method like:
private String copyFilesToStorage(Context context, int resourceId, String resourceName) {
File destinationPath = context.getExternalFilesDir("MyProject");
if (!destinationPath.exists()) {
destinationPath.mkdirs();
}
String pathSDCard = new File(destinationPath, resourceName).getAbsolutePath();
try {
InputStream in = getResources().openRawResource(resourceId);
FileOutputStream out = null;
out = new FileOutputStream(pathSDCard);
byte[] buff = new byte[1024];
int read = 0;
try {
while ((read = in.read(buff)) > 0) {
out.write(buff, 0, read);
}
} finally {
in.close();
out.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
return pathSDCard;
}
change share Intent code to like:
File file = new File(copyFilesToStorage(this, R.raw.audio1, "audio1.mp3"));
Uri path = FileProvider.getUriForFile(this,"com.restart.shareaudiofiles.fileprovider", file);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, path);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setType("audio/mp3");//Replace with audio/* to choose other extensions
startActivity(Intent.createChooser(intent, "Share Audio"));
don't forgot about permission:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
This question already has answers here:
What exactly does URLConnection.setDoOutput() affect?
(4 answers)
Closed 12 months ago.
This is the code I wrote for downloading image from url, but receving response code 400 with java.io.FilenotFoundException
#Override
protected Void doInBackground(String... strings) {
try {
URL url = new URL(strings[0]);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestProperty("User-Agent", "Mozilla/5.0
(Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2)
Gecko/20100316 Firefox/3.6.2");
con.setRequestMethod("GET");
con.setDoOutput(true);
con.connect();
File file = Environment.getExternalStorageDirectory();
File f1 = new File(file, "_Url download");
if(!f1.exists()){
f1.mkdir();
}
fileName = System.currentTimeMillis() + ".jpg";
File f2 = new File(f1, fileName);
f2.createNewFile();
InputStream er = con.getErrorStream();
Log.i("ErrorCode", con.getResponseCode()+"");
Log.i("ErrorMessage", con.getResponseMessage());
Log.i("ErrorStream", er+"");
InputStream in = con.getInputStream();
FileOutputStream out = new FileOutputStream(f2);
byte[] buffer = new byte[1024];
int len;
System.out.println(Arrays.toString(buffer));
while((len = in.read(buffer, 0, 1024)) > 0) {
out.write(buffer, 0, len);
}
out.close();
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
Log.i("IOException", e.toString());
}
return null;
}
LOG
2021-06-26 09:26:25.532 26760-26890/com.example.urldownload I/ErrorCode: 400
2021-06-26 09:26:25.533 26760-26890/com.example.urldownload I/ErrorMessage: Bad Request
2021-06-26 09:26:25.533 26760-26890/com.example.urldownload I/Errorstream: buffer(com.android.okhttp.internal.http.Http1xStream$FixedLengthSource#fbb2c70).inputStream()
2021-06-26 09:26:25.534 26760-26890/com.example.urldownload I/IOException: java.io.FileNotFoundException: https://instagram.fidr1-1.fna.fbcdn.net/v/t51.2885-15/e35/190664842_184685183538740_5039921250568173600_n.jpg?tp=1&_nc_ht=instagram.fidr1-1.fna.fbcdn.net&_nc_cat=108&_nc_ohc=RrEU4lTwYCwAX-vgVQ4&edm=AABBvjUBAAAA&ccb=7-4&oh=3ac34be54793fa59134380fd9e0bd617&oe=60DCB7E6&_nc_sid=83d603
Manifest
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
Image of the file where the image is being saved
For more details look at this image
what should I do to resolve this error or is there any better way to do this
I got my mistake.
Thank you everyone for sharing your ideas
con.setDoOutput(true); is a POST method
And it doesn't fetches any data
con.setDoOutput(true); should not be used.
Use picasso to save images in external storage, you can do something like following
private Target mTarget = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
// Perform simple file operation to store this bitmap
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
}
...
Picasso.with(this).load("url").into(mTarget);
Here "Target" is a class provided by picasso, and it has very simple method to understand...
This is a easy way to do
It is hard to figure out what might be causing the error due to lack of provided code. My best guess would be to use DownloadManager instead of AsyncTask.
The download manager is a system service that handles long-running HTTP downloads. Clients may request that a URI be downloaded to a particular destination file. The download manager will conduct the download in the background, taking care of HTTP interactions and retrying downloads after failures or across connectivity changes and system reboots. (https://developer.android.com/reference)
I tried to save "viewBitmap" into SD card.
Here is my code:
try{
String mPath = Environment.getExternalStorageDirectory().toString();
imageFile = new File(mPath, "/snapshot.png");
FileOutputStream outputStream = new FileOutputStream(imageFile);
viewBitmap.compress(Bitmap.CompressFormat.JPEG,100,outputStream);
outputStream.flush();
outputStream.close();
Toast.makeText(Share.this, "Collage was saved.",Toast.LENGTH_SHORT).show();
}catch(Throwable e) {
e.printStackTrace();
}
At the line "FileOutputStream outputStream = new FileOutputStream(imageFile);", an exception was thrown:
In your AndroidManifest.XML file did you add permission
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
If the device is running Android 6.0 (API level 23) or higher, and the app's targetSdkVersion is 23 or higher, refer to the documentation to request the permission at run time.
I have tried to implement over 10-15 different download mechanisms for android java, I have not been able to succeed at all.
I don't care about progress bars or background processes.
I just want one functional download code in fewest lines possible
and I want it to download a binary file (foreground) to the directory in the device wherever it can be accessed as
File pf = new File("filename");
if (pf.exists()) { ... }
Try this (modified from here):
try {
URL url = new URL("http://url.com");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
//THIS IS WHERE YOU GET THE DIRECTORY TO SAVE TO
File SDCardRoot = Environment.getExternalStorageDirectory();
//THIS IS WHERE YOU WILL SET THE FILE NAME
File file = new File(SDCardRoot,"somefile.txt");
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();
//create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
fileOutput.write(buffer, 0, bufferLength);
}
fileOutput.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
You may also need to add permissions to access the phone directory:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
For information on accessing certain folders on the internal directory, see the android developer page: http://developer.android.com/training/basics/data-storage/files.html#WriteInternalStorage
In fact, the solution on that page is also fairly short:
String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
I use the code below to get image:
public Bitmap loadImageFromUrl(String urlStr) {
try {
BufferedInputStream bis = new BufferedInputStream(new URL(urlStr).openStream());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(baos);
copy(bis, bos);
bos.flush();
bos.close();
bis.close();
return BitmapFactory.decodeByteArray(baos.toByteArray(), 0, baos.size());
} catch (Exception e) {
e.printStackTrace();
}
I'm sure of the permisson and wifi connection.
such as:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
If you are getting this error then might be there is 2 issue.
1) Either you forget to add permission of internet in android manifest.
<uses-permission android:name="android.permission.INTERNET" />
2) If you are running in real device then your device is not connected with internet. Check whether your device is connected with internet or not.