diff --git a/brouter-routing-app/src/main/AndroidManifest.xml b/brouter-routing-app/src/main/AndroidManifest.xml
index 0d50b10..8efa1af 100644
--- a/brouter-routing-app/src/main/AndroidManifest.xml
+++ b/brouter-routing-app/src/main/AndroidManifest.xml
@@ -91,11 +91,6 @@
android:enabled="true"
android:exported="true"
android:process=":brouter_service" />
-
diff --git a/brouter-routing-app/src/main/java/btools/routingapp/BInstallerActivity.java b/brouter-routing-app/src/main/java/btools/routingapp/BInstallerActivity.java
index 63aeb08..8781696 100644
--- a/brouter-routing-app/src/main/java/btools/routingapp/BInstallerActivity.java
+++ b/brouter-routing-app/src/main/java/btools/routingapp/BInstallerActivity.java
@@ -35,7 +35,6 @@ import btools.router.RoutingHelper;
public class BInstallerActivity extends AppCompatActivity {
- public static final String DOWNLOAD_ACTION = "btools.routingapp.download";
private static final int DIALOG_CONFIRM_DELETE_ID = 1;
public static boolean downloadCanceled = false;
private File mBaseDir;
diff --git a/brouter-routing-app/src/main/java/btools/routingapp/DownloadService.java b/brouter-routing-app/src/main/java/btools/routingapp/DownloadService.java
deleted file mode 100644
index f1ec4bf..0000000
--- a/brouter-routing-app/src/main/java/btools/routingapp/DownloadService.java
+++ /dev/null
@@ -1,277 +0,0 @@
-package btools.routingapp;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-import android.widget.Toast;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.List;
-
-import btools.mapaccess.PhysicalFile;
-import btools.mapaccess.Rd5DiffManager;
-import btools.mapaccess.Rd5DiffTool;
-import btools.util.ProgressListener;
-
-public class DownloadService extends Service implements ProgressListener {
- private static final String PROFILES_DIR = "profiles2/";
- private static final String SEGMENTS_DIR = "segments4/";
- private static final String SEGMENT_DIFF_SUFFIX = ".df5";
- private static final String SEGMENT_SUFFIX = ".rd5";
-
- private static final boolean DEBUG = false;
- public static boolean serviceState = false;
- private ServerConfig mServerConfig;
- private NotificationHelper mNotificationHelper;
- private List mSegmentNames;
- private String baseDir;
- private volatile String lastProgress = "";
- private ServiceHandler mServiceHandler;
- private boolean bIsDownloading;
- private int mSegmentIndex;
- private int mSegmentCount;
-
- @Override
- public void onCreate() {
- if (DEBUG) Log.d("SERVICE", "onCreate");
- serviceState = true;
- mServerConfig = new ServerConfig(getApplicationContext());
-
- HandlerThread thread = new HandlerThread("ServiceStartArguments", 1);
- thread.start();
-
- // Get the HandlerThread's Looper and use it for our Handler
- Looper serviceLooper = thread.getLooper();
- mServiceHandler = new ServiceHandler(serviceLooper);
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- if (DEBUG) Log.d("SERVICE", "onStartCommand");
-
- mNotificationHelper = new NotificationHelper(this);
- Bundle extra = intent.getExtras();
- if (extra != null) {
- String dir = extra.getString("dir");
- mSegmentNames = extra.getStringArrayList("urlparts");
- baseDir = dir;
- }
-
- mNotificationHelper.startNotification(this);
-
- Message msg = mServiceHandler.obtainMessage();
- msg.arg1 = startId;
- mServiceHandler.sendMessage(msg);
-
- // If we get killed, after returning from here, restart
- return START_STICKY;
- }
-
- @Override
- public void onDestroy() {
- if (DEBUG) Log.d("SERVICE", "onDestroy");
- serviceState = false;
- super.onDestroy();
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-
- public void downloadFiles() {
- try {
- mSegmentIndex = 0;
- downloadLookupAndProfiles();
-
- mSegmentIndex = 1;
- mSegmentCount = mSegmentNames.size();
- for (String segmentName : mSegmentNames) {
- downloadSegment(mServerConfig.getSegmentUrl(), segmentName + SEGMENT_SUFFIX);
- mSegmentIndex++;
- }
- } catch (IOException e) {
- Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
- } catch (InterruptedException e) {
- updateProgress("canceled");
- } finally {
- bIsDownloading = false;
- updateProgress("finished");
- }
- }
-
- public void updateProgress(String progress) {
- if (!lastProgress.equals(progress)) {
- if (mSegmentIndex > 0) {
- progress = mSegmentIndex + "/" + mSegmentCount + " " + progress;
- }
- if (DEBUG) Log.d("BR", "up " + progress);
- Intent intent = new Intent(BInstallerActivity.DOWNLOAD_ACTION);
- intent.putExtra("txt", progress);
- intent.putExtra("ready", bIsDownloading);
- sendBroadcast(intent);
- mNotificationHelper.progressUpdate(progress);
- lastProgress = progress;
- }
- }
-
- private void downloadLookupAndProfiles() throws IOException, InterruptedException {
- String[] lookups = mServerConfig.getLookups();
- for (String fileName : lookups) {
- if (fileName.length() > 0) {
- File lookupFile = new File(baseDir, PROFILES_DIR + fileName);
- String lookupLocation = mServerConfig.getLookupUrl() + fileName;
- URL lookupUrl = new URL(lookupLocation);
- downloadFile(lookupUrl, lookupFile, false);
- }
- }
-
- String[] profiles = mServerConfig.getProfiles();
- for (String fileName : profiles) {
- if (fileName.length() > 0) {
- File profileFile = new File(baseDir, PROFILES_DIR + fileName);
- if (profileFile.exists()) {
- String profileLocation = mServerConfig.getProfilesUrl() + fileName;
- URL profileUrl = new URL(profileLocation);
- downloadFile(profileUrl, profileFile, false);
- }
- }
- }
- }
-
- private void downloadSegment(String segmentBaseUrl, String segmentName) throws IOException, InterruptedException {
- File segmentFile = new File(baseDir, SEGMENTS_DIR + segmentName);
- File segmentFileTemp = new File(segmentFile.getAbsolutePath() + "_tmp");
- try {
- if (segmentFile.exists()) {
- updateProgress("Calculating local checksum...");
- String md5 = Rd5DiffManager.getMD5(segmentFile);
- String segmentDeltaLocation = segmentBaseUrl + "diff/" + segmentName.replace(SEGMENT_SUFFIX, "/" + md5 + SEGMENT_DIFF_SUFFIX);
- URL segmentDeltaUrl = new URL(segmentDeltaLocation);
- if (httpFileExists(segmentDeltaUrl)) {
- File segmentDeltaFile = new File(segmentFile.getAbsolutePath() + "_diff");
- try {
- downloadFile(segmentDeltaUrl, segmentDeltaFile, true);
- updateProgress("Applying delta...");
- Rd5DiffTool.recoverFromDelta(segmentFile, segmentDeltaFile, segmentFileTemp, this);
- } catch (IOException e) {
- throw new IOException("Failed to download & apply delta update", e);
- } finally {
- segmentDeltaFile.delete();
- }
- }
- }
-
- if (!segmentFileTemp.exists()) {
- URL segmentUrl = new URL(segmentBaseUrl + segmentName);
- downloadFile(segmentUrl, segmentFileTemp, true);
- }
-
- PhysicalFile.checkFileIntegrity(segmentFileTemp);
- if (segmentFile.exists()) {
- if (!segmentFile.delete()) {
- throw new IOException("Failed to delete existing " + segmentFile.getAbsolutePath());
- }
- }
-
- if (!segmentFileTemp.renameTo(segmentFile)) {
- throw new IOException("Failed to write " + segmentFile.getAbsolutePath());
- }
- } finally {
- segmentFileTemp.delete();
- }
- }
-
- private boolean httpFileExists(URL downloadUrl) throws IOException {
- HttpURLConnection connection = (HttpURLConnection) downloadUrl.openConnection();
- connection.setConnectTimeout(5000);
- connection.setRequestMethod("HEAD");
- connection.connect();
-
- return connection.getResponseCode() == HttpURLConnection.HTTP_OK;
- }
-
-
- private void downloadFile(URL downloadUrl, File outputFile, boolean limitDownloadSpeed) throws IOException, InterruptedException {
- // For all those small files the progress reporting is really noisy
- boolean reportDownloadProgress = limitDownloadSpeed;
- HttpURLConnection connection = (HttpURLConnection) downloadUrl.openConnection();
- connection.setConnectTimeout(5000);
- connection.connect();
-
- if (reportDownloadProgress) updateProgress("Connecting...");
-
- if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
- throw new IOException("HTTP Request failed");
- }
- int fileLength = connection.getContentLength();
- if (reportDownloadProgress) updateProgress("Loading");
-
- try (
- InputStream input = connection.getInputStream();
- OutputStream output = new FileOutputStream(outputFile)
- ) {
- byte[] buffer = new byte[4096];
- long total = 0;
- long t0 = System.currentTimeMillis();
- int count;
- while ((count = input.read(buffer)) != -1) {
- if (isCanceled()) {
- throw new InterruptedException();
- }
- total += count;
- // publishing the progress....
- if (fileLength > 0) // only if total length is known
- {
- int pct = (int) (total * 100 / fileLength);
- if (reportDownloadProgress) updateProgress("Progress " + pct + "%");
- } else {
- if (reportDownloadProgress) updateProgress("Progress (unknown size)");
- }
- output.write(buffer, 0, count);
-
- if (limitDownloadSpeed) {
- // enforce < 16 Mbit/s
- long dt = t0 + total / 2096 - System.currentTimeMillis();
- if (dt > 0) {
- Thread.sleep(dt);
- }
- }
- }
- }
- }
-
- public boolean isCanceled() {
- return BInstallerActivity.downloadCanceled;
- }
-
- // Handler that receives messages from the thread
- private final class ServiceHandler extends Handler {
- public ServiceHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- bIsDownloading = true;
- downloadFiles();
-
- stopForeground(true);
- stopSelf(msg.arg1);
- mNotificationHelper.stopNotification();
- }
- }
-
-}
diff --git a/brouter-routing-app/src/main/java/btools/routingapp/NotificationHelper.java b/brouter-routing-app/src/main/java/btools/routingapp/NotificationHelper.java
deleted file mode 100644
index a97f296..0000000
--- a/brouter-routing-app/src/main/java/btools/routingapp/NotificationHelper.java
+++ /dev/null
@@ -1,134 +0,0 @@
-package btools.routingapp;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.media.AudioAttributes;
-import android.os.Build;
-import android.util.Log;
-
-import androidx.core.app.NotificationCompat;
-
-
-import static android.content.Context.NOTIFICATION_SERVICE;
-
-public class NotificationHelper {
-
- private static final boolean DEBUG = false;
-
- public static String BRouterNotificationChannel1 = "brouter_channel_01";
-
- private Context mContext;
- private int NOTIFICATION_ID = 111;
- private Notification mNotification;
- private NotificationManager mNotificationManager;
- private PendingIntent mContentIntent;
- private CharSequence mContentTitle;
-
- public NotificationHelper(Context context) {
- if (DEBUG) Log.d("NH", "init ");
- mContext = context;
- createNotificationChannels();
- }
-
- public void startNotification(Service service) {
- if (DEBUG) Log.d("NH", "startNotification ");
-
- mNotification = createNotification("BRouter Download", "Download some files");
-
- if (service != null) service.startForeground(NOTIFICATION_ID, mNotification);
-
- mNotificationManager.notify(NOTIFICATION_ID, mNotification);
-
- }
-
- public void progressUpdate(String text) {
- mNotification = createNotification("BRouter Download", text);
- mNotification.flags = Notification.FLAG_NO_CLEAR |
- Notification.FLAG_ONGOING_EVENT;
-
- mNotificationManager.notify(NOTIFICATION_ID, mNotification);
- }
-
-
- public Notification createNotification(String title, String desc) {
-
- Intent resultIntent = new Intent(mContext, BInstallerActivity.class);
-
- Intent notificationIntent = new Intent();
- mContentIntent = PendingIntent.getActivity(mContext, 0, resultIntent, PendingIntent.FLAG_IMMUTABLE);
-
- mNotificationManager = (NotificationManager) mContext.getSystemService(NOTIFICATION_SERVICE);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-
-
- final NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, BRouterNotificationChannel1);
- builder.setSmallIcon(android.R.drawable.stat_sys_download)
- .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
- .setContentTitle(title)
- .setContentText(desc)
- .setTicker(desc)
- .setOngoing(true)
- .setAutoCancel(true)
- .setOnlyAlertOnce(true)
- .setCategory(NotificationCompat.CATEGORY_SERVICE)
- .setContentIntent(mContentIntent);
-
- return builder.build();
-
- } else {
- final NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
- builder.setSmallIcon(android.R.drawable.stat_sys_download)
- .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
- .setContentTitle(title)
- .setContentText(desc)
- .setOnlyAlertOnce(true)
- .setCategory(NotificationCompat.CATEGORY_SERVICE)
- .setContentIntent(mContentIntent);
-
- return builder.build();
- }
-
- }
-
- /**
- * create notification channels
- */
- public void createNotificationChannels() {
- if (DEBUG) Log.d("NH", "createNotificationChannels ");
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-
- NotificationManager sNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
- // Sound channel
- CharSequence name = "BRouter Download";
- // The user-visible description of the channel.
- String description = "BRouter Download Channel"; //getString(R.string.channel_description);
-
- NotificationChannel channel = new NotificationChannel(BRouterNotificationChannel1, name, NotificationManager.IMPORTANCE_LOW);
- channel.setDescription(description);
- AudioAttributes att = new AudioAttributes.Builder()
- .setUsage(AudioAttributes.USAGE_UNKNOWN)
- .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
- .build();
- channel.setSound(null, null);
- channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
-
- sNotificationManager.createNotificationChannel(channel);
-
- }
- }
-
- public void stopNotification() {
- if (DEBUG) Log.d("NH", "stopNotification ");
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- mNotificationManager.deleteNotificationChannel(BRouterNotificationChannel1);
- }
- mNotificationManager.cancel(NOTIFICATION_ID);
- }
-}