I want to add checking update function in android app
I know this question is asked already and post a lib on Github
How to allow users to check for the latest app version from inside the app?
but my cant i post on the Google Play Store due to some problem of copyright
So i cant use the method
what should i do?
Your code to check update once in a day. only works when you open app once in a day. in onCreate() of your launcher activity.
SharedPreferences mSettings = PreferenceManager.getDefaultSharedPreferences
(Dashboard.this);
long lastUpdateTime = mSettings.getLong("lastUpdateTime", 0);
/* Should Activity Check for Updates Now? */
if ((lastUpdateTime + (24 * 60 * 60 * 1000)) < System.currentTimeMillis()) {
/* Save current timestamp for next Check*/
SharedPreferences.Editor editor = mSettings.edit();
lastUpdateTime = System.currentTimeMillis();
editor.putLong("lastUpdateTime", lastUpdateTime);
editor.commit();
/* Start Update by using asynctask that run in backGround eg. http://portal.aksuniversity.com:8089/utility/apkversion*/
String URL = "your app url in my case ;
AsyncRequest asyncRequestTime = new AsyncRequest(Dashboard.this, "GET", null,
null, 3);
asyncRequestTime.execute(URL);
}
the response you will get is json object. get jsonObject key of version code and match it with your app version code
int versionCode = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0).versionCode;
if (versionCode < jsonObject.getString(""VersionCode))
//if greater show dialog for app update and download apk with new url of your app which will give you apk
for download you can use
private String callApiDownload(String address) {
try {
URL url = new URL(address);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
if (Cookie.getCookie() != null)
urlConnection.addRequestProperty("Cookie", Cookie.getCookie());
if (urlConnection.getResponseCode() == 200) {
File file = new File(Environment.getExternalStorageDirectory() + "/" + folderName);
boolean fileExist = true;
if (!file.exists()) {
fileExist = file.mkdir();
}
if (fileExist) {
String FileName = Environment.getExternalStorageDirectory() + "/" + folderName + "/"
+ fileName;
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream outputStream = new FileOutputStream(FileName);
int bytesRead;
byte[] buffer = new byte[4096];
int total = 0;
int contentLength = urlConnection.getContentLength();
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {
publishProgress((int) ((total * 100) / contentLength));
}
}
outputStream.flush();
outputStream.close();
inputStream.close();
return fileName;
}
} else {
InputStream inputStream = new BufferedInputStream(urlConnection.getErrorStream());
return fileName = Connection.convertInputStreamToString(inputStream);
}
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return fileName;
}
on download complete you can use intent to open apk for installation which will prompmt user for new update apk installation.
The first code will call the api once a day when user open the app. This api will return the json object of your app version code and version name. You need to manually maintain it when you create new apk for user. Parse the json object. And get the version code. In your app check if api version code is greater than your app version code. And if it is than fire a new api which is the last code i have given that download the your apk from url(in server you have to place apk for specified urlby calling which your apk will downloaded) which is last code you need to run in backthread asynctak. I will create the source code more proper and notifie you.
Related
i have create a modul to download file from server to my android apps like this
#Override
protected String doInBackground(String... f_url) {
int count;
try {
URL url = new URL(f_url[0]);
URLConnection connection = url.openConnection();
connection.connect();
// getting file length
int lengthOfFile = connection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
String timestamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
//Extract file name from URL
fileName = f_url[0].substring(f_url[0].lastIndexOf('/') + 1, f_url[0].length());
//Append timestamp to file name
fileName = timestamp + "_" + fileName;
//External directory path to save file
folder = Environment.getExternalStorageDirectory() + File.separator + "simpel/";
//Create androiddeft folder if it does not exist
File directory = new File(folder);
if (!directory.exists()) {
directory.mkdirs();
}
// Output stream to write file
OutputStream output = new FileOutputStream(folder + fileName);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress("" + (int) ((total * 100) / lengthOfFile));
Log.d(TAG, "Progress: " + (int) ((total * 100) / lengthOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
return "Downloaded at: " + folder + fileName;
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return "Something went wrong";
}
but when i try to download, i always get error like this
E/Error::
/storage/emulated/0/simpel/2019.07.06.18.57.51_REGISTER_TILANG.xlsx
(Permission denied)
even though I have added this to my manifest
android.permission.READ_EXTERNAL_STORAGE
android.permission.WRITE_EXTERNAL_STORAGE
i use this libary:
implementation 'pub.devrel:easypermissions:0.2.0'
I know it's been more than a year but I hope this helps someone.
I worked with your code now and I found out the mistake you might have made.
You might have added these android.permission.READ_EXTERNAL_STORAGE android.permission.WRITE_EXTERNAL_STORAGE to your manifest.xml but you need to ask for the permission in your code.
Even using the library (same I used) implementation 'pub.devrel:easypermissions:0.2.0' it seems you didn't check for both READ and WRITE permissions (something like this):
private static final int WRITE_REQUEST_CODE = 1;
if (EasyPermissions.hasPermissions(DownloadActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
//your asyncTask to download
downloadFile.execute(url);
} else {
//If permission has no be granted, request
EasyPermissions.requestPermissions(DownloadActivity.this, "This app needs access to your file storage" , WRITE_REQUEST_CODE, Manifest.permission.READ_EXTERNAL_STORAGE);
}
Notice that in the code above, only WRITE permission was checked. If there isn't, then READ permission was requested (which is kind of contradictory). The correct would be checking for both permissions then if either of them has not been granted, the system will request for thr two. Compare the following code:
private static final int REQUEST_CODE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
if (EasyPermissions.hasPermissions(DownloadActivity.this, PERMISSIONS_STORAGE)) {
//your asyncTask to download
downloadFile.execute(url);
} else {
//If permission has not been granted, request
EasyPermissions.requestPermissions(DownloadActivity.this, "This app needs access to your file storage", REQUEST_CODE, PERMISSIONS_STORAGE);
}
I had similarcode as yours and had the same error, I fixed it this way.
This question already has answers here:
Download a file with Android, and showing the progress in a ProgressDialog
(16 answers)
Closed 5 years ago.
I need to download a big file on my app (almost 1gb) and i was wondering what is the best way to do that and some libs to help me. First I looked the Android Asynchronous Http Library but I didn't find examples showing how to publish the progress or start, pause download. Then I don't know if should I use this lib or just use a standart http commons. Other problem is, should I use a service to download my file??
You can use this code in asynctask to download with resume:
#SuppressLint("Wakelock")
#Override
protected String doInBackground(String... sUrl) {
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
wl.acquire();
try {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
File SDCardRoot = Environment.getExternalStorageDirectory();
File file = new File(SDCardRoot,FOLDER_PATH1+FOLDER_PATH2+ "/"+fileName);
int downloaded=0;
if(file.exists()){
downloaded=(int) file.length();
connection.setRequestProperty("Range", "bytes=" + (int) file.length() + "-");
}
else{
file.createNewFile();
}
connection.setDoInput(true);
connection.setDoOutput(true);
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength()+(int)file.length();
// download the file
input = connection.getInputStream();
if(downloaded>0){
output = new FileOutputStream(file,true);
}
else{
output = new FileOutputStream(file);
}
byte data[] = new byte[1024];
long total = downloaded;
int count;
mProgressDialog.setMax(fileLength/1024);
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled())
return null;
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int)total/1024);
output.write(data, 0, count);
}
output.flush();
if (output != null)
output.close();
if (input != null)
input.close();
if (connection != null)
connection.disconnect();
wl.release();
return null;
} catch (Exception e) {
return e.toString();
}
}
catch (Exception e) {
return e.toString();
}
}
You should use library because it will handle your all test cases & it will help you to maintain downloading state.
Some of libraries:
1] ThinDownloadManager
2] Android-Download-Manager-Pro
You should use DownLoad Manager which is a system service that can handle long-running HTTP downloads.
I am trying to download a PPT file from a server.
it's in Bytes.
but while debugging I noticed that the input stream throws an exception of FileNotFound while running.. the file does exist on the server, here's my code, any help would be greatly appreciated.
public class DownloadFileAsync extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.addRequestProperty("Authorization", "Basic " + SharedPref.getAuthPrefValue());
connection.addRequestProperty("Device", BaseApplication.getCurrentDevice().getDevice().toString());
connection.addRequestProperty("DeviceId", BaseApplication.getCurrentDevice().getDeviceId());
connection.connect();
int lengthOfFile = connection.getContentLength();
Log.d("ANDRO_ASYNC", "Length of file: " + lengthOfFile);
InputStream input = new BufferedInputStream(url.openStream());
File sdcardDest = new File(Environment.getExternalStorageDirectory(), "Availo");
String finalDest = sdcardDest + File.separator + "Check1" + "." + "PPT";
OutputStream output = new FileOutputStream(finalDest);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lengthOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
I am using Charles on Mac (which is similar to fiddler on windows.) to see what I send and receive from the server,
The server doesn't return any error, though it shows download steps for 6-7 sec, downloading around 400 bytes and then it stops.
The Exception is thrown from the input stream line.
Thanks!
I suggest you take a look at the DownloadManager system service. it's designed specifically for what you are trying to do:
(from the documentation)
The download manager is a system service that handles long-running
HTTP downloads. Clients may request that a URI be downloaded to a
particular destination file. The download manager will conduct the
download in the background, taking care of HTTP interactions and
retrying downloads after failures or across connectivity changes and
system reboots
While I do agree with Muzikant regarding the download manager,
FileNotFoundException is usually thrown when... the file is not found on the local device...
You need to do the following to make sure it doesnt happen
File dest = new File(finalDest);
try{
File parentDest = dest.getParentFile();
if(!parentDest.exists()){
parentDest.mkdirs(); //make all the directory structures needed
}
if(!dest.exists()){
dest.createNewFile();
}
OutputStream output = new FileOutputStream(dest);
//now you can use your file dest
//write data to it...
}catch (Exception e){
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Android:“Unexpected end of stream” exception downloading large files
I'm downloading a file with the following code below. The file is approx. 5MB in size. However, I'm getting a java.io.IOException "unexpected end of stream" error when the download is around 60-90%
I don't understand how to solve it and it's driving me crazy.
EDIT: Could someone at least just test it, if it downloads a file successfully on your phone. This will allow me to determine whether the problem is my phone or the code.
try {
URL url = new URL(full_url);
conexion = (URLConnection)url.openConnection();
conexion.setReadTimeout(20000);
conexion.connect();
File file = new File(root.getAbsolutePath()+"/", fileName);
int lenghtOfFile = conexion.getContentLength();
System.out.println("content-length-header is: " + lenghtOfFile);
InputStream input = conexion.getInputStream();
OutputStream output = new FileOutputStream(file);
byte data[] = new byte[8192];
long total = 0;
contentView.setTextViewText(R.id.status_text,"Downloading file " + (78 - GlobalData.missingFiles.size()) + " of " + 77);
int downloadProgress = (int)((total*100)/lenghtOfFile);
int lastProgressUpdate=0;
while ((count = input.read(data)) != -1) {
System.out.println("available bytes:" + input.available());
total += count;
downloadProgress = (int)((total*100)/lenghtOfFile);
Log.e("totaltotal","" + (int)((total*100)/lenghtOfFile));
output.write(data,0,count);
if(downloadProgress%20==0 && downloadProgress != lastProgressUpdate) {
notification.contentView.setProgressBar(R.id.status_progress, 100,downloadProgress, false);
notificationManager.notify(1,notification);
lastProgressUpdate=downloadProgress;
}
if(downloadProgress == 100){
GlobalData.downloadFiles.add("" +fileName);
GlobalData.missingFiles.remove(fileName);
}
}
output.flush();
output.close();
input.close();
if(downloadProgress != 100){
File temp_file = new File(root.getAbsolutePath()+"/", fileName);
try{
if(temp_file.exists()){
boolean del_main = temp_file.delete();
Log.e("File","Does file exists: " + del_main);
Log.e("FilePath","PATH: " + temp_file.getAbsolutePath());
}else{
Log.e("File Exists NOT","NOT EXISTING");
}
}catch(Exception e){
Log.e("FileDelete","deleting is giving problems");
}
}
} catch (Exception e) {
Log.e("PRINTSTACK","STACK:" + e.getMessage());
e.printStackTrace();
System.out.println("Downloading didn't work");
killService();
}
For some reason the input stream is closing prematurely. Often this is since an inputstream is read mulitple times at once, but I'm guessing this is not the case here, even though you for some reason have conexion available in a wider scope than we see here.
You say conexion = (URLConnection)url.openConnection(); instead of the expected URLConnection conexion = url.openConnection();. Please make sure you do not try to fetch the input stream twice.
The only other thing I can see that is weird when I look is that you use the inputstream from conexion.getInputStream() directly. Try wrapping it in a buffered input stream as such:
InputStream input = new BufferedInputStream(connexion.getInputStream());
I'm a newbie at Android, and developing my first app.
I'm using the following code to download 10 images from my website
private class DownloadImages extends AsyncTask<Integer, Integer, Integer> {
#Override
protected Integer doInBackground(Integer... pic_ids){
int count = pic_ids.length;
for (int i = 0; i < count; i++) {
// download the image from website ...
String url = "http://www.mysite.com/pic.php?pid=" + pic_ids[i];
DownloadFromUrl(url, pic_ids[i] + ".jpg");
publishProgress((int) (i + 1));
}
return count;
}
}
public void DownloadFromUrl(String imageURL, String fileName){
try {
URL url = new URL(imageURL);
File file = new File(getFilesDir() + "/" + fileName);
URLConnection ucon = url.openConnection();
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is, 8192);
ByteArrayBuffer baf = new ByteArrayBuffer(128);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(baf.toByteArray());
fos.close();
} catch (Exception e) {
Log.d("ImageManager", "Error: " + e);
}
}
The "DownloadImages" is passed an array of 10 ID's. All are handled (I have Log.d statements in between to check), however, only 1 out of 2 actually gets downloaded. Not in a random way: the first one is downloaded, the second one not, the third one is downloade, the fourth not etc. That means: The files are all written to the phone/emulator, but those that "fail" are empty.
When I start it again with only the 5 remaining images (those that were not downloaded the first time), the same thing happens (1st one downloaded, 2nd one not, ...)
I don't see an error in the logs.
Adding a check for baf.length shows that this is 0 for those files that fail.
Any idea ?
This is long past due but I was having the same issue a few months ago. The strange thing was it only happened while connecting with SSL.
I eventually had to implement a checker to see if it truly downloaded and if not tried again (terminated after the second attempt at each file).