I am developing an android project with google maps and it has custom images for the markers of google map.But instead of downloading the images each time, the first time the marker images are downloaded into internal memory, from the second time onwards i check if the images are downloaded and then they are retrieved from memory.
But the code works fine on my phone (Android version 2.6.3) , But when i tried on newer devices (Android 4 and above) the code for retrieving the downloaded bitmap image returns null.
The code for checking if the images have been downloaded:
public void checkcategoryimagesavailable() {
path_file=MainActivity.this.getFilesDir().getAbsolutePath();
for(int i=0;i<catprearr.size();i++) {
File file = new File(path_file+File.separator+catprearr.get(i)+".png");
if(file.exists()) {
} else {
downloadfile(URL_image+catprearr.get(i)+".png",path_file+File.separator+catprearr.get(i)+".png");
}
}
setvaluesonmap();
}
The code for downloading the images:
public void downloadfile(String path,String filepath) {
try {
URL url = new URL(path);
URLConnection ucon = url.openConnection();
ucon.setReadTimeout(5000);
ucon.setConnectTimeout(10000);
InputStream is = ucon.getInputStream();
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
File file = new File(filepath);
file.createNewFile();
FileOutputStream outStream = new FileOutputStream(file);
byte[] buff = new byte[5 * 1024];
int len;
while ((len = inStream.read(buff)) != -1) {
outStream.write(buff, 0, len);
}
outStream.flush();
outStream.close();
inStream.close();
} catch(Exception e) {
e.printStackTrace();
}
}
The code for setting the markers:
public void setvaluesonmap() {
for(int i=0;i<list.size();i++) {
final Store_data s=list.get(i);
Bitmap obj=getImageBitmap(MainActivity.this,s.category+".png");
obj=Bitmap.createScaledBitmap(obj,68,62,false);
iv_category_logo.setImageBitmap(obj);
googleMap.addMarker(new MarkerOptions().title(s.store_name)
.icon(BitmapDescriptorFactory.fromBitmap(createDrawableFromView(MainActivity.this, custom_layout)))
.position(new LatLng(Double.parseDouble(s.store_latitude),Double.parseDouble(s.store_longitude))));
}
}
The code for retrieving the downloaded image:This is the troubled code:the bitmap returns null on newer devices
public Bitmap getImageBitmap(Context context,String name) {
try {
// FileInputStream fis = context.openFileInput(name);
// File file = new File("filesdir", name);
File myFile = new File (path_file+File.separator+name);
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
Bitmap b = BitmapFactory.decodeStream(fis);
//fis.close();
return b;
} catch(Exception e) {
return null;
}
}
Why does it work fine on older devices,But doesnt work on newer devices.
Related
I'm trying to download the following the following file, with this link that redirects you to a direct download: http://www.lavozdegalicia.es/sitemap_sections.xml.gz
I've done my own research, but all the results I see are related to HTTP URL redirections
[3xx] and not to direct download redirections (maybe I'm using the wrong terms to do the research).
I've tried the following pieces of code (cite: https://programmerclick.com/article/7719159084/ ):
// Using Java IO
private static void downloadFileFromUrlWithJavaIO(String fileName, String fileUrl) {
BufferedInputStream inputStream = null;
FileOutputStream outputStream = null;
try {
URL url = new URL(fileUrl);
inputStream = new BufferedInputStream(url.openStream());
outputStream = new FileOutputStream(fileName);
byte data[] = new byte[1024];
int count;
while ((count = inputStream.read(data, 0, 1024)) != -1) {
outputStream.write(data, 0, count);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Using Apache common IO
private static void downloadFileFromUrlWithCommonsIO(String fileName, String fileUrl) {
try {
FileUtils.copyURLToFile(new URL(fileUrl), new File(fileName));
} catch (IOException e) {
e.printStackTrace();
}
}
// Using NIO
private static void downloadFileFromURLUsingNIO(String fileName, String fileUrl) {
try {
URL url = new URL(fileUrl);
ReadableByteChannel readableByteChannel = Channels.newChannel(url.openStream());
FileOutputStream fileOutputStream = new FileOutputStream(fileName);
fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
fileOutputStream.close();
readableByteChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
But the result I get with any of the three options is an empty file, my thoughts are that the problem is related to the file being a .xml.gz because when I debug it the inputStream doesn't seem to have any content.
I ran out of options, anyone has an idea of how to handle this case, or what would be the correct terms I should use to research about this specific case?
I found a solution, there's probably a more polite way of achieving the same result but this worked fine for me:
//Download the file and decompress it
filecount=0;
URL compressedSitemap = new URL(urlString);
HttpURLConnection con = (HttpURLConnection) compressedSitemap.openConnection();
con.setRequestMethod("GET");
if (con.getResponseCode() == HttpURLConnection.HTTP_MOVED_TEMP || con.getResponseCode() == HttpURLConnection.HTTP_MOVED_PERM) {
String location = con.getHeaderField("Location");
URL newUrl = new URL(location);
con = (HttpURLConnection) newUrl.openConnection();
}
String file = "/home/user/Documentos/Decompression/decompressed" + filecount + ".xml";
GZIPInputStream gzipInputStream = new GZIPInputStream(con.getInputStream());
FileOutputStream fos = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = gzipInputStream.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
filecount++;
Two things to note:
When I was trying to do HTTPGet the url that was a redirect, the response code was 301 or 302 (depending on the example I used), I overcame this problem with the if check, that follows the redirect and aims to the downloaded file.
Once aiming the file, to get the content of the compressed file I found the GZIPInputStream package, that allowed me to get an inputStream directly from the compressed file and dump it on an xml file, that saved me the time of doing it on three steps (decompress, read, copy).
Good morning.
I want to use the Android plug-in to save the image to Internal Storage and import the image from Internal Storage.
When you save an image in Unity, the user can access the saved image.
I do not want users to access stored images.
So I tried to create and use Android plugin, but it is not working properly.
I need help.
Android Native Code :
public void WriteToInternalStorage(String name, byte[] data) {
try{
FileOutputStream fileOutputStream = context.openFileOutput(name, context.MODE_PRIVATE);
fileOutputStream.write(data);
fileOutputStream.close();
} catch(IOException e) {
e.printStackTrace();
}
}
public byte[] ReadToInternalStorage(String name) {
StringBuffer stringBuffer = new StringBuffer("");
byte[] buffer = new byte[1024];
int n;
try {
FileInputStream fileInputStream = context.openFileInput(name);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line;
while((line = bufferedReader.readLine()) != null) {
stringBuffer.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return String.valueOf(stringBuffer).getBytes();
}
Unity Code :
public void NativeCall_ReadInternalStorage(string name)
{
byte[] test = instance.Call<byte[]>("ReadToInternalStorage", name);
Texture2D tex = new Texture2D(2, 2);
tex.LoadImage(test);
Thumbnail.texture = tex;
}
The image is not displayed properly.
I do not know what's wrong with the Android native code.
Please help me.
I am working on a project with google maps where i try to retrieve bitmaps from URL and save it to internal memory.After downloading the bitmap into internal memory i try to read it from memory using the following code:
public Bitmap getImageBitmap(Context context, String name) {
FileInputStream fis = null;
try {
File myFile = new File (path_file + File.separator + name);
fis = new FileInputStream(myFile);
Bitmap b = BitmapFactory.decodeStream(fis);
return b;
} catch(Exception e) {
return null;
} finally {
if(fis!=null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The problem is that the code works fine on Android 2.6 , but it throws Filenotfoundexception at this line
fis = new FileInputStream(myFile);
Why does the code work fine on older versions of android but throws exception on newer versions of android?How do i fix the issue?
EDIT:
The issue was with the code which downloads the bitmap:
The code that i am using is:
public void downloadfile(String path,String filepath)
{
try
{
URL url = new URL(path);
URLConnection ucon = url.openConnection();
ucon.setReadTimeout(5000);
ucon.setConnectTimeout(10000);
InputStream is = ucon.getInputStream();
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
File file = new File(filepath);
file.createNewFile();
FileOutputStream outStream = new FileOutputStream(file);
byte[] buff = new byte[5 * 1024];
int len;
while ((len = inStream.read(buff)) != -1)
{
outStream.write(buff, 0, len);
}
outStream.flush();
outStream.close();
inStream.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
The code throws NetworkonMainThreadException at this line: InputStream is = ucon.getInputStream();
This error is thrown only on the newer android version.Please help!!
Try this..
Just use
path_file=MainActivity.this.getFilesDir();
EDIT
class downloadfile extends AsyncTask<String, Void, Void> {
protected Void doInBackground(String... urls) {
try
{
URL url = new URL(path);
URLConnection ucon = url.openConnection();
ucon.setReadTimeout(5000);
ucon.setConnectTimeout(10000);
InputStream is = ucon.getInputStream();
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
File file = new File(filepath);
file.createNewFile();
FileOutputStream outStream = new FileOutputStream(file);
byte[] buff = new byte[5 * 1024];
int len;
while ((len = inStream.read(buff)) != -1)
{
outStream.write(buff, 0, len);
}
outStream.flush();
outStream.close();
inStream.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
protected void onPostExecute() {
// TODO: check this.exception
// TODO: do something with the feed
}
}
Instead if calling downloadfile method use below
new downloadfile().execute();
You are trying to perform a network related operation in Main thread,you are getting this NetworkonMainThreadException.
Refer to my answer here for more explanation.
In your case try downloading the bitmap file in worker thread. You can use an Asynctask for it and download bitmap in doInBackground().
Refer this example
Im trying to use Adobe reader to read pdf files downloaded from the server the problem is When i store it in the internal storage Other application can't read the file. Now i Want to know how can i Copy this file in the external storage(/sdcard/) so it can be viewed by pdf viewers.
Due to security reason I'm storing the files in the Internal Storage and would delete the one in external storage afterwards.
My question is How can i copy the file saved in the internal storage without using the raw or the assets to put in the inputstream.
InputStream myInput = getResources().openRawResource(R.raw.p13);
FileOutputStream fos = openFileOutput("sample", Context.MODE_PRIVATE);
// transfer bytes from the input file to the output file
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0)
{
fos.write(buffer, 0, length);
}
// Close the streams
fos.flush();
fos.close();
myInput.close();
at which path you are storing the pdf file ?
See below one to get file from android Assets and copy it to the specific sdcard location.
I will first check for the pdf file whether it is already available at desire path or not.
File file1 = new File("/sdcard/SampleProjectApp/WindsorONE_Mobile_Molding.pdf");
File file2 = new File("/sdcard/SampleProjectApp/WindsorONE_Mobile_PK.pdf");
File file3 = new File("/sdcard/SampleProjectApp/Alone.mp4");
if(!((file1.exists())) || !((file2.exists())) || !((file3.exists()))) {
ArrayList<String> files = new ArrayList<String>();
files.add("WindsorONE_Mobile_Molding.pdf");
files.add("WindsorONE_Mobile_PK.pdf");
files.add("Alone.mp4");
new myAsyncTask().execute(files);
}
Now, if the file is not present at that position then it will execute the myAsyncTask to copy file from assets to the SdCard.
// AsyncTass for the Progress Dialog and to do Background Process
private class myAsyncTask extends AsyncTask<ArrayList<String>, Void, Void> {
ArrayList<String> files;
ProgressDialog dialog;
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(ListSample.this, "W1 SALES (beta)", "Loading...");
}
#Override
protected Void doInBackground(ArrayList<String>... params) {
files = params[0];
for (int i = 0; i < files.size(); i++) {
copyFileFromAssetsToSDCard(files.get(i));
} return null;
}
#Override
protected void onPostExecute(Void result) {
dialog.dismiss();
}
}
// Function to copy file from Assets to the SDCard
public void copyFileFromAssetsToSDCard(String fileFromAssets){
AssetManager is = this.getAssets();
InputStream fis;
try {
fis = is.open(fileFromAssets);
FileOutputStream fos;
if (!APP_FILE_PATH.exists()) {
APP_FILE_PATH.mkdirs();
}
fos = new FileOutputStream(new File(Environment.getExternalStorageDirectory()+"/SampleProjectApp", fileFromAssets));
byte[] b = new byte[8];
int i;
while ((i = fis.read(b)) != -1) {
fos.write(b, 0, i);
}
fos.flush();
fos.close();
fis.close();
}
catch (IOException e1) {
e1.printStackTrace();
}
}
Updated
For your part:
replace
SampleProjectApp/WindsorONE_Mobile_Molding.pdf
with
Android/data/com.project.projectname/cache/YOUR_PDF_FILE.pdf
Hope it make sense.
Updated 2
Below code is copy file from one path to another path. You simply have to pass the path of the file where it is exist and the path where it has to be copy.
Code:
public static boolean copyFile(String from, String to) {
try {
int bytesum = 0;
int byteread = 0;
File oldfile = new File(from);
if (oldfile.exists()) {
InputStream inStream = new FileInputStream(from);
FileOutputStream fs = new FileOutputStream(to);
byte[] buffer = new byte[1444];
while ((byteread = inStream.read(buffer)) != -1) {
bytesum += byteread;
fs.write(buffer, 0, byteread);
}
inStream.close();
fs.close();
}
return true;
} catch (Exception e) {
return false;
}
}
you can use this method
boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
if(isSDPresent)
{
InputStream in = null;
OutputStream out = null;
in = //Place your file in the inputstream
out = new FileOutputStream(Environment.getExternalStorageDirectory().getAbsolutePath() + filename);
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
in.close();
in = null;
out.flush();
out.close();
out = null;
}
else
{
Toast.makeText(getApplicationContext(), "SD Card not present", Toast.LENGTH_LONG).show();
}
I'm trying to grab (with the method below) an image from the internet and do some canvas work with. but sometimes i'm having outOfMemory exception. So i'm wondering if is there a way to load the inputStream directly in the memory card instead of the internal memory.
private Bitmap LoadImageFromWebOperations(String url)
{
try {
InputStream is = (InputStream) new URL(url).getContent();
Drawable d = Drawable.createFromStream(is, "src name");
bitmap = ((BitmapDrawable)d).getBitmap().copy(Config.ARGB_8888, true);
return bitmap;
}catch (Exception e) {
System.out.println("Exc="+e);
return null;
}
}
the logcat says that the exception is due to that line :
Drawable d = Drawable.createFromStream(is, "src name");
Thx in advance!
I took this code from Fedor Vlasov's lazylist demo:
Lazy load of images in ListView.
First you need to create a function to copy your input stream to file output stream:
public static void CopyStream(InputStream is, OutputStream os)
{
final int buffer_size=1024;
try
{
byte[] bytes=new byte[buffer_size];
for(;;)
{
int count=is.read(bytes, 0, buffer_size);
if(count==-1)
break;
os.write(bytes, 0, count);
}
}
catch(Exception ex){}
}
Then get a cache folder:
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"MyCacheDir");
else
cacheDir=context.getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
Then load your bitmap:
private Drawable getBitmap(String url)
{
String filename=URLEncoder.encode(url);
File f= new File(cacheDir, filename);
try {
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
InputStream is = conn.getInputStream();
OutputStream os = new FileOutputStream(f);
CopyStream(is, os);
os.close();
Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(f));
return new BitmapDrawable(bitmap);
} catch (Exception ex){
ex.printStackTrace();
return null;
}
}