An issue in auto-updating.That downloads a new app if an update is available and uninstall a current application and install a new app. It all works well till target SDK 22. but After target SDK 24 or updating Phone os above API Level 2 this functionality not working Whenever I install it shows package parsing error. because of an old app is already there and we are trying to install a new app.
targetSDK:24
compileSDK:28
minSDK:19
Here is a piece of code:
public class UpdateActivity extends AppCompatActivity implements AppConstants {
public static final String TAG = UpdateActivity.class.getSimpleName();
private String appName = "XYZ.apk";
private final Handler mHideHandler = new Handler();
private View mContentView;
private TextView txtDownloading;
private NumberProgressBar numberProgressBar;
private String updateUrl = "";
private final Runnable mHidePart2Runnable = new Runnable() {
#SuppressLint("InlinedApi")
#Override
public void run() {
// Delayed removal of status and navigation bar
mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update);
updateUrl = getIntent().getStringExtra("url");
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build());
mContentView = findViewById(R.id.fullscreen_content);
mHideHandler.post(mHidePart2Runnable);
numberProgressBar = (NumberProgressBar) findViewById(R.id.numberbar8);
txtDownloading = (TextView) findViewById(R.id.txtDownload);
try {
new DownloadFileFromURL().execute();
} catch (Exception e) {
e.printStackTrace();
}
}
private class DownloadFileFromURL extends AsyncTask<String, Integer, String> {
DownloadFileFromURL() {
}
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... f_url) {
try {
HttpURLConnection c = (HttpURLConnection) new URL(updateUrl).openConnection();
c.setRequestMethod("POST");
c.setDoOutput(false);
c.connect();
int lengthOfFile = c.getContentLength();
File file = new File(Environment.getExternalStorageDirectory().getPath() + "/Download/");
file.mkdirs();
File outputFile = new File(file, appName);
if (outputFile.exists()) {
outputFile.delete();
}
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream();
byte[] data = new byte[AccessibilityNodeInfoCompat.ACTION_NEXT_HTML_ELEMENT];
long total1 = 0;
while (true) {
int count = is.read(data);
if (count == -1) {
break;
}
total1 += (long) count;
Integer[] strArr = new Integer[1];
strArr[0] = DOWNLOAD_COUNT + ((int) ((100 * total1) / ((long) lengthOfFile)));
publishProgress(strArr);
fos.write(data, 0, count);
}
fos.close();
is.close();
installApp();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
protected void onProgressUpdate(Integer... progress) {
try {
numberProgressBar.setUnreachedBarColor(Color.parseColor("#CCCCCC"));
numberProgressBar.setProgressTextSize(30.0f);
if (progress[0] > 0 && progress[0] <= 20) {
numberProgressBar.setProgressTextColor(Color.parseColor("#E74C3C"));
numberProgressBar.setReachedBarColor(Color.parseColor("#E74C3C"));
txtDownloading.setTextColor(Color.parseColor("#E74C3C"));
}
if (progress[0] > 20 && progress[0] <= 40) {
numberProgressBar.setProgressTextColor(Color.parseColor("#FF3D7F"));
numberProgressBar.setReachedBarColor(Color.parseColor("#FF3D7F"));
txtDownloading.setTextColor(Color.parseColor("#FF3D7F"));
}
if (progress[0] > 40 && progress[0] <= 60) {
numberProgressBar.setProgressTextColor(Color.parseColor("#FFC73B"));
numberProgressBar.setReachedBarColor(Color.parseColor("#FFC73B"));
txtDownloading.setTextColor(Color.parseColor("#FFC73B"));
}
if (progress[0] > 60 && progress[0] <= 80) {
numberProgressBar.setProgressTextColor(Color.parseColor("#6DBCDB"));
numberProgressBar.setReachedBarColor(Color.parseColor("#6DBCDB"));
txtDownloading.setTextColor(Color.parseColor("#6DBCDB"));
}
if (progress[0] > 80 && progress[0] <= 100) {
numberProgressBar.setProgressTextColor(Color.parseColor("#70A800"));
numberProgressBar.setReachedBarColor(Color.parseColor("#70A800"));
txtDownloading.setTextColor(Color.parseColor("#70A800"));
}
numberProgressBar.setProgress(progress[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
protected void onPostExecute(String file_url) {
numberProgressBar.setVisibility(View.GONE);
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
private void installApp() {
try {
File apkFile = new File(Environment.getExternalStorageDirectory().getPath() + "/Download/", appName);
Intent intent = new Intent("android.intent.action.VIEW");
intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
}
I faced the same issue, and resolved it using the following:
Disabling Google Play Protect from playstore app worked the trick, i-e it was blocking the installation from external sources and i was able to get rid of the parse error.
On Android N and above, to give access to particular file or folder to make them accessible for other apps, you cant use File Uri, instead you have to use Provider Uri from FileProvider class , otherwise we get the FileUriExposedException such as android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData() etc.
For more information to how to setup FileProvider, see this guide:
https://developer.android.com/reference/android/support/v4/content/FileProvider
Hope this helps.
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.
When my application tries to download a file from an Ftp server (running on a Pi zero W with DietPi) it throws the error above, but when I tried with other phones(Xiaomi Redmi 4x with android 6.0 and Samsung Galaxy J5 running on android 7.0) the error does not occur, only on the Samsung galaxy s7 running android 7.0. Also, uploading still works from the same phone
Invalid server reply (MLST): '250-modify=20180603012615;perm=adfrw;size=3679098;type=file;unique=801U4A;UNIX.group=0;UNIX.mode=0777;UNIX.owner=0; /C-jegyzet.pdf'
And the class that throws the error:
private class DownloadFileAsync extends AsyncTask<String, Long, Boolean>
{
ProgressBar downloadProgressbar;
TextView titleTextView;
TextView nameTextView;
TextView percentageTextView;
TextView completedTextView;
CardView downloadCardView;
boolean isFirstCall = true;
String name;
Long fileLength;
String errorMessage = Constants.ErrorCodes.NO_ERROR_CODE;
int progress;
#Override
protected Boolean doInBackground(String... strings)
{
int port = 21;
FTPClient client = new FTPClient();
try
{
client.connect(server, port);
client.login(username, password);
client.enterLocalPassiveMode();
client.setFileType(FTPClient.BINARY_FILE_TYPE);
client.setBufferSize(1);
File fileToWrite = new File(strings[2] + "/" + strings[1]);
name = strings[1];
OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(fileToWrite));
fileLength = client.mlistFile(strings[0]).getSize();
client.setCopyStreamListener(new CopyStreamListener() {
#Override
public void bytesTransferred(CopyStreamEvent copyStreamEvent)
{
}
#Override
public void bytesTransferred(long l, int i, long l1)
{
progress += i;
if(progress > 50000)
{
progress = 0;
publishProgress(l, l1);
}
}
});
boolean isSuccessful = client.retrieveFile(strings[0], outputStream);
client.logout();
outputStream.close();
return isSuccessful;
} catch (IOException e) {
errorMessage = e.getMessage();
Log.d("ftperror", errorMessage);
return false;
}
}
#Override
protected void onProgressUpdate(Long... values)
{
//int percentage = Math.round((float)(values[0] / fileLength) * 100);
float c = (((float)values[0]/(float)fileLength)*100);
int percentage = Math.round(c);
if(isFirstCall)
{
isFirstCall = false;
downloadCardView = ((Activity) context).findViewById(R.id.downloadingCardView);
downloadProgressbar = ((Activity) context).findViewById(R.id.downloadingProgressBar);
titleTextView = ((Activity) context).findViewById(R.id.downloadingTitleTextView);
nameTextView = ((Activity) context).findViewById(R.id.donwloadingNameTextView);
percentageTextView = ((Activity) context).findViewById(R.id.downloadingPercentageTextView);
completedTextView = ((Activity) context).findViewById(R.id.downloadingCompletedTextView);
downloadCardView.setVisibility(View.VISIBLE);
titleTextView.setText(R.string.file_handler_downloading);
nameTextView.setText(name);
downloadProgressbar.setProgress(0);
}
downloadProgressbar.setProgress(percentage);
percentageTextView.setText(percentage + "%");
completedTextView.setText(android.text.format.Formatter.formatShortFileSize(context, values[0]) + "/" + android.text.format.Formatter.formatShortFileSize(context, fileLength));
}
#Override
protected void onPostExecute(Boolean aBoolean)
{
if(!isFirstCall)
{
downloadCardView.setVisibility(View.GONE);
}
if (aBoolean)
{
Toast.makeText(context, R.string.file_handler_download_success, Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(context, R.string.file_handler_download_failure, Toast.LENGTH_LONG).show();
if (!errorMessage.equals(Constants.ErrorCodes.NO_ERROR_CODE))
{
DisplayFilesActivity displayFilesActivity = (DisplayFilesActivity)context;
displayFilesActivity.showError(errorMessage);
}
}
}
}
I figured it out. The problem was not with the retrieve file but actually with the mlist method. Turns out my ftp server doesn't actually support the command. Using a list with the file as the argument had the same effect and my code works with that
As a preface, I am familiar with coding (2 years in highschool) but am a complete novice when it comes to Android Studio (and Java, in general). I've been searching for solutions for my problem, but due to my inexperience I have no idea how to implement the solutions to my project.
In short, I need to download a pdf from some external URL, store it into external storage, and display it using some pdf-viewer application. I've been getting error:
...
android.os.FileUriExposedException: file:///storage/emulated/0/pdf/Read.pdf exposed beyond app through Intent.getData()
...
I've been using this source on using an intent to open a pdf-viewer and this source on "File Provider" as references.
Below is what I have so far:
Fire (with a clickable TextView that should download and display the pdf)
public class Fire extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fire);
final TextView testButton = findViewById(R.id.testPDF);
// File file = getFilesDir();
testButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Fire.this, pdfView.class);
startActivity(intent);
}
});
pdfView activity
public class pdfView extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdf_view);
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File folder = new File(extStorageDirectory, "pdf");
folder.mkdir();
File file = new File(folder, "Read.pdf");
try {
file.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
Downloader.DownloadFile(__PDF_URL___, file);
showPdf();
}
public void showPdf()
{
File file = new File(Environment.getExternalStorageDirectory()+"/pdf/Read.pdf");
PackageManager packageManager = getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType("application/pdf");
List list = packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
}
Downloader class
public class Downloader {
public static void DownloadFile(String fileURL, File directory) {
try {
FileOutputStream f = new FileOutputStream(directory);
URL u = new URL(fileURL);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
} catch (Exception e) {
e.printStackTrace();
}
}
From my research, it seems that my problem stems from my usage of URI instead of a "File provider." Also, it seems the solution that implements a "File Provider" uses Context in some form or another, and I'm confused on what the purpose of context is and how to implement it.
If you do not have answers that is fine. Any information on how to figure this out or even understand the concept is good enough for me.
If your targetSdkVersion >= 24, then we have to use FileProvider class to give access to the particular file or folder to make them accessible for other apps.
1) First Add a FileProvider tag in AndroidManifest.xml under tag as below:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
...
<application
...
<provider
android:name=".GenericFileProvider"
android:authorities="${applicationId}.my.package.name.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
</application>
</manifest>
2) Then create a provider_paths.xml file in res/xml folder. Folder may be needed to created if it doesn't exist.
<paths>
<external-path name="external_files" path="."/>
</paths>
3) Now create PdfDownload.java class file and paste below code:
public class PdfDownload extends Activity {
TextView tv_loading;
Context context;
int downloadedSize = 0, totalsize;
float per = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
isStoragePermissionGranted();
super.onCreate(savedInstanceState);
tv_loading = new TextView(this);
tv_loading.setGravity(Gravity.CENTER);
tv_loading.setTypeface(null, Typeface.BOLD);
setContentView(tv_loading);
downloadAndOpenPDF();
}
public static String getLastBitFromUrl(final String url) {
return url.replaceFirst(".*/([^/?]+).*", "$1");
}
void downloadAndOpenPDF() {
final String download_file_url = getIntent().getStringExtra("url");
new Thread(new Runnable() {
public void run() {
Uri path = Uri.fromFile(downloadFile(download_file_url));
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri uri = FileProvider.getUriForFile(PdfDownload.this, BuildConfig.APPLICATION_ID, downloadFile(download_file_url));
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
finish();
} catch (ActivityNotFoundException e) {
tv_loading
.setError("PDF Reader application is not installed in your device");
}
}
}).start();
}
File downloadFile(String dwnload_file_path) {
File file = null;
try {
URL url = new URL(dwnload_file_path);
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.connect();
String test = getLastBitFromUrl(dwnload_file_path);
String dest_file_path = test.replace("%20", "_");
// set the path where we want to save the file
File SDCardRoot = Environment.getExternalStorageDirectory();
// // create a new file, to save the downloaded file
file = new File(SDCardRoot, dest_file_path);
if (file.exists()) {
return file;
}
FileOutputStream fileOutput = new FileOutputStream(file);
// Stream used for reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
// this is the total size of the file which we are
// downloading
totalsize = urlConnection.getContentLength();
setText("Starting PDF download...");
// create a buffer...
byte[] buffer = new byte[1024 * 1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
per = ((float) downloadedSize / totalsize) * 100;
if ((totalsize / 1024) <= 1024) {
setText("Total PDF File size : " + (totalsize / 1024)
+ " KB\n\nDownloading PDF " + (int) per + "% complete");
} else {
setText("Total PDF File size : " + (totalsize / 1024) / 1024
+ " MB\n\nDownloading PDF " + (int) per + "% complete");
}
// setText("configuring your book pleease wait a moment");
}
// close the output stream when complete //
fileOutput.close();
// setText("Download Complete. Open PDF Application installed in the device.");
setText("configuaration is completed now your book is ready to read");
} catch (final MalformedURLException e) {
setTextError("Some error occured. Press back and try again.",
Color.RED);
} catch (final IOException e) {
setTextError("Some error occured. Press back and try again.",
Color.RED);
} catch (final Exception e) {
setTextError(
"Failed to download image. Please check your internet connection.",
Color.RED);
}
return file;
}
void setTextError(final String message, final int color) {
runOnUiThread(new Runnable() {
public void run() {
tv_loading.setTextColor(color);
tv_loading.setText(message);
}
});
}
void setText(final String txt) {
runOnUiThread(new Runnable() {
public void run() {
tv_loading.setText(txt);
}
});
}
private static final String TAG = "MyActivity";
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG, "Permission is granted");
return true;
} else {
Log.v(TAG, "Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
} else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG, "Permission is granted");
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.v(TAG, "Permission: " + permissions[0] + "was " + grantResults[0]);
}
}
}
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!