downloading file in sdcard showing size 0 - java

I have following code for downloading file from url to sdcard . This code is working fine for small file , but when the file size is large i am getting the downloaded file size 0.
Any help would be appreciated.
Java Code
setContentView(R.layout.activity_download_file);
String exStorageDirectory = Environment.getExternalStorageDirectory()
.toString();
File folder = new File(exStorageDirectory, "Folder");
folder.mkdir();
File file = new File(folder, "scjp.pdf");
try {
if (!file.exists()) {
file.createNewFile();
}
} catch (IOException e) {
e.printStackTrace();
}
downloadFile(
"http://java.net/downloads/jfjug/SCJP%20Sun%20Certified%20Programmer%20for%20Java%206-0071591060.pdf",
file);
}
private void downloadFile(String fileUrl, File directory) {
try {
FileOutputStream fileOutput = new FileOutputStream(directory);
URL url = new URL(fileUrl);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.connect();
InputStream inputStream = connection.getInputStream();
byte buffer[] = new byte[1024];
int len = 0;
while ((len = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, len);
}
fileOutput.close();
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
}
}

Have a try with this code.
package com.example.stack;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RelativeLayout;
public class MainActivity extends Activity {
ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
overridePendingTransition(R.anim.enter, R.anim.enter);
setContentView(R.layout.activity_main);
// declare the dialog as a member field of your activity
// instantiate it within the onCreate method
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setMessage("A message");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
// execute this when the downloader must be fired
DownloadFile downloadFile = new DownloadFile();
downloadFile.execute("http://java.net/downloads/jfjug/SCJP%20Sun%20Certified%20Programmer%20for%20Java%206-0071591060.pdf");
}
//The AsyncTask will look like this:
// usually, subclasses of AsyncTask are declared inside the activity class.
// that way, you can easily modify the UI thread from here
private class DownloadFile extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... sUrl) {
try {
URL url = new URL(sUrl[0]);
URLConnection connection = url.openConnection();
connection.connect();
// this will be useful so that you can show a typical 0-100% progress bar
int fileLength = connection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream("/sdcard/output.pdf");
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
}
return null;
}
//The method above (doInBackground) runs always on a background thread. You shouldn't do any UI tasks there. On the other hand, the onProgressUpdate and onPreExecute run on the UI thread, so there you can change the progress bar:
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
mProgressDialog.setProgress(progress[0]);
}
}
}
Add the following permission in you manifest file .
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
i have tested in mobile too. its worked.

Try working with this code:
URL url;
long startTime = System.currentTimeMillis();
// Open a connection to that URL.
URLConnection ucon = null;
try {
url = new URL(
"http://java.net/downloads/jfjug/SCJP%20Sun%20Certified%20Programmer%20for%20Java%206-0071591060.pdf");
ucon = url.openConnection();
Log.i("", "image download beginning: " + url);
ucon.setReadTimeout(TIMEOUT_CONNECTION);
ucon.setConnectTimeout(TIMEOUT_SOCKET);
// Define InputStreams to read from the URLConnection.
// uses 3KB download buffer
InputStream is = ucon.getInputStream();
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
FileOutputStream outStream = new FileOutputStream(
"mnt/sdcard/example.pdf");
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 (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

As per the java doc for public int read (byte\[\] buffer, int offset, int length) method it returns
the number of bytes actually read or -1 if the end of the stream has
been reached.
So you should check for -1 rather then 0.
Change your while loop from
while ((len = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, len);
}
to following
while ((len = inputStream.read(buffer)) != -1) {
fileOutput.write(buffer, 0, len);
}
And as pointed out in comments you should do this in background thread or AsyncTask...
EDIT1:
Can you put some logs to see the point of error.. like if the input stream is getting opened or not... Also after the call to connect check for the HTTP response code by calling getResponseCode() method if the response code is 200 then only create the file..

Related

How to check if Referer is empty or not before downloading

I have this two URL
From this website https://wvw1.123movies.net/ I got this URL
https://s02.eplayvid.net/vids/mars.attacks.1996.720p.brrip.x264.yify.mp4
and from https://oceanofapk.com/ I got this URL
https://51-75-145-23.xyz/OceanofAPK.com/KSWEB_v3.963_[Pro_Mod_By_Stabiron].apk?md5=8RIbo_gkOkiR7c9XrpVDnQ&expires=1655617658
The first one requires Referer but the second one doesn't require Referer but will throws 403 error if I added Referer to the request.
Adding this to the first one will work
connection.addRequestProperty("Referer", url.toExternalForm());
but to the second one throws 403 forbidden error.
So my question is how can I check if the server requires Referer header request or not and based on that download the file.
Full Code
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.PowerManager;
import android.webkit.CookieManager;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class Demo extends AppCompatActivity {
ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
// declare the dialog as a member field of your activity
// instantiate it within the onCreate method
mProgressDialog = new ProgressDialog(Demo.this);
mProgressDialog.setMessage("Downloading...");
mProgressDialog.setIndeterminate(true);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);
// execute this when the downloader must be fired
final DownloadTask downloadTask = new DownloadTask(Demo.this);
downloadTask.execute("https://s02.eplayvid.net/vids/mars.attacks.1996.720p.brrip.x264.yify.mp4");
//downloadTask.execute("https://51-75-145-23.xyz/OceanofAPK.com/KSWEB_v3.963_[Pro_Mod_By_Stabiron].apk?md5=8RIbo_gkOkiR7c9XrpVDnQ&expires=1655617658");
mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
downloadTask.cancel(true); //cancel the task
}
});
}
// usually, subclasses of AsyncTask are declared inside the activity class.
// that way, you can easily modify the UI thread from here
private class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
private PowerManager.WakeLock mWakeLock;
public DownloadTask(Context context) {
this.context = context;
}
#Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.addRequestProperty("Referer", url.toExternalForm());
connection.setInstanceFollowRedirects(false);
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.setRequestProperty("Accept-Encoding", "identity");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Linux; Android 12) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.61 Mobile Safari/537.36");
// Get the cookies for the current domain.
String cookiesString = CookieManager.getInstance().getCookie(url.toString());
// Only add the cookies if they are not null.
if (cookiesString != null) {
// Add the cookies to the header property.
connection.setRequestProperty("Cookie", cookiesString);
}
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
output = new FileOutputStream("/sdcard/mars.attacks.1996.720p.brrip.x264.yify.mp4");
//output = new FileOutputStream("/sdcard/ksweb.apk");
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) {
input.close();
return null;
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) Demo.this.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
mWakeLock.acquire();
mProgressDialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// if we get here, length is known, now set indeterminate to false
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgress(progress[0]);
}
#Override
protected void onPostExecute(String result) {
mWakeLock.release();
mProgressDialog.dismiss();
if (result != null) {
Toast.makeText(context, "Download error: " + result, Toast.LENGTH_LONG).show();
System.out.println(result);
}else {
Toast.makeText(context, "File downloaded", Toast.LENGTH_SHORT).show();
}
}
}
}

Downloading an image into internal storage and reading it in android

I am trying to download an image from url and i want to display it in an imageview.My code is as follows:
package com.example.imageinternalstorage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends Activity {
Button btnstoreinternal,btnloadfrominternal;
ImageView iv_category;
boolean download_success;
String URL_image="http://footballultimate.com/storelocator/resource/uploads/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnstoreinternal=(Button) findViewById(R.id.btnstoreinternal);
btnloadfrominternal=(Button) findViewById(R.id.btnloadfrominternal);
iv_category=(ImageView) findViewById(R.id.iv_category);
btnstoreinternal.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
download_success=downloadFile(URL_image+"Hospital.png");
if(download_success==true)
{
Toast.makeText(getApplicationContext(),"Download success",Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getApplicationContext(),"Download failed",Toast.LENGTH_LONG).show();
}
}
});
btnloadfrominternal.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
iv_category.setImageBitmap(getImageBitmap(MainActivity.this,"Hospital.png"));
}
});
}
public boolean downloadFile(final String path)
{
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(MainActivity.this.getDir("filesdir", Context.MODE_PRIVATE) + "/Hospital.png");
if (file.exists())
{
file.delete();
}
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();
return false;
}
return true;
}
public Bitmap getImageBitmap(Context context,String name){
try{
FileInputStream fis = context.openFileInput(name);
Bitmap b = BitmapFactory.decodeStream(fis);
fis.close();
return b;
}
catch(Exception e){
}
return null;
}
}
When i click the first button the download is shown as successfull.But when i click the second button to display the image in the imageview nothing happens.So can anyone give me a replacement code for the retrival code from memory:
public Bitmap getImageBitmap(Context context,String name){
try{
FileInputStream fis = context.openFileInput(name);
Bitmap b = BitmapFactory.decodeStream(fis);
fis.close();
return b;
}
catch(Exception e){
}
return null;
}
The code for dowloading is:
public boolean downloadFile(final String path)
{
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(MainActivity.this.getDir("filesdir", Context.MODE_PRIVATE) + "/Hospital.png");
if (file.exists())
{
file.delete();
}
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();
return false;
}
return true;
}
Android does not allow such Network operations in the onCreate method ever since version >2.2 I think.
Solutions:
1- Try using a private class inside the main class that extends AsyncTask and if you are not sure about the return type you can use Void. E.g take a look at this AndroidHive tutorial ,while he is retrieving JSON data from a website he calls the 'GetContacts' class which he created to do the network operations.
2-If you are not feeling all this AsyncTask stuff take a look at Android Volley library which has a nice AndroidHive tutorial as well.
while downloading image you are storing it in "filesdir" while for retrieving image you are using openFileInput(name)
replace FileInputStream fis = context.openFileInput(name); By File file = new File("filesdir", FILENAME);
else use this for storing downloaded image
String path=context.getFilesDir().getAbsolutePath();
File file = new File(path + File.separator + fileName);
and this for retriving image
File myFile = new File ( path+ File.separator + fileName);
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);

Read a pdf file from assets folder

public void DOCS(View btnDocs)
{
File fileBrochure = new File("android.resource://com.project.datastructure/assets/abc.pdf");
if (!fileBrochure.exists())
{
CopyAssetsbrochure();
}
/** PDF reader code */
File file = new File("android.resource://com.project.datastructure/assets/abc.pdf");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file),"application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try
{
getApplicationContext().startActivity(intent);
}
catch (ActivityNotFoundException e)
{
Toast.makeText(Stack_dr.this, "NO Pdf Viewer", Toast.LENGTH_SHORT).show();
}
}
private void CopyAssetsbrochure() {
AssetManager assetManager = getAssets();
String[] files = null;
try
{
files = assetManager.list("");
}
catch (IOException e){}
for(int i=0; i<files.length; i++)
{
String fStr = files[i];
if(fStr.equalsIgnoreCase("abc.pdf"))
{
InputStream in = null;
OutputStream out = null;
try
{
in = assetManager.open(files[i]);
out = new FileOutputStream("/sdcard/" + files[i]);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
break;
}
catch(Exception e){}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
I am trying to read a pdf file from assets folder which is present in my application folder . Everything is working perfectly when i click on my DOCS button a pop up comes to let me choose an application for opening the pdf i.e "abc.pdf" but after selecting an option i get an error message "The file path is not valid". I think their is some problem with the path which i have specified in the code.
please help
Try this
public class SampleActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
CopyReadAssets();
}
private void CopyReadAssets()
{
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
File file = new File(getFilesDir(), "abc.pdf");
try
{
in = assetManager.open("abc.pdf");
out = openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e)
{
Log.e("tag", e.getMessage());
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(
Uri.parse("file://" + getFilesDir() + "/abc.pdf"),
"application/pdf");
startActivity(intent);
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
}
Make sure to include
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
in manifest
You can do it like this (tested and working on API 27)
Step 1
Add following dependency in your app gradle:
implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'
Step 2
Add following XML code:
<com.github.barteksc.pdfviewer.PDFView
android:id="#+id/pdfv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.github.barteksc.pdfviewer.PDFView>
Step 3
Add following code in your java file:
public class MainActivity extends AppCompatActivity {
PDFView pdfView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pdfView=findViewById(R.id.pdfv);
pdfView.fromAsset("filename.pdf").load();
}
}
These changes will load a PDF file on creation of your activity.
Though this has been answered, I wanted to share my solution as I think it is a bit easier to include.
Usage:
new OpenLocalPDF(context, 'nameOfPDFStoredInAssets').execute()
And here is the OpenLocalPDF class:
public class OpenLocalPDF {
private static String TAG = OpenLocalPDF.class.getSimpleName();
private WeakReference<Context> contextWeakReference;
private String fileName;
public OpenLocalPDF(Context context, String fileName) {
this.contextWeakReference = new WeakReference<>(context);
this.fileName = fileName.endsWith("pdf") ? fileName : fileName + ".pdf";
}
public void execute() {
Context context = contextWeakReference.get();
if (context != null) {
new CopyFileAsyncTask().execute();
}
}
private class CopyFileAsyncTask extends AsyncTask<Void, Void, File> {
final String appDirectoryName = BuildConfig.APPLICATION_ID;
final File fileRoot = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOCUMENTS), appDirectoryName);
#Override
protected File doInBackground(Void... params) {
Context context = contextWeakReference.get();
AssetManager assetManager = context.getAssets();
File file = new File(fileRoot, fileName);
InputStream in = null;
OutputStream out = null;
try {
file.mkdirs();
if (file.exists()) {
file.delete();
}
file.createNewFile();
in = assetManager.open(fileName);
Log.d(TAG, "In");
out = new FileOutputStream(file);
Log.d(TAG, "Out");
Log.d(TAG, "Copy file");
copyFile(in, out);
Log.d(TAG, "Close");
in.close();
out.flush();
out.close();
return file;
} catch (Exception e)
{
Log.e(TAG, e.getMessage());
}
return null;
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
#Override
protected void onPostExecute(File file) {
super.onPostExecute(file);
Context context = contextWeakReference.get();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(
Uri.fromFile(file),
"application/pdf");
context.startActivity(intent);
}
}
}
add this permission in Manifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
like say sunsil, but in the case for external directory.
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Environment;
import android.os.Bundle;
import android.util.Log;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
copyReadAssets();
}
private void copyReadAssets()
{
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
String strDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)+ File.separator + "Pdfs";
File fileDir = new File(strDir);
fileDir.mkdirs(); // crear la ruta si no existe
File file = new File(fileDir, "example2.pdf");
try
{
in = assetManager.open("example.pdf"); //leer el archivo de assets
out = new BufferedOutputStream(new FileOutputStream(file)); //crear el archivo
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e)
{
Log.e("tag", e.getMessage());
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + File.separator + "Pdfs" + "/example2.pdf"), "application/pdf");
startActivity(intent);
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
}
change parts of code like these:
out = new BufferedOutputStream(new FileOutputStream(file));
the before example is for Pdfs, in case of to example .txt
FileOutputStream fos = new FileOutputStream(file);
This works for me.
Step 1: In MainActivity.java
public class SampleActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//call this method by passing file name in params.
readFromAssets("User guide.pdf");
}
public static void readFromAssets(String fileName) {
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
File file = new File(mContext.getFilesDir(), fileName);
try {
in = assetManager.open(fileName);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
out = mContext.openFileOutput(file.getName(), Context.MODE_PRIVATE);
} else {
out = mContext.openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
}
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
Uri pdfFileURI;
Intent intent = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
pdfFileURI = FileProvider.getUriForFile(mContext,
BuildConfig.APPLICATION_ID + ".provider", file);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
pdfFileURI = Uri.parse("file://" + mContext.getFilesDir() + "/" + fileName);
}
intent.setDataAndType(pdfFileURI, "application/pdf");
mContext.startActivity(intent);
}
private static void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
}
Step 2: Create provider_paths.xml inside res->xml->provider_paths.xml. See here
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="." />
<root-path
name="root"
path="." />
</paths>
Step 3: In AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppThemeMaterial">
<!-- INSIDE APPLICATION TAG -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
</application>
No answer worked for me out-of-the-box when attempting to open a file via an intent (in my case PDF) from the assets folder. So here is my solution combining 2 brilliant answers I'm sure it will help someone. Must be for api >= 24.
Once you have followed this link and added the your own GenericFileProvider and declared it in your manifest within the Application tag and created the provider_paths.xml simply use the below class and call it like:
OpenLocalPDF(this, "YOUR_PDF_NAME_IN_ASSETS_FOLDER.pdf").execute()
OpenLocalPdf.kt: (kudos too the OP https://stackoverflow.com/a/41212708/1133011)
import android.content.Context
import android.content.Intent
import android.content.res.AssetManager
import android.os.AsyncTask
import android.util.Log
import androidx.core.content.FileProvider
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream
import java.io.OutputStream
import java.lang.ref.WeakReference
class OpenLocalPDF(context: Context?, fileName: String?) {
private val contextWeakReference: WeakReference<Context?>?
private val fileName: String?
fun execute() {
val context: Context = contextWeakReference!!.get()!!
if (context != null) {
CopyFileAsyncTask().execute()
}
}
private inner class CopyFileAsyncTask :
AsyncTask<Void?, Void?, File?>() {
val appDirectoryName: String? = co.za.umbiflow.BuildConfig.APPLICATION_ID
val fileRoot: File? = File(
android.os.Environment.getExternalStoragePublicDirectory(
android.os.Environment.DIRECTORY_DOCUMENTS
), appDirectoryName
)
override fun doInBackground(vararg params: Void?): File? {
val context: Context = contextWeakReference!!.get()!!
val assetManager: AssetManager = context.getAssets()
val file = File(fileRoot, fileName)
var `in`: InputStream? = null
var out: OutputStream? = null
try {
file.mkdirs()
if (file.exists()) {
file.delete()
}
file.createNewFile()
`in` = assetManager.open(fileName)
out = FileOutputStream(file)
copyFile(`in`, out)
`in`.close()
out.flush()
out.close()
return file
} catch (e: Exception) {
Log.e(TAG, e.message)
}
return null
}
private fun copyFile(`in`: InputStream, out: OutputStream) {
val buffer = ByteArray(1024)
var read: Int
while (`in`.read(buffer).also { read = it } != -1) {
out.write(buffer, 0, read)
}
}
override fun onPostExecute(file: File?) {
super.onPostExecute(file)
val context: Context = contextWeakReference!!.get()!!
var pdfUri =
FileProvider.getUriForFile(
context,
context.packageName + ".provider",
file!!
)
val intent = Intent()
intent.action = Intent.ACTION_VIEW
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.setDataAndType(
pdfUri,
"application/pdf"
)
context.startActivity(intent)
}
}
companion object {
private val TAG = OpenLocalPDF::class.java.simpleName
}
init {
contextWeakReference = WeakReference(context)
this.fileName = if (fileName!!.endsWith("pdf")) fileName else "$fileName.pdf"
}
}
This is a way to open multiple PDF files from assets using a zip file.
Step1: Copy a zip file(pdf.zip) into assets folder that contains the list of pdfs
Step2: Write PDF's into external cache inside the app in a Utils class
public static void writePDFs(Context context) {
try {
InputStream inputStream = context.getApplicationContext().getAssets().open("pdf.zip");
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
ZipEntry zipEntry;
File file = new File(context.getExternalCacheDir().getAbsolutePath(), "PDFs");
if (!file.getAbsoluteFile().exists()) {
if (file.mkdir()) {
BufferedOutputStream outputStream;
byte[] buffer = new byte[1024];
int count;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
String s1 = file + "/" + zipEntry.getName();
File file1 = new File(s1);
if (!file1.exists()) {
file1.createNewFile();
}
outputStream = new BufferedOutputStream(new FileOutputStream(file1));
while ((count = zipInputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, count);
}
outputStream.flush();
outputStream.close();
zipInputStream.closeEntry();
}
}
zipInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Step3: Call the above function in Activities onCreate
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FileUtils.writePDFs(this);
}
Step4: Create a common function in Utils class to open the PDF
public static void openPDF(Activity activity, String fileName) {
if (activity == null) return;
File file = new File(activity.getExternalCacheDir().getAbsolutePath() + "/PDFs" + "/" + fileName);
Uri docUri = GenericFileProvider.getUriForFile(activity, activity.getApplicationContext().getPackageName(), file);
try {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(docUri, "application/pdf");
} else {
intent.setDataAndType(Uri.fromFile(file), "application/pdf");
}
activity.startActivityForResult(intent, ACTIVITY_VIEW_ATTACHMENT);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
Step5: Call the openPDF function on click on the view in Activity
myView.setOnClickListener(v -> ApplicationUtils.openPDF(this, "MyPdfFile.pdf"));
I had success, using the answer from cYrixmorten, with the OpenLocalPDF class.
But, Environment.DIRECTORY_DOCUMENTS is not supported for Android 18. To support Android 18 - 28, I had to make the following changes.
In "CopyFileAsyncTask", change the fileRoot declaration:
final File fileRoot = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOCUMENTS), appDirectoryName);
To this:
final File fileRoot = new File(Environment.getExternalStorageDirectory() + "/YourAppName");
In "onPostExecute", change this:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(
Uri.fromFile(file),
"application/pdf");
context.startActivity(intent);
To this:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(FileProvider.getUriForFile(context, "com.example.yourappname.provider", file), "application/pdf");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(intent);
Finally, setup your manifest to support the FileProvider as described in this post.
try this:
public String getAssetsPdfPath(Context context) {
String filePath = context.getFilesDir() + File.separator + "myFile.pdf";
File destinationFile = new File(filePath);
try {
FileOutputStream outputStream = new FileOutputStream(destinationFile);
InputStream inputStream = context.getAssets().open("myFile.pdf");
byte[] buffer = new byte[1024];
int length = 0;
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
outputStream.close();
inputStream.close();
} catch (IOException e) {
Log.e(context.getClass().getSimpleName(), "Error.");
}
return destinationFile.getPath();
}
If you want to open a .pdf file that is stored locally in the assets folder without using an Intent to launch an external app, I suggest using the Android class PdfRenderer. Documentation found here.
This is a good example that worked for me.
However, this example wouldn't run when I downloaded it. I had to change it a bit to use the copyReadAssets() function as mentioned in the other answers here, then to reference the file (after it has been copied) I use:
File file = new File("/data/data/" + getContext().getPackageName() + "/files/mypdf.pdf");
I also ended up modifying onAttach() because it was using the deprecated form of onAttach() and closeRenderer() because it was throwing errors for closing objects that were null.
So my complete PdfRendererBasicFragment.java file looks like this:
package com.example.android.pdfrendererbasic;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.pdf.PdfRenderer;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* This fragment has a big {#ImageView} that shows PDF pages, and 2 {#link android.widget.Button}s to move between
* pages. We use a {#link android.graphics.pdf.PdfRenderer} to render PDF pages as {#link android.graphics.Bitmap}s.
*/
public class PdfRendererBasicFragment extends Fragment implements View.OnClickListener {
/**
* Key string for saving the state of current page index.
*/
private static final String STATE_CURRENT_PAGE_INDEX = "current_page_index";
/**
* File descriptor of the PDF.
*/
private ParcelFileDescriptor mFileDescriptor;
/**
* {#link android.graphics.pdf.PdfRenderer} to render the PDF.
*/
private PdfRenderer mPdfRenderer;
/**
* Page that is currently shown on the screen.
*/
private PdfRenderer.Page mCurrentPage;
/**
* {#link android.widget.ImageView} that shows a PDF page as a {#link android.graphics.Bitmap}
*/
private ImageView mImageView;
/**
* {#link android.widget.Button} to move to the previous page.
*/
private Button mButtonPrevious;
/**
* {#link android.widget.Button} to move to the next page.
*/
private Button mButtonNext;
public PdfRendererBasicFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_pdf_renderer_basic, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Retain view references.
mImageView = (ImageView) view.findViewById(R.id.image);
mButtonPrevious = (Button) view.findViewById(R.id.previous);
mButtonNext = (Button) view.findViewById(R.id.next);
// Bind events.
mButtonPrevious.setOnClickListener(this);
mButtonNext.setOnClickListener(this);
// Show the first page by default.
int index = 0;
// If there is a savedInstanceState (screen orientations, etc.), we restore the page index.
if (null != savedInstanceState) {
index = savedInstanceState.getInt(STATE_CURRENT_PAGE_INDEX, 0);
}
showPage(index);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
openRenderer(context);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(context, "Error! " + e.getMessage(), Toast.LENGTH_SHORT).show();
getActivity().finish();
}
}
#Override
public void onDetach() {
try {
closeRenderer();
} catch (IOException e) {
e.printStackTrace();
}
super.onDetach();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (null != mCurrentPage) {
outState.putInt(STATE_CURRENT_PAGE_INDEX, mCurrentPage.getIndex());
}
}
/**
* Sets up a {#link android.graphics.pdf.PdfRenderer} and related resources.
*/
private void openRenderer(Context context) throws IOException {
// Copy the pdf to a usable location
CopyReadAssets();
File file = new File("/data/data/" + context.getPackageName() + "/files/sample.pdf");
mPdfRenderer = new PdfRenderer(ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY));
}
/**
* Closes the {#link android.graphics.pdf.PdfRenderer} and related resources.
*
* #throws java.io.IOException When the PDF file cannot be closed.
*/
private void closeRenderer() throws IOException {
if (mCurrentPage != null) {
mCurrentPage.close();
}
if (mPdfRenderer != null) {
mPdfRenderer.close();
}
if (mFileDescriptor != null) {
mFileDescriptor.close();
}
}
/**
* Shows the specified page of PDF to the screen.
*
* #param index The page index.
*/
private void showPage(int index) {
if (mPdfRenderer.getPageCount() <= index) {
return;
}
// Make sure to close the current page before opening another one.
if (null != mCurrentPage) {
mCurrentPage.close();
}
// Use `openPage` to open a specific page in PDF.
mCurrentPage = mPdfRenderer.openPage(index);
// Important: the destination bitmap must be ARGB (not RGB).
Bitmap bitmap = Bitmap.createBitmap(mCurrentPage.getWidth(), mCurrentPage.getHeight(),
Bitmap.Config.ARGB_8888);
// Here, we render the page onto the Bitmap.
// To render a portion of the page, use the second and third parameter. Pass nulls to get
// the default result.
// Pass either RENDER_MODE_FOR_DISPLAY or RENDER_MODE_FOR_PRINT for the last parameter.
mCurrentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
// We are ready to show the Bitmap to user.
mImageView.setImageBitmap(bitmap);
updateUi();
}
/**
* Updates the state of 2 control buttons in response to the current page index.
*/
private void updateUi() {
int index = mCurrentPage.getIndex();
int pageCount = mPdfRenderer.getPageCount();
mButtonPrevious.setEnabled(0 != index);
mButtonNext.setEnabled(index + 1 < pageCount);
getActivity().setTitle(getString(R.string.app_name_with_index, index + 1, pageCount));
}
/**
* Gets the number of pages in the PDF. This method is marked as public for testing.
*
* #return The number of pages.
*/
public int getPageCount() {
return mPdfRenderer.getPageCount();
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.previous: {
// Move to the previous page
showPage(mCurrentPage.getIndex() - 1);
break;
}
case R.id.next: {
// Move to the next page
showPage(mCurrentPage.getIndex() + 1);
break;
}
}
}
private void CopyReadAssets()
{
AssetManager assetManager = getActivity().getAssets();
InputStream in = null;
OutputStream out = null;
File file = new File(getActivity().getFilesDir(), "sample.pdf");
if(!file.exists()) {
try {
in = assetManager.open("sample.pdf");
out = getActivity().openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
else {
Log.d("test", "file already exists");
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
}
This code work on every android version:
Activity:
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Environment;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.util.Log;
import android.widget.Toast;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import unimedbh.UnimedBH.R;
public class MainActivity extends Activity {
private static final int MY_PERMISSION_REQUEST_STORAGE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSION_REQUEST_STORAGE);
} else {
copyReadAssets("YOUR_PDF_NAME.pdf");
}
}
private void copyReadAssets(String fileName) {
String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyFiles";
File dir = new File(dirPath);
if (!dir.exists()) {
dir.mkdirs();
}
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(fileName);
File outFile = new File(dirPath, fileName);
out = new FileOutputStream(outFile);
copyFile(in, out);
Intent intent = new Intent(Intent.ACTION_VIEW, FileProvider.getUriForFile(this, "com.package.name.fileprovider", outFile));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "Error!", Toast.LENGTH_SHORT).show();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
}
Manifest.xml:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.package.name.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
file_paths.xml:
<paths>
<files-path name="app_directory" path="directory/"/>
</paths>
Tested in API 16-28, worked on all api´s!

Updating the progress dialog on an uploading process

My program is uploading a video from SD Card without a problem but I am trying to add a progress dialog to show how much bytes uploaded so far in percentage. I am using async task. However, altough I am able to show the dialog on the screen. The dialog is not updating. After the upload finished it turns to 100/100 and it dissappears. Could you please help me how can I update the progress dialog?
package com.isoft.uploader2;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class Proje2Activity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button select =(Button)findViewById(R.id.select);
Button back =(Button)findViewById(R.id.back1);
Button camera =(Button)findViewById(R.id.camera);
//Select a video from SD-Card
select.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View arg0)
{
// TODO Auto-generated method stub
openGaleryVideo();
}
});
//Turn back
back.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View arg0)
{
// TODO Auto-generated method stub
finish();
}
});
//Record a video
camera.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View arg0)
{
// TODO Auto-generated method stub
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivity(intent);
}
});
}
/** Called when the activity is first created. */
public static final int SELECT_VIDEO=1;
public static final String TAG="UploadActivity";
String path="";
//Open Gallery
public void openGaleryVideo()
{
Intent intent=new Intent();
intent.setType("video/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Video"),SELECT_VIDEO);
}
//Select the video and start to execute the upload class
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK)
{
if (requestCode == SELECT_VIDEO)
{
Uri videoUri = data.getData();
path= getPath(videoUri);
upload upload = new upload();
upload.execute();
}
}
}
//Getting the URİ from the SD Card
public String getPath(Uri uri)
{
String[] projection = { MediaStore.Video.Media.DATA};
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
//ASYNC TASK Upload Class which uploads the file and shows the progress via a dialog
public class upload extends AsyncTask<Object, Integer, Void>
{
//Initializations
public ProgressDialog dialog;
File file=new File(path);
String urlServer = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
String filename=file.getName();
int bytesRead, bytesAvailable, bufferSize,progress;
byte[] buffer;
int maxBufferSize = 20*1024*1024;
//Before start to upload the file creating a dialog
#Override
public void onPreExecute()
{
dialog = new ProgressDialog(Proje2Activity.this);
dialog.setMessage("Uploading...");
dialog.setIndeterminate(false);
dialog.setTitle("UPLOADING");
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setProgress(0);
dialog.setMax(100);
dialog.show();
//Burada işlemi yapmadan önce ilk olarak ne yaptırmak istiyorsak burada yaparız.
//Örneğin burada dialog gösterip "onPostExecute()" metodunda dismiss edebiliriz.
}
//Uploading the file in background with showing the progress
#Override
public Void doInBackground(Object... arg0)
{
// TODO Auto-generated method stub
try
{
final FileInputStream fileInputStream = new FileInputStream(file);
URL url = new URL(urlServer);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setFixedLengthStreamingMode((int) file.length());
// Allow Inputs & Outputs
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
// Enable POST method
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "multipart/form-data");
connection.setRequestProperty("SD-FileName", filename);//This will be the file name
final DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
progress=0;
progress+=bytesRead;
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
publishProgress((int)((progress*100)/(file.length())));
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
progress+=bytesRead;
}//end of while statement
fileInputStream.close();
publishProgress(100);
outputStream.flush();
outputStream.close();
}//end of try body
catch (Exception ex)
{
//ex.printStackTrace();
Log.e("Error: ", ex.getMessage());
}
return null;
}//end of doInBackground method
//making an update on progress
#Override
public void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
dialog.setProgress(values[0]);
}//end of onProgressUpdate
//After finishing the progress the dialog will disappear!
#Override
public void onPostExecute(Void result)
{
try
{
dialog.dismiss();
} //End of the second try body
catch(Exception e)
{
}
}//end of onPostExecute method
}// end of asyncTask class
}//end of main
problems i noticed are :
your bufferSize can be total file length. so, in one read itself, the buffer can be full. i changed it to 512 to get noticeable change in progressbar
your resets progress variable inside the loop
also, you are writing the entire buffer (ie from 0 to bufferSize) to the output stream. not the actual `bytesRead. at the last portions you may get error values.
before reading again, you are not restting the buffer
updated code
bufferSize = 512;
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
progress=0;
while (bytesRead > 0)
{
progress+=bytesRead;
outputStream.write(buffer, 0, bytesRead);
bytesAvailable = fileInputStream.available();
publishProgress((int)((progress*100)/(file.length())));
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}//end of while statement
fileInputStream.close();
publishProgress(100);
outputStream.flush();
outputStream.close();
Your loop should look something like this, there was a couple of logical errors in your code.
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
progress=0;
progress+=bytesRead;
while (bytesRead > 0)
{
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
publishProgress((int)((progress/file.length())*100));
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
progress+=bytesRead;
}//end of while statement
Update: I just noticed, that you use a buffer with 20MB, change maxBufferSize to int maxBufferSize = 1024, and it should work.

Downloading pdf file and saving to SD card

I want to download and save pdf file to internal storage. Here is code that i am using:
I am calling my method from other class:
new Thread(new Runnable() {
public void run() {
new Main().downloadPdfContent("http://people.opera.com/howcome/2005/ala/sample.pdf");
}
}).start();
Method look like this:
public void downloadPdfContent(String urlToDownload){
URLConnection urlConnection = null;
try{
URL url = new URL(urlToDownload);
//Opening connection of currrent url
urlConnection = url.openConnection();
urlConnection.connect();
//int lenghtOfFile = urlConnection.getContentLength();
String PATH = Environment.getExternalStorageDirectory() + "/1/";
File file = new File(PATH);
file.mkdirs();
File outputFile = new File(file, "test.pdf");
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = url.openStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
is.close();
System.out.println("--pdf downloaded--ok--"+urlToDownload);
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
I found link of pdf on the web:
http://people.opera.com/howcome/2005/ala/sample.pdf
However i get an exception on this line:
urlConnection.connect();
Exception:
java.net.UnknownHostException: people.opera.com
I can't figure out what's wrong. Maybe someone could take a look.
Thanks.
Put
<uses-permission android:name="android.permission.INTERNET"/>
in your AndroidManifest.xml
Follow following steps :
1) Declare file name
String fileName;
//for image
fileName = "matchfine1.png";
//for pdf
fileName = "samplepdf.pdf";
2) Call method to invoke download process.
startDownload(fileName);
3) Define startDownload method:
//for download file start
private void startDownload(String filename) {
String filedowname = filename;
//for image
String url = "http://farm1.static.flickr.com/114/298125983_0e4bf66782_b.jpg";
//for pdf
String url = "http://people.opera.com/howcome/2005/ala/sample.pdf";
new DownloadFileAsync().execute(url,filedowname);
}
4) For auto loading progressBar:
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_DOWNLOAD_PROGRESS:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Downloading file..");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}
5) Define the download process extending AsyncTask
class DownloadFileAsync extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
#Override
protected String doInBackground(final String... aurl) {
try {
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File (root.getAbsolutePath() + "/Your_file_save_path/");
if(dir.exists()==false) {
dir.mkdirs();
}
URL url = new URL(aurl[0]);
String filename = aurl[1];
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(dir+"/"+filename);
byte data[] = new byte[1024];
long total = 0;
int count;
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]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
}
}
//for download file end
6) Replace "Your_file_save_path" by your file path in dir. and then download and check in the specified location.
I have used the same code and got Network.onThreadException Error. But then after using this piece of code in my oncreate() method, I was able to resolve the issue.
if (android.os.Build.VERSION.SDK_INT > 9)
{
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}

Categories