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!
Related
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 found an excellent UnZip class with progress bar support for Android. However the progress bar does not update when clicking extract in my app. The Unzipping works fine.
Can someone please tell me what I am doing wrong?
public class UnZip1 extends AsyncTask<Void, Integer, Integer> {
{
}
private String _zipFile;
private String _location;
private ProgressDialog mProgressDialog;
private int per = 0;
private Context _conti;
private ProgressBar bar1;
public UnZip1(Context conti,String zipFile, String location) {
_conti = conti;
_zipFile = zipFile;
_location = location;
bar1 = (ProgressBar)findViewById(R.id.pb1);
_dirChecker("");
}
public void streamCopy(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[32 * 1024]; // play with sizes..
int readCount;
while ((readCount = in.read(buffer)) != -1) {
out.write(buffer, 0, readCount);
}
}
protected Integer doInBackground(Void... params) {
try {
ZipFile zip = new ZipFile(_zipFile);
FileInputStream fin = new FileInputStream(_zipFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
Log.v("Decompress", "Unzipping " + ze.getName());
if(ze.isDirectory()) {
_dirChecker(ze.getName());
} else {
// Here I am doing the update of my progress bar
Log.v("Decompress", "more " + ze.getName());
per++;
publishProgress(per);
FileOutputStream fout = new FileOutputStream(_location + ze.getName());
streamCopy(zin, fout);
zin.closeEntry();
fout.close();
} }
zin.close();
} catch(Exception e) {
Log.e("Decompress", "unzip", e);
}
return null;
}
protected void onProgressUpdate(Integer... progress) {
bar1.setProgress(per);
}
protected void onPostExecute(Integer... result) {
Log.i("UnZip" ,"Completed. Total size: "+result);
}
private void _dirChecker(String dir) {
File f = new File(_location + dir);
if(!f.isDirectory()) {
f.mkdirs();
}
}
}
}
You have to use the ProgressDialog with STYLE_HORIZONTAL
if you want to see the actual progress.
You can add the initialization in your preExecute():
#Override
protected void onPreExecute()
{
super.onPreExecute();
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener()
{
public void onCancel(DialogInterface dialog)
{
}
});
mProgressDialog.setCancelable(true);
mProgressDialog.setMessage("Progress");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setProgress(1);
mProgressDialog.show();
}
MainActivity is the name of my activity class.
Then set the progress on the onProgressUpdate function.
protected void onProgressUpdate(Integer... progress)
{
mProgressDialog.setProgress(progress[0]);
}
Can you try this :
#Override
protected void onProgressUpdate(Integer... progress) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
bar1.setProgress(progress[0])
}
I hired someone to code my app. It loads a instrumental downloaded from the internet to my app. To download the instrumental it is fast but when loading the instrumental it takes a really long time at least a minute or more. I looked over the code to see where it would be slowing it down but i can't seem to figure it out. Any help is appreciated.
Code:
//File loading task
class SaveInputStreamTask extends AsyncTask<String, Integer, String> {
private Context context;
ProgressDialog mProgressDialog;
public SaveInputStreamTask(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
// mProgressDialog = new ProgressDialog(context);
//mProgressDialog.setMessage("Beat Will Take A Minute To Load When Mixing So Start Recording");
mProgressDialog = ProgressDialog.show(context, getResources().getString(R.string.app_name), "Beat Will Take Up To A Minute To Load. In The Meantime How's Your Day?");
mProgressDialog.show();
}
#Override
protected String doInBackground(String... sUrl) {
try
{
File file = new File(instrument_file_name);
long totalFilesize = file.length();
long readSize = 0;
FileInputStream fis = new FileInputStream(file);
saveInputStream(fis);
return "SUCCESS";
}
catch(Exception ex)
{
ex.printStackTrace();
}
return null;
}
#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) {
mProgressDialog.dismiss();
if(result == null){
Toast.makeText(context, "Loading Beat failed. Please try again", Toast.LENGTH_SHORT).show();
RecordRap.this.finish();
}
else
{
}
}
public void saveInputStream(InputStream is) throws IOException
{
int n = 0;
DataInputStream in1;
in1 = new DataInputStream(is);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try
{
while ((n = in1.read()) != -1)
{
bos.write(n);
}
}
catch (IOException e)
{
e.printStackTrace();
}
ByteBuffer bb = ByteBuffer.wrap(bos.toByteArray());
bb.order(ByteOrder.LITTLE_ENDIAN);
ShortBuffer sb = bb.asShortBuffer();
for (int i = 0; i < sb.capacity(); i++) {
beatsShortList.add(sb.get(i));
}
}
}
So thanks to #Stephen C the problem was while ((n = in1.read()) != -1) so i added a buffer and changed the code to the following and the problem is fixed now loading only takes a few seconds. Thanks to Stephen C for the help and as Ratul Sharker.
Updated code:
byte[] buffer = new byte[0xFFFF];
while ((n = in1.read(buffer)) != -1)
{
bos.write(buffer, 0, n);
}
for (int i = 0; i < sb.capacity(); i++) {
beatsShortList.add(sb.get(i));
}
This is the culprit what are you looking for :)
I'm using AWS's Java SDK to upload some files (>130 MBs) into an S3 bucket.
The issue I'm having is that during the upload process (using TransferManager), the getBytesTransferred() returns a number greater than that of the file size itself.
This is causing my Progress Dialog to hang at 100%.
Am I missing some sort of configuration?
I should point out that this doesn't happen all the time.
public class PutFileTask extends AsyncTask<Void, Long, UploadZipCode> {
#Override
protected UploadZipCode doInBackground(final Void... params) {
// Initialize S3 Client
BasicAWSCredentials credentials = new BasicAWSCredentials(mS3AccessKey, mS3SecretKey);
AmazonS3Client amazonS3Client = new AmazonS3Client(credentials);
mTransferManager = new TransferManager(credentials);
mUploadStart = new Date(System.currentTimeMillis());
Upload myUpload = mTransferManager.upload(mS3UploadBucket, mFile.getName(), mFile);
myUpload.addProgressListener(new ProgressListener() {
long totalBytesTransferred = 0;
#Override
public void progressChanged(ProgressEvent progressEvent) {
totalBytesTransferred += progressEvent.getBytesTransferred();
Log.d(TAG, "Bytes transferred = " + totalBytesTransferred);
onProgressUpdate(totalBytesTransferred);\
if (progressEvent.getEventCode() == ProgressEvent.COMPLETED_EVENT_CODE) {
cancel(true);
} else if (progressEvent.getEventCode() == ProgressEvent.FAILED_EVENT_CODE
|| progressEvent.getEventCode() == ProgressEvent.CANCELED_EVENT_CODE) {
Log.e(TAG, "Uploaded erred out with AWS Event Code: " + progressEvent.getEventCode());
cancel(true);
}
Log.d(TAG, "Setting completion code to: " + progressEvent.getEventCode());
}
});
try {
myUpload.waitForCompletion();
} catch (InterruptedException e) {
cancel(true);
e.printStackTrace();
return UploadZipCode.CONNECTION_ERROR;
} catch (Exception e) {
cancel(true);
e.printStackTrace();
return UploadZipCode.AWS_ERROR;
}
return UploadZipCode.UPLOAD_SUCCESS;
}
...
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(mActivity);
mProgressDialog.setTitle("Please wait...");
mProgressDialog.setMessage("Uploading your session zip file...");
mProgressDialog.setProgressStyle(mProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setProgress(0);
mProgressDialog.setMax((int) (mFile.length()));
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
...
#Override
protected void onProgressUpdate(Long... values) {
super.onProgressUpdate(values);
for (long value : values) {
mProgressDialog.setProgress((int) value);
}
}
...
#Override
protected void onPostExecute(UploadZipCode resultCode) {
super.onPostExecute(resultCode);
mProgressDialog.dismiss();
mListener.onUploadFinished(resultCode);
}
...
#Override
protected void onCancelled(UploadZipCode resultCode) {
super.onCancelled(resultCode);
if (mProgressDialog != null) {
mProgressDialog.dismiss();
}
mListener.onUploadFinished(resultCode);
}
}
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.