Skip to content

Commit

Permalink
Added Nav Menu option for downloading and saving offline zip and made…
Browse files Browse the repository at this point in the history
… two independent intent service for downloading and saving.
  • Loading branch information
prashantkh19 committed Feb 2, 2019
1 parent 0467e51 commit da6172e
Show file tree
Hide file tree
Showing 8 changed files with 614 additions and 292 deletions.
2 changes: 2 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@
</service>
<service android:name=".utils.UploadService" />
<service android:name=".utils.WifiUploadReceiver$WifiService" />
<service android:name=".jobs.DownloadOfflineProductService" />
<service android:name=".jobs.ExtractOfflineProductService" />

<provider
android:name=".utils.GenericFileProvider"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
package openfoodfacts.github.scrachx.openfood.jobs;

import android.annotation.SuppressLint;
import android.app.IntentService;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.util.Pair;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import okhttp3.ResponseBody;
import openfoodfacts.github.scrachx.openfood.R;
import openfoodfacts.github.scrachx.openfood.network.OpenFoodAPIClient;
import openfoodfacts.github.scrachx.openfood.views.MainActivity;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class DownloadOfflineProductService extends IntentService {

private static final String TAG = "DOPService";
public static boolean isDownloadOfflineProductServiceRunning = false;
SharedPreferences settings;
NotificationManager notificationManager;
NotificationCompat.Builder builder;

DownloadZipFileTask downloadZipFileTask;

public DownloadOfflineProductService() {
super("DownloadOfflineProductService");
}

@Override
protected void onHandleIntent(@Nullable Intent intent) {
isDownloadOfflineProductServiceRunning = true;
settings = getSharedPreferences("prefs", Context.MODE_PRIVATE);
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
builder = new NotificationCompat.Builder(this, "export_channel");

builder.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.txtDownloading))
.setAutoCancel(true)
.setSmallIcon(R.mipmap.ic_launcher);

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
String channelId = "channel";
CharSequence channelName = getString(R.string.notification_channel_name);
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel notificationChannel = new NotificationChannel(channelId, channelName, importance);
notificationManager.createNotificationChannel(notificationChannel);
}

doTask();
}

private void doTask() {

//notify downloading is started
builder.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.txtDownloading))
.setProgress(100, 0, true)
.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher);

notificationManager.notify(7, builder.build());

//downloading data
OpenFoodAPIClient client = new OpenFoodAPIClient(this);
String fileURL = "http://fr.openfoodfacts.org/data/offline/fr.openfoodfacts.org.products.small.zip";
client.getAPIService().downloadFileWithDynamicUrlSync(fileURL)
.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {

//downloading completed .. notify processing is started!
Log.d(TAG, "server contacted and has file");
downloadZipFileTask = new DownloadZipFileTask();
downloadZipFileTask.execute(response.body());

} else {
//download error .. notify and handle actions
isDownloadOfflineProductServiceRunning = false;
Log.d(TAG, "server contact failed");
Intent intent = new Intent(DownloadOfflineProductService.this, MainActivity.class);
intent.putExtra("from_download_service", "retry");
PendingIntent pendingIntent = PendingIntent.getActivity(DownloadOfflineProductService.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentText(getString(R.string.txtConnectionFailed))
.setOngoing(false)
.addAction(R.mipmap.ic_launcher, getString(R.string.txtRetry), pendingIntent);
notificationManager.notify(7, builder.build());
}
}

@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
//download error .. notify and handle actions
isDownloadOfflineProductServiceRunning = false;
Log.d(TAG, "server contact failed");
Intent intent = new Intent(DownloadOfflineProductService.this, MainActivity.class);
intent.putExtra("from_download_service", "retry");
PendingIntent pendingIntent = PendingIntent.getActivity(DownloadOfflineProductService.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentText(getString(R.string.txtConnectionFailed))
.setOngoing(false)
.addAction(R.mipmap.ic_launcher, getString(R.string.txtRetry), pendingIntent);
notificationManager.notify(7, builder.build());
}
});
}

private void saveToDisk(ResponseBody body, String filename) {
try {

File destinationFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), filename);

InputStream inputStream = null;
OutputStream outputStream = null;

try {

inputStream = body.byteStream();
outputStream = new FileOutputStream(destinationFile);
byte data[] = new byte[4096];
int count;
int progress = 0;
long fileSize = body.contentLength();
Log.d(TAG, "File Size=" + fileSize);
while ((count = inputStream.read(data)) != -1) {
outputStream.write(data, 0, count);
progress += count;
Pair<Integer, Long> pairs = new Pair<>(progress, fileSize);
downloadZipFileTask.doProgress(pairs);
Log.d(TAG, "Progress: " + progress + "/" + fileSize + " >>>> " + (float) progress / fileSize);
}

outputStream.flush();

Log.d(TAG, destinationFile.getParent());
Pair<Integer, Long> pairs = new Pair<>(100, 100L);
downloadZipFileTask.doProgress(pairs);
return;
} catch (IOException e) {
e.printStackTrace();
Pair<Integer, Long> pairs = new Pair<>(-1, Long.valueOf(-1));
downloadZipFileTask.doProgress(pairs);
Log.d(TAG, "Failed to save the file!");
return;
} finally {
if (inputStream != null) inputStream.close();
if (outputStream != null) outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG, "Failed to save the file!");
return;
}
}

@SuppressLint("StaticFieldLeak")
private class DownloadZipFileTask extends AsyncTask<ResponseBody, Pair<Integer, Long>, String> {

@Override
protected void onPreExecute() {
super.onPreExecute();

}

@Override
protected String doInBackground(ResponseBody... urls) {
//Copy you logic to calculate progress and call
saveToDisk(urls[0], "fr.openfoodfacts.org.products.small.zip");
return null;
}

protected void onProgressUpdate(Pair<Integer, Long>... progress) {

Log.d(TAG, progress[0].second + " ");

if (progress[0].first == 100) {
settings.edit().putBoolean("is_data_downloaded", true).apply();
Intent intent = new Intent(DownloadOfflineProductService.this, MainActivity.class);
intent.putExtra("from_download_service", "start_extraction");
PendingIntent pendingIntent = PendingIntent.getActivity(DownloadOfflineProductService.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentText(getString(R.string.txtDownloaded))
.addAction(R.mipmap.ic_launcher, getString(R.string.txtExtractSave), pendingIntent)
.setOngoing(false)
.setProgress(0, 0, false);
notificationManager.notify(7, builder.build());
}

if (progress[0].second > 0) {
int currentProgress = (int) ((double) progress[0].first / (double) progress[0].second * 100);
builder.setProgress(100, currentProgress, false)
.setOngoing(true);
notificationManager.notify(7, builder.build());
}

if (progress[0].first == -1) {
Intent intent = new Intent(DownloadOfflineProductService.this, MainActivity.class);
intent.putExtra("from_download_service", "retry");
PendingIntent pendingIntent = PendingIntent.getActivity(DownloadOfflineProductService.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentText(getString(R.string.txtConnectionFailed))
.setOngoing(false)
.addAction(R.mipmap.ic_launcher, getString(R.string.txtRetry), pendingIntent)
.setProgress(0, 0, false);
notificationManager.notify(7, builder.build());
}

}

public void doProgress(Pair<Integer, Long> progressDetails) {
publishProgress(progressDetails);
}

@Override
protected void onPostExecute(String result) {
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("is_data_downloaded", true);
editor.apply();
isDownloadOfflineProductServiceRunning = false;
}
}


}
Loading

0 comments on commit da6172e

Please sign in to comment.