I'm apologise for my english.
I use the following piece of code to download a file from ftp host to Tablet. When I use Wi-Fi everything works well. But when I try to download a file using the mobile Internet, the download stops, but not always, sometimes finishes normally. I've found that stop is always going on "retrieveFile" or "logout", the program comes to these commands and no going further, and simply stands, the icon of data transfer does not blink, stops occur randomly. I tried to use different mobile operators, but there is no difference. What could be the reason?
And another question, but It is not so important, I've not found how to get the file size, and used my decision, maybe there is another way to get the file size ?
private void downloadFile(final String url, final String Message, final String Message2, final Uri uri) {
final ProgressDialog progressDialog = new ProgressDialog(this);
new AsyncTask() {
private Exception m_error = null;
#Override
protected void onPreExecute() {
progressDialog.setMessage(Message);
progressDialog.setCancelable(true);
progressDialog.setMax(100);
progressDialog
.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.show();
}
#Override
protected File doInBackground(String... params) {
FileOutputStream fos = null;
File file = null;
FTPClient client = null;
try{
client = new FTPClient();
client.connect(ftp_host,Integer.parseInt(ftp_port));
client.login(ftp_user, ftp_password);
client.enterLocalPassiveMode();
client.setFileType(FTP.BINARY_FILE_TYPE);
String stat = "";
if (url.equals("MobiTrade.apk")){
client.changeWorkingDirectory("/var/srv/home/user/mobitrade/update/");}
file = new File(Environment.getExternalStorageDirectory(),
"/MobiTrade/update/MobiTrade.apk");}
stat = client.getStatus("/var/srv/home/user/mobitrade/update/MobiTrade.apk");
else {
client.changeWorkingDirectory("/var/srv/home/user/mobitrade/"+number+"/out/");
file = new File(Environment.getExternalStorageDirectory(),
"/MobiTrade/in/"+url);
if (url.equals("message.csv")) file.delete();
stat = client.getStatus("/var/srv/home/user/mobitrade/"+number+"/out/"+url);
}
final Integer FileSize;
if (stat.length() >= 64) {
stat = stat.substring(49,64);
stat = stat.trim();
FileSize = Integer.parseInt(stat);
}
else {
FileSize = 0;
}
fos = new FileOutputStream(file);
CountingOutputStream cos = new CountingOutputStream(fos){
protected void beforeWrite(int n){
super.beforeWrite(n);
publishProgress(getCount(), FileSize);
}
};
if (url.equals("MobiTrade.apk")){
client.retrieveFile("/var/srv/home/user/mobitrade/update/MobiTrade.apk", cos);
}
else {
client.retrieveFile("/var/srv/home/user/mobitrade/"+number+"/out/"+url, cos);
}
if (url.equals("message.csv")){
client.deleteFile("/var/srv/home/user/mobitrade/"+number+"/out/"+url);
}
client.logout();
}
catch (Exception e){
e.printStackTrace();
}
finally{
try{
if (fos != null) fos.close();
if (client.isConnected()) {
client.disconnect();
}
}
catch (IOException e){
e.printStackTrace();
}
}
return file;
}
protected void onProgressUpdate(Integer... values) {
progressDialog
.setProgress((int) ((values[0] / (float) values[1]) * 100));
};
#Override
protected void onPostExecute(File result) {
if (m_error != null) {
m_error.printStackTrace();
return;
}
progressDialog.hide();
if (url.equals("settings.csv"))
ProcessSettings(url);
else if (url.equals("MobiTrade.apk"))
ProcessUpdate();
else
ProcessData(url, Message2, uri);
}
}.execute(url);
}
Any help would be appreciable.
Related
I wrote a program that
Download the photo from the url...
But I have a problem...
Some photos are downloaded.
And there is no problem.
But some of the pictures are not downloadable incompletely :(
and in the file manager I look at
it is broken
Can you help?
my code is:
public class DownloadFileFromURL_img extends AsyncTask {
private viewHolderPost holderPOST;
public DownloadFileFromURL_img(viewHolderPost holderPOST) {
Log.d(TAG, "DownloadFileFromURL_img: ");
this.holderPOST = holderPOST;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
* Downloading file in background thread
*/
#Override
protected String doInBackground(String... f_url) {
int count;
try {
File file = new File(Environment.getExternalStorageDirectory(), "98Diha/img");
if (!file.exists()) {
if (!file.mkdirs()) {
file.createNewFile();
}
}
InputStream input = null;
int response = -1;
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
if (!(conection instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
try{
HttpURLConnection httpConn = (HttpURLConnection) conection;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
input = httpConn.getInputStream();
}
}
catch (Exception ex)
{
throw new IOException("Error connecting");
}
int lenghtOfFile = conection.getContentLength();
input = new BufferedInputStream(url.openStream());
String imgS[] = f_url[0].split("/");
String name = imgS[imgS.length - 1];
String path = Environment
.getExternalStorageDirectory().toString()
+ "/98diha/img/" + name;
File filePath = new File(path);
if (!filePath.exists()) {
OutputStream output = new FileOutputStream(path);
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();
} else {
SSToast(context, "Exist!");
holderPOST.dowload_img.setVisibility(View.GONE);
holderPOST.setWallpaper.setVisibility(View.VISIBLE);
holderPOST.setWallpaper.setText(context.getString(R.string.set_wp));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
holderPOST.setWallpaper.setTextColor(ContextCompat.getColor(context, R.color.Teal_400));
} else {
holderPOST.setWallpaper.setTextColor(context.getResources().getColor(R.color.Teal_400));
}
}
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
/**
* Updating progress bar
*/
protected void onProgressUpdate(String... progress) {
holderPOST.dowload_img.setVisibility(View.GONE);
holderPOST.setWallpaper.setVisibility(View.VISIBLE);
holderPOST.setWallpaper.setText(context.getString(R.string.dowloading));
}
/**
* After completing background task Dismiss the progress dialog
**/
#Override
protected void onPostExecute(String file_url) {
holderPOST.setWallpaper.setText(context.getString(R.string.set_wp));
holderPOST.setWallpaper.setTextColor(context.getResources().getColor(R.color.Teal_400));
Log.d(TAG, "onPostExecute: ");
}
}
Instead of using AsyncTask to download images from URL. You can use libraries such as Glide or Picasso to do it quickly just in one line. But if you don't want to use libraries than you could use DownloadManager to download it and save it in a file. You can check this tutorial or other tutorials on the web for the implementation of DownloadManager.
I am trying to download an apk file to update my application and apk is placed in ftp server and I am downloading that apk using FTP Client.
Even though I call mProgress.setProgress(percent);
the ProgressBar is not getting updated from the function where I download the apk file by ftp
public class UpdateAppByFTP extends AsyncTask<String,Void,Void> {
private Context context;
CopyStreamAdapter streamListener;
public void setContext(Context mContext){
context = mContext;
}
private ProgressDialog mProgress;
#Override
protected void onPreExecute(){
super.onPreExecute();
mProgress = new ProgressDialog(this.context);
mProgress.setMessage("Downloading new apk .. Please wait...");
mProgress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//mProgress.setIndeterminate(true);
mProgress.show();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
mProgress.dismiss(); //Dismiss the above Dialogue
}
#Override
protected Void doInBackground(String... arg0) {
try {
String serverName = arg0[0];
String userName = arg0[1];
String password = arg0[2];
String serverFilePath = arg0[3];
String localFilePath = arg0[4]; if(getFileByFTP(serverName,userName,password,serverFilePath,localFilePath)){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(localFilePath)), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error!
context.startActivity(intent);
}else{
//Do nothing could not download
}
String apkLocation="/download/"+"SmartPOS.apk";
Intent intent1 = new Intent(Intent.ACTION_VIEW);
intent1.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() +apkLocation)), "application/vnd.android.package-archive");
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error!
context.startActivity(intent1);
} catch (Exception e) {
}
return null;
}
//Below code to download using FTP
public boolean getFileByFTP(String serverName, String userName,
String password, String serverFilePath, String localFilePath)
throws Exception {
FTPClient ftp = new FTPClient();
try {
ftp.connect(serverName);
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return false;
}
} catch (IOException e) {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException f) {
throw e;
}
}
throw e;
} catch (Exception e) {
throw e;
}
try {
if (!ftp.login(userName, password)) {
ftp.logout();
}
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ftp.enterLocalPassiveMode();
final int lenghtOfFile =(int)getFileSize(ftp,serverFilePath);
OutputStream output = new FileOutputStream(localFilePath);
CountingOutputStream cos = new CountingOutputStream(output) {
protected void beforeWrite(int n) {
super.beforeWrite(n);
int percent = Math.round((getCount() * 100) / lenghtOfFile);
Log.d("FTP_DOWNLOAD", "bytesTransferred /downloaded"+percent);
System.err.println("Downloaded "+getCount() + "/" + percent);
mProgress.setProgress(percent);
}
};
ftp.setBufferSize(2024*2048);//To increase the download speed
ftp.retrieveFile(serverFilePath, output);
output.close();
ftp.noop(); // check that control connection is working OK
ftp.logout();
return true;
}
catch (FTPConnectionClosedException e) {
Log.d("FTP_DOWNLOAD", "ERROR FTPConnectionClosedException:"+e.toString());
throw e;
} catch (IOException e) {
Log.d("FTP_DOWNLOAD", "ERROR IOException:"+e.toString());
throw e;
} catch (Exception e) {
Log.d("FTP_DOWNLOAD", "ERROR Exception:"+e.toString());
throw e;
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException f) {
throw f;
}
}
}
}
private static long getFileSize(FTPClient ftp, String filePath) throws Exception {
long fileSize = 0;
FTPFile[] files = ftp.listFiles(filePath);
if (files.length == 1 && files[0].isFile()) {
fileSize = files[0].getSize();
}
Log.d("FTP_DOWNLOAD", "File size = " + fileSize);
return fileSize;
}
}
Basically, the UI Does not get updated, also I am not sure whether the CountingOutputStream is the correct method to find the downloaded size of the file.
Thanks in advance.
I changed this retrieveFile section of the code and it is fine now
ftp.retrieveFile(serverFilePath, cos);
I tried your solution, it worked fine for me for file sizes up to 30 MB from FTP, going above, the download crashed every time. So I assumed the getCount() method as it is being called every time would result in some issue.
I even tried running the getCount() on separate thread, but still no use.
So finally I changed percent (for progress) variable to fraction of FileSize of local/FTP file size. So in above case it will be:
int percent = Math.round(output.length() * 100) / lenghtOfFile);
Works fine.
I've been getting very strange behavior from my code.
Basically, my code is using an Input/Output stream to download a .pdf file from the internet, saving it to internal storage (using an AsyncTask) and then outputting it using an outside "showPdf" library.
The strangest thing is that it only works on two conditions:
I run the code twice (run or debug without any break points). The first run logs File is empty when showPdf() is called, but the second run through runs perfectly fine when showPdf() is called on its own.
I debug the code and step through the program
As a preface, I'm new to java and android studio, so my guess may not be right at all, but I'm guessing since the InputStream is being done "asynchronously", showPdf() may be called before the byte[] array is written into memory. If this is the case, what could I do to delay Async long enough to work?
public class pdfView extends AppCompatActivity {
PDFView pdfView; //pdfView object
String URL;
String fileName;
File directory; //path of created File
// Container for all parameters of DownloadAsync
private static class AsyncParameters {
String URL;
File directory;
AsyncParameters(String URL, File directory) {
this.URL = URL;
this.directory = directory;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdf_view);
//Grab the extras from the intent call
Intent intent = getIntent(); //whatever calls this activity, gather the intent
URL = intent.getStringExtra("File URL"); // in this case, get the file name of the "extra" passed through
fileName = intent.getStringExtra("File Name");
//Grab the internal storage directory and create a folder if it doesn't exist
File intDirectory = getFilesDir();
File folder = new File(intDirectory, "pdf");
boolean isDirectoryCreated = folder.exists();
//See if the file exists
if (!isDirectoryCreated) {
isDirectoryCreated= folder.mkdir();
}
if(isDirectoryCreated) {
directory = new File(folder, fileName);
try {
directory.createNewFile();
if (directory.canWrite())
Log.d("hngggggggggggggg", "onCreate: ");
} catch (IOException e1) {
e1.printStackTrace();
}
//See if file already exists
boolean empty = directory.length() == 0;
if (empty){
/**Call class to create parameter container**/
AsyncParameters param = new AsyncParameters(URL, directory);
DownloadAsync Downloader = new DownloadAsync();
Downloader.execute(param);
showPdf();
}
else
showPdf();
}
}
public void showPdf()
{
pdfView = (PDFView) findViewById(R.id.pdfView);
pdfView.fromFile(directory).load();
}
/**Class for asynchronous tasks**/
public class DownloadAsync extends AsyncTask<AsyncParameters, Void, Void> {
// Container for all parameters of DownloadAsync
ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(pdfView.this);
pDialog.setMessage("Downloading Database...");
String message= "Downloading Files";
SpannableString ss2 = new SpannableString(message);
ss2.setSpan(new RelativeSizeSpan(2f), 0, ss2.length(), 0);
ss2.setSpan(new ForegroundColorSpan(Color.BLACK), 0, ss2.length(), 0);
pDialog.setMessage(ss2);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(AsyncParameters... params) {
Log.d("WE ARE IN DOBACKGROUND", "doInBackground: ");
String fileURL = params[0].URL;
File directory = params[0].directory;
try {
FileOutputStream f = new FileOutputStream(directory);
java.net.URL u = new URL(fileURL);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.connect();
InputStream in = c.getInputStream();
byte[] buffer = new byte[8192];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
} catch (Exception e) {
e.printStackTrace();
}
onPostExecute();
return null;
}
protected void onPostExecute() {
pDialog.dismiss();
}
}
}
You already have answered your own question. Since the download is asyncTask running on a different thread, there is no wait for the asyncTask to complete before showPdf() is called. You can call showPdf() from onPostExecute() which is called after the background task completes. Your code should look like:
#Override
protected void onCreate(Bundle savedInstanceState) {
........
........
AsyncParameters param = new AsyncParameters(URL, directory);
DownloadAsync Downloader = new DownloadAsync();
Downloader.execute(param);
.......
.......
}
public class DownloadAsync extends AsyncTask<AsyncParameters, Void, Void> {
.......
#Override
protected void onPostExecute() {
pDialog.dismiss();
showPdf();
}
}
Please help me to add update code to my app to be update from my server thank you
nothing worked from net , i need complete guide
You can't install your app without users permission and root access but you can download your applications new version from server then ask users for install. Here is an example:
{
PackageManager manager = context.getPackageManager();
try {
PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
version = info.versionName;
if (newversion.replace(".", "") < version.replace(".", "")) {
new DownloadFileFromURL().execute("http://exampl.com/Content/files/example.apk");
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
private class DownloadFileFromURL extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = onCreateDialog();
}
#Override
protected String doInBackground(String... f_url) {
int count;
try {
File file = new File(Environment.getExternalStorageDirectory() + "/example.apk");
if (file.exists()) {
file.delete();
}
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
int lenghtOfFile = conection.getContentLength();
pDialog.setMax(lenghtOfFile / 1024);
InputStream input = new BufferedInputStream(url.openStream(), 8192);
OutputStream output = new FileOutputStream(Environment.getExternalStorageDirectory() + "/example.apk");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(total / 1024 + "");
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception ignored) {
}
return null;
}
protected void onProgressUpdate(String... progress) {
pDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String file_url) {
dialog.dismiss();
File file = new File(Environment.getExternalStorageDirectory() + "/example.apk");
if (file.exists()) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} else {
//finish() or whatever you want
}
}
}
I'm using Apache's FTPClient to upload files to my server (images from the gallery if it matters)
I'm having a small and pretty insignificant problem, but I would still like to solve it.
The problem is that the bar is filled and reaches 100% before the upload actually completes, causing the dialog to show 100% for an extra 2-3 seconds on small files (and could be a lot more on files weighing several MBs).
I'm guessing it's because of the conversion from long to int, but that's just a guess.
Here's the code:
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(UploadActivity.this);
dialog.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
uploadImage.cancel(true);
}
});
dialog.setMessage("Uploading...\nPlease Wait.");
dialog.setIndeterminate(false);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setProgress(0);
dialog.setCancelable(false);
dialog.setMax((int)(file.length()/1024));
dialog.setProgressNumberFormat ("%1dKB/%2dKB");
dialog.show();
}
#Override
protected String doInBackground(Void... params) {
CopyStreamAdapter streamListener = new CopyStreamAdapter() {
#Override // THIS PART IS RESPONSIBLE FOR UPDATING THE PROGRESS
public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize) {
int percent = (int) (totalBytesTransferred * 100 / file.length());
publishProgress(percent);
}
};
String name = null;
ftp.setCopyStreamListener(streamListener);
FileInputStream fis = null;
try {
String extension = "";
String fileName = file.getName();
int i = fileName.lastIndexOf('.');
int p = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));
if (i > p) {
extension = fileName.substring(i + 1);
}
SimpleDateFormat sdf = new SimpleDateFormat("ddMMyy-hhmmss-SSS");
name = String.format("File-%s.%s", sdf.format(new Date()), extension);
ftp.connect(FTP_SERVER);
ftp.enterLocalPassiveMode();
ftp.login(ftpUser, ftpPassword);
ftp.setFileType(FTP.BINARY_FILE_TYPE);
fis = new FileInputStream(file);
if (!ftp.storeFile(name, fis)) {
showToast("Failed uploading");
return null;
}
ftp.logout();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return name;
}
#Override
protected void onProgressUpdate(Integer... values) {
dialog.setProgress(values[0]);
}
Thanks!