/**
* Copyright (C) 2013 - 2015 the enviroCar community
* <p>
* This file is part of the enviroCar app.
* <p>
* The enviroCar app is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* <p>
* The enviroCar app is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
* <p>
* You should have received a copy of the GNU General Public License along
* with the enviroCar app. If not, see http://www.gnu.org/licenses/.
*/
package org.envirocar.app.services;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.widget.RemoteViews;
import org.envirocar.app.BaseMainActivity;
import org.envirocar.app.R;
import org.envirocar.app.handler.TrackRecordingHandler;
import org.envirocar.app.handler.TrackUploadHandler;
import org.envirocar.core.entity.Track;
import org.envirocar.core.injection.Injector;
import org.envirocar.core.logging.Logger;
import org.envirocar.storage.EnviroCarDB;
import java.util.List;
import javax.inject.Inject;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
/**
* TODO JavaDoc
*
* @author dewall
*/
public class TrackUploadService extends Service {
private static final Logger LOG = Logger.getLogger(TrackUploadService.class);
private static final int NOTIFICATION_ID = 52;
@Inject
protected TrackRecordingHandler trackRecordingHandler;
@Inject
protected EnviroCarDB enviroCarDB;
@Inject
protected TrackUploadHandler trackUploadHandler;
@Override
public void onCreate() {
LOG.debug("onCreate()");
super.onCreate();
// Inject the OBDServiceHandler;
((Injector) getApplicationContext()).injectObjects(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
LOG.info("onStartCommand()");
// TODO change it to clean u
List<Track> localTrackList = enviroCarDB.getAllLocalTracks().first().toBlocking().first();
if (localTrackList.size() > 0) {
LOG.info(String.format("%s local tracks to upload", localTrackList.size()));
// setNotification("yeae", "oiad");
uploadAllLocalTracks();
} else {
LOG.info("No local tracks to upload");
// setNotification("yeae", "oiad");
try {
finalize();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void uploadAllLocalTracks() {
Observable.defer(() -> enviroCarDB.getAllLocalTracks())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.first()
.concatMap(tracks -> getUploadWithNotificationObservable(tracks))
.subscribe(new Subscriber<Track>() {
@Override
public void onStart() {
LOG.info("onStart()");
}
@Override
public void onCompleted() {
LOG.info("onCompleted()");
}
@Override
public void onError(Throwable e) {
LOG.warn(e.getMessage(), e);
}
@Override
public void onNext(Track track) {
LOG.info("Track has been successfully uploaded -> " + track.getRemoteID());
}
});
}
private Observable<Track> getUploadWithNotificationObservable(final List<Track> tracks) {
return Observable.create(new Observable.OnSubscribe<Track>() {
private RemoteViews smallView;
private RemoteViews bigView;
private Notification foregroundNotification;
private NotificationManager notificationManager;
private int numberOfTracks = tracks.size();
private int numberOfSuccesses = 0;
private int numberOfFailures = 0;
@Override
public void call(Subscriber<? super Track> subscriber) {
subscriber.add(trackUploadHandler.uploadTracksObservable(tracks, false)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Track>() {
@Override
public void onStart() {
subscriber.onStart();
foregroundNotification = new NotificationCompat
.Builder(getApplicationContext())
.setSmallIcon(R.drawable.ic_cloud_upload_white_24dp)
.setContentTitle(
getString(R.string.notification_automatic_track_upload_title))
.setPriority(Integer.MAX_VALUE)
.build();
smallView = new RemoteViews(getPackageName(),
R.layout.service_track_upload_handler_notification_small);
bigView = new RemoteViews(getPackageName(),
R.layout.service_track_upload_handler_notification);
foregroundNotification.bigContentView = bigView;
setSmallViewText(
getString(R.string
.notification_automatic_track_upload_title),
getString(R.string.
notification_slide_down));
setBigViewText(
getString(R.string.
notification_automatic_track_upload_title),
getString(R.string.
notification_automatic_track_upload_success_sub)
);
notificationManager = (NotificationManager) getSystemService(Context
.NOTIFICATION_SERVICE);
updateProgress();
}
@Override
public void onCompleted() {
LOG.info("getUploadWithNotificationObservable.onCompleted()");
subscriber.onCompleted();
setSmallViewText(
getString(R.string.
notification_automatic_track_upload_success),
getString(R.string.
notification_automatic_track_upload_success_sub,
numberOfSuccesses, numberOfTracks));
foregroundNotification = new NotificationCompat
.Builder(getApplicationContext())
.setSmallIcon(R.drawable.ic_cloud_upload_white_24dp)
.setContentTitle(
getString(R.string.notification_automatic_track_upload_title))
.setContent(smallView)
.build();
notificationManager.notify(100, foregroundNotification);
}
@Override
public void onError(Throwable e) {
subscriber.onError(e);
setSmallViewText(
getString(R.string.
notification_automatic_track_upload_error),
getString(R.string.
notification_automatic_track_upload_error_sub));
foregroundNotification = new NotificationCompat
.Builder(getApplicationContext())
.setSmallIcon(R.drawable.ic_error_outline_white_24dp)
.setContentTitle("Track Upload Error")
.setContent(smallView)
.build();
notificationManager.notify(100, foregroundNotification);
}
@Override
public void onNext(Track track) {
if (track == null) {
LOG.info("track had to less measurements");
numberOfFailures++;
} else {
subscriber.onNext(track);
numberOfSuccesses++;
}
updateProgress();
}
private void updateProgress() {
int totalNumber = numberOfFailures + numberOfSuccesses;
bigView.setProgressBar(
R.id.service_track_upload_handler_notification_progressbar,
numberOfTracks,
numberOfFailures + numberOfSuccesses,
false);
bigView.setTextViewText(
R.id.service_track_upload_handler_notification_total,
String.format("%s / %s", totalNumber, numberOfTracks));
bigView.setTextViewText(
R.id.service_track_upload_handler_notification_percentage,
"" + ((numberOfFailures +
numberOfSuccesses) / numberOfTracks) * 100);
notificationManager.notify(100, foregroundNotification);
}
private void setSmallViewText(String title, String content) {
smallView.setTextViewText(
R.id.service_track_upload_handler_notification_small_title,
title);
smallView.setTextViewText(
R.id.service_track_upload_handler_notification_small_content,
content);
}
private void setBigViewText(String title, String content) {
bigView.setTextViewText(
R.id.service_track_upload_handler_notification_text,
title);
bigView.setTextViewText(
R.id.service_track_upload_handler_notification_sub_text,
content);
}
}));
}
});
}
private void setNotification(String title, String notification) {
RemoteViews bigView = new RemoteViews(getPackageName(), R.layout
.service_track_upload_handler_notification);
RemoteViews smallView = new RemoteViews(getPackageName(), R.layout
.service_track_upload_handler_notification_small);
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.home_icon);
Notification forgroundNotification = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_cloud_upload_white_24dp)
.setContentTitle(title)
.setContent(smallView)
// .setAutoCancel(false)
.setPriority(Integer.MAX_VALUE)
// .setOngoing(true)
// .setLargeIcon(bm)
.build();
forgroundNotification.bigContentView = bigView;
Intent intent = new Intent(getBaseContext(), BaseMainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(BaseMainActivity.class);
stackBuilder.addNextIntent(intent);
PendingIntent resultIntent = stackBuilder.getPendingIntent(0, PendingIntent
.FLAG_UPDATE_CURRENT);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context
.NOTIFICATION_SERVICE);
notificationManager.notify(100, forgroundNotification);
}
}