I am trying to build an application in which I Am playing videos and images simultaneously. Every one hour or so the app has to download materials from internet. so to use the new materials I am trying to make it restart. I have implemented a runnable and put the code for download and restart in the run method. The problem is that the app freezes soon after start-
synchronized public void run() {
download("http://www.justieltsshaddi.com/pankaj/list.txt",
Environment.getExternalStorageDirectory() + "/alpha/list.txt");
File beta = new File(Environment.getExternalStorageDirectory()
+ "/beta/");
File betalist = new File(beta + "/list.txt");
File alpha = new File(Environment.getExternalStorageDirectory()
+ "/alpha/");
File alphalist = new File(alpha + "/list.txt");
if (alphalist.lastModified() == betalist.lastModified()) {
return;
}
try {
FileReader inAlpha = new FileReader(alphalist);
BufferedReader br = new BufferedReader(inAlpha);
String s;
Toast.makeText(this, "Starting Download...", Toast.LENGTH_SHORT)
.show();
while ((s = br.readLine()) != null) {
download("http://www.justieltsshaddi.com/pankaj" + "/" + s,
Environment.getExternalStorageDirectory() + "/alpha/"
+ s);
}
// stop the activity to rename folders
Toast.makeText(this, "Download done. Restarting...",
Toast.LENGTH_SHORT).show();
Log.d("Pankaj", "Download Done");
Intent intent = getIntent();
overridePendingTransition(0, 0);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
Log.d("Pankaj", "MainActivity Killed");
// rename alpha to beta
deleteSubFolders(beta.toString());
alpha.renameTo(beta);
if (!alpha.exists()) {
alpha.mkdir();
}
File upper = new File(alpha + "/upper/");
if (!upper.exists())
upper.mkdirs();
File lower = new File(alpha + "/lower/");
if (!lower.exists())
lower.mkdirs();
// restart the activity
overridePendingTransition(0, 0);
startActivity(intent);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
any help is appreciated. thanks in advance.
I would suggest you use Aysnc Task to download the files
private class DownloadFile extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... sUrl) {
try {
//do your download
while ((s = br.readLine()) != null) {
download("http://www.justieltsshaddi.com/pankaj" + "/" + s,
Environment.getExternalStorageDirectory() + "/alpha/"
+ s);
}
} catch (Exception e) {
}
return null;
}
call the download task as below
// execute this when the downloader must be fired
DownloadFile downloadFile = new DownloadFile();
downloadFile.execute("the url to the file you want to download");
may be thinking of firing the download task in loop.
Use Service and Alarm Manager
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 10);
Intent intent = new Intent(this, reciever.class);
PendingIntent pi = PendingIntent.getBroadcast(context, _id, i, 0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
//for 30 mint 60*60*1000
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
60*60*1000, pi );
In broadcast reciever start the service
public class reciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
}
Related
This question already has answers here:
Android: install .apk programmatically [duplicate]
(4 answers)
Closed 5 years ago.
I've seen a few answers related to this but can't quite seem to find what I'm looking for. Say I have a self hosted app. Now say I've made some changes to that app and would like to let the user know within the app that there is an update available. I can get the app to successfully download the apk file and begin installing it. After the installation is "finished" the app closes out. When I restart the app none of the changes I've made have been applied. So it appears the installation has failed, but there was no apparent crash. However, when I install the apk that was downloaded from the Downloads manager it installs just fine and the changes I have made are applied. Any ideas? Here is the section of code I use to download and install programmatically:
String destination = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
String fileName = "TheApp.apk";
destination += fileName;
final Uri uri = Uri.parse("file://" + destination);
String url = "myapplocation";
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setDescription("Downloading necessary update files.");
request.setTitle("Updating The App");
final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
final long downloadId = manager.enqueue(request);
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
install.setDataAndType(uri,
manager.getMimeTypeForDownloadedFile(downloadId));
startActivityForResult(install, 0);
unregisterReceiver(this);
}
};
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
Get VersionName and VersionCode for current Running application.
code:
try {
PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
Common.VersionName = pInfo.versionName;
Common.VersionCode = pInfo.versionCode;
Log.e("VersionCode", ">>>>>>>>>>" + Common.VersionCode + Common.VersionName);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
**Check the Version Names**
if (!Common.VersionName.equals(Common.VersionNamefromWebApi)) {
AlertDialogUpdate(MakeTransactionActivity.this, Common.AppUpdateTitle, "YokoYepi Version" + Common.VersionNamefromWebApi + " available.");
}
**Alert Dialog Box**
public void AlertDialogUpdate(Activity activity, String title, CharSequence message) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setCancelable(false);
if (title != null) builder.setTitle(title);
builder.setMessage(message);
builder.setPositiveButton("UPDATE", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
new DownloadNewVersion().execute();
dialog.dismiss();
}
});
builder.show();
}
**Download and Install the .apk file from URL**
class DownloadNewVersion extends AsyncTask<String, Integer, Boolean> {
#Override
protected void onPreExecute() {
super.onPreExecute();
bar = new ProgressDialog(MakeTransactionActivity.this);
bar.setCancelable(false);
bar.setMessage("Downloading...");
bar.setIndeterminate(true);
bar.setCanceledOnTouchOutside(false);
bar.show();
stoptimertask();
}
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
bar.setIndeterminate(false);
bar.setMax(100);
bar.setProgress(progress[0]);
String msg = "";
if (progress[0] > 99) {
msg = "Finishing... ";
} else {
msg = "Downloading... " + progress[0] + "%";
}
bar.setMessage(msg);
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
startTimer();
bar.dismiss();
if (result) {
Toast.makeText(getApplicationContext(), "Update Done",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Error: Try Again",
Toast.LENGTH_SHORT).show();
}
}
#Override
protected Boolean doInBackground(String... arg0) {
Boolean flag = false;
try {
String PATH;
Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
if (isSDPresent) {
PATH = Environment.getExternalStorageDirectory() + "/Download/";
} else {
PATH = Environment.getDataDirectory() + "/Download/";
}
File file = new File(PATH);
file.mkdirs();
File outputFile = new File(file, "yokoyepi.apk");
if (outputFile.exists()) {
outputFile.delete();
}
// Download File from url
URL u = new URL(Common.AppUpdateURL);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();
DataOutputStream fos = new DataOutputStream(new FileOutputStream(outputFile));
fos.write(buffer);
fos.flush();
fos.close();
// Install dowloaded Apk file from Devive----------------
OpenNewVersion(PATH);
flag = true;
} catch (MalformedURLException e) {
Log.e(TAG, "Update Error: " + e.getMessage());
flag = false;
} catch (IOException e) {
Log.e(TAG, "Update Error: " + e.getMessage());
flag = false;
} catch (Exception e) {
Log.e(TAG, "Update Error: " + e.getMessage());
flag = false;
}
return flag;
}
}
void OpenNewVersion(String location) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(location + "yokoyepi.apk")),
"application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
// if your not install u should call the function in onResume().
// again it will check whether apk updated or not.
I have an intent service which is processing long running task. But while processing if an exception occurs lets say SocketTimeOutException the service stops. How to catch the exception and restart the process.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
protected void onHandleIntent(Intent intent) {
String name = intent.getStringExtra("name");
String packageName = intent.getStringExtra("packageName");
String path = intent.getStringExtra("path");
int downloadedSoFar = 0;
Intent i = new Intent(getApplicationContext(), DownloadListViewApp.class);
PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0, i, 0);
nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle(name)
.setContentText("Download in progress")
.setSmallIcon(R.drawable.logo).setContentInfo("0%").setContentIntent(pi);
mBuilder.setOngoing(true);
try {
url = new URL(IPClass.SERVERIP + path + "/" + packageName);
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setReadTimeout(7000);
int fileLength = connection.getContentLength();
connection.connect();
input = connection.getInputStream();
output = new FileOutputStream("/sdcard/Android/appdata/tmp/downloadtmp/" + packageName, true);
byte data[] = new byte[1024];
int count;
boolean continueLoop = true;
while ((count = input.read(data)) > 0 && continueLoop) {
progressChange((int) (downloadedSoFar * 100L) / fileLength, packageName);
downloadedSoFar = downloadedSoFar + count;
output.write(data, 0, count);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (output != null) output.close();
if (input != null) input.close();
} catch (IOException ignored) {
}
if (connection != null) {
connection.disconnect();
}
}
You can't stop intent service till its duty has completed, if you want to stop it then you should have to stop alarm manager in intent service like this.
Intent DataSyncing = new Intent(getBaseContext(), DataSyncingScheduledReceiver.class);
DataSyncing.setAction(DataSyncingScheduledReceiver.ACTION_DATASYNC_RECEIVER);
PendingIntent DataSyncingIntent = PendingIntent.getBroadcast(getBaseContext(),1003, DataSyncing, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManagerdatasync = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManagerdatasync.cancel(DataSyncingIntent);
DataSyncingIntent.cancel();
Ref :- https://stackoverflow.com/a/12776012/2705391
You can use this for your problem.
#Override
protected void onHandleIntent(Intent intent)
{
try
{
// STOP SERVICE
// DO YOUR WORK HERE
}
finally
{
// START SERVICE
}
}
I think restarting a servise is not a solution you should handle it in catch
put your code to call api inside seperate function
supose your function is like callAPI()
} catch (final java.net.SocketTimeoutException e) {
// connection timed out...let's try again
callAPI()
}
This creates a recursion
by this your api will be called n time untill your api will give SocketTimeoutException
so you will not need to restart your IntentService. it will remain onrun until your api executed
if you want to prevent this you have to specify and implement logic of nuberofAttempts as in volley
volley inbuilt has retry policy you should read about it.
else i sugest volley or retrofit to use
I'm developing an Android application for downloading a file from
server and save that file to the path specified..
I want to make this happen in the background, So I code the downloading function in service. Now I'm getting an error when I used the code in my service..
Can anyone help me to find the error... Thank You..
My Service code Is...
public class MyService extends Service {
Contacts c = new Contacts();
// File url to download
private static String file_url = "http://f23.wapka-files.com/download/6/9/4/1408248_69459e029be95f96ff9f98ff.mp3/a0f9f2173d3d81a49c28/01-Podimeesha-Anand.Madhusoodhanan.mp3y";
public MyService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
File folder = new File(Environment.getExternalStorageDirectory().getPath() + "/Jithin's/");
if (!folder.exists()) {
try {
folder.mkdirs();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Default Save Path Creation Error:" + folder);
}
}
c.setA(Environment.getExternalStorageDirectory().toString() + "/Jithin's/downloadedfile.srt");
// starting new Async Task
new DownloadFileFromURL().execute(file_url);
MyService.this.stopService(intent);
return super.onStartCommand(intent, flags, startId);
}
/**
* Background Async Task to download file
* */
class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread
* Show Progress Bar Dialog
*/
#Override
protected void onPreExecute() {
super.onPreExecute();
}
* Downloading file in background thread
*/
#Override
protected String doInBackground(String... f_url) {
int count;
try {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
// 6yi7 conection.connect();
conection.setRequestProperty("Accept-Encoding", "identity");
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream(c.getA());
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) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(String file_url) {
Toast.makeText(MyService.this, "Downloaded Succesfully.. check Jithin's folder 2 see file...", Toast.LENGTH_LONG).show();
//my_image.setImageDrawable(Drawable.createFromPath(imagePath));
}
}
}
My Main Activity code is..
public void download(View view) {
String value = getIntent().getExtras().getString("id");
if (value.equals("Song0")) {
Intent i=new Intent(Song_List.this, MyService.class);
startActivity(i);
Toast.makeText(Song_List.this, "Downloading..........", Toast.LENGTH_SHORT).show();
}
}
Change your code from,
Intent i=new Intent(Song_List.this, MyService.class);
startActivity(i);
this to,
Intent i=new Intent(Song_List.this, MyService.class);
startService(i);
First of all you should start your service like this not with startActivity
public void download(View view) {
String value = getIntent().getExtras().getString("id");
if (value.equals("Song0")) {
Intent i=new Intent(Song_List.this, MyService.class);
startService(i);
Toast.makeText(Song_List.this, "Downloading..........", Toast.LENGTH_SHORT).show();
}
}
after stop service when your file download is completed
MyService is the extention of Service. So you have to use startService(Intent).
so your code may look like this :
public void download(View view) {
String value = getIntent().getExtras().getString("id");
if (value.equals("Song0")) {
Intent i=new Intent(Song_List.this, MyService.class);
startService(i);
Toast.makeText(Song_List.this, "Downloading..........", Toast.LENGTH_SHORT).show();
}
}
We have an app in the Google Play Store that runs in the foreground continuously. The devices that it runs on are out of our control and are not rooted. They run on either Android 4.2 or 4.4.
Our goal is to have the app update to the newest version that we release via the Play Store without user interaction. Restarting the device would be the only acceptable "interaction" option.
We find that a running app does not updated automatically when it is running even if the "automatic update" is turned on.
What is the way to achieve our goal?
Use an Alarm Manager to scheduled your update and then use a create a class and extend the service or IntentService class. Check if theres an internet connection if yes proceed to update like this: Check this link Android Services - Tutorial In this way you can update even not showing your Activity by using service.
Creating the Alarm Manager:
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(this, MyService.class);
PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
// Start every 30 seconds
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 30*1000, pintent);
For service:
public class DownloadService extends IntentService {
private int result = Activity.RESULT_CANCELED;
public static final String URL = "urlpath";
public static final String FILENAME = "filename";
public static final String FILEPATH = "filepath";
public static final String RESULT = "result";
public static final String NOTIFICATION = "com.vogella.android.service.receiver";
public DownloadService() {
super("DownloadService");
}
// will be called asynchronously by Android
#Override
protected void onHandleIntent(Intent intent) {
String urlPath = intent.getStringExtra(URL);
String fileName = intent.getStringExtra(FILENAME);
File output = new File(Environment.getExternalStorageDirectory(),
fileName);
if (output.exists()) {
output.delete();
}
InputStream stream = null;
FileOutputStream fos = null;
try {
URL url = new URL(urlPath);
stream = url.openConnection().getInputStream();
InputStreamReader reader = new InputStreamReader(stream);
fos = new FileOutputStream(output.getPath());
int next = -1;
while ((next = reader.read()) != -1) {
fos.write(next);
}
// successfully finished
result = Activity.RESULT_OK;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
publishResults(output.getAbsolutePath(), result);
}
private void publishResults(String outputPath, int result) {
Intent intent = new Intent(NOTIFICATION);
intent.putExtra(FILEPATH, outputPath);
intent.putExtra(RESULT, result);
sendBroadcast(intent);
}
}
I have this code with wich I download APK expension file
private void performAPKExpansionCheckAndDownload(){
String APK_LOG = "APK_LOG";
String mainFileName = Helpers.getExpansionAPKFileName(this, true, 2);
Log.d(APK_LOG,"mainFileName "+mainFileName);
boolean fileExists = Helpers.doesFileExist(this, mainFileName, 38783430L, false);
Log.d(APK_LOG,"fileExists "+fileExists);
if (!fileExists) {
Intent launcher = getIntent();
Intent fromNotification = new Intent(this, getClass());
fromNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
fromNotification.setAction(launcher.getAction());
if (launcher.getCategories() != null) {
for (String cat : launcher.getCategories()) {
Log.d(APK_LOG,"cat "+cat);
fromNotification.addCategory(cat);
}
}
PendingIntent pendingIntent = PendingIntent.getActivity(
this, 0, fromNotification, PendingIntent.FLAG_UPDATE_CURRENT);
try {
int result = DownloaderClientMarshaller.startDownloadServiceIfRequired(
this, pendingIntent, MyDownloaderService.class);
Log.d(APK_LOG,"result "+result);
if (DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED != result) {
// implement Downloading UI.
return;
}
} catch (NameNotFoundException e) {
Log.e("apk-expansion-files", "NameNotFoundException occurred. " + e.getMessage(), e);
}
}
}
The problem is that I need to handle callbacks like onDownloadFinished and onProgressUpdate. I know that thous messages are posted somewhere but I don't know how to handle them. Since I haven't worked with messages in Android any help would be good.
UPDATE:
All downloading happens here:
int result = DownloaderClientMarshaller.startDownloadServiceIfRequired(
this, pendingIntent, MyDownloaderService.class);
if (DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED != result) {
// implement Downloading UI.
return;
}
I guess those callbacks must be connected to that DownloaderClientMarshaller class.