Show download progress in different view
This commit is contained in:
parent
6045a18a61
commit
51ef5c6aad
5 changed files with 124 additions and 91 deletions
|
@ -12,14 +12,24 @@ import android.content.pm.ActivityInfo;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.StatFs;
|
import android.os.StatFs;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class BInstallerActivity extends Activity {
|
public class BInstallerActivity extends Activity {
|
||||||
|
|
||||||
public static final String DOWNLOAD_ACTION = "btools.routingapp.download";
|
public static final String DOWNLOAD_ACTION = "btools.routingapp.download";
|
||||||
|
|
||||||
private static final int DIALOG_CONFIRM_DELETE_ID = 1;
|
private static final int DIALOG_CONFIRM_DELETE_ID = 1;
|
||||||
|
public static boolean downloadCanceled = false;
|
||||||
|
private File baseDir;
|
||||||
private BInstallerView mBInstallerView;
|
private BInstallerView mBInstallerView;
|
||||||
private DownloadReceiver downloadReceiver;
|
private DownloadReceiver downloadReceiver;
|
||||||
|
private View mDownloadInfo;
|
||||||
|
private TextView mDownloadInfoText;
|
||||||
|
private Button mButtonDownloadCancel;
|
||||||
|
|
||||||
static public long getAvailableSpace(String baseDir) {
|
static public long getAvailableSpace(String baseDir) {
|
||||||
StatFs stat = new StatFs(baseDir);
|
StatFs stat = new StatFs(baseDir);
|
||||||
|
@ -40,6 +50,58 @@ public class BInstallerActivity extends Activity {
|
||||||
|
|
||||||
setContentView(R.layout.activity_binstaller);
|
setContentView(R.layout.activity_binstaller);
|
||||||
mBInstallerView = findViewById(R.id.BInstallerView);
|
mBInstallerView = findViewById(R.id.BInstallerView);
|
||||||
|
mDownloadInfo = findViewById(R.id.view_download_progress);
|
||||||
|
mDownloadInfoText = findViewById(R.id.textViewDownloadProgress);
|
||||||
|
mButtonDownloadCancel = findViewById(R.id.buttonDownloadCancel);
|
||||||
|
mButtonDownloadCancel.setOnClickListener(view -> {
|
||||||
|
cancelDownload();
|
||||||
|
});
|
||||||
|
|
||||||
|
baseDir = ConfigHelper.getBaseDir(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String baseNameForTile(int tileIndex) {
|
||||||
|
int lon = (tileIndex % 72) * 5 - 180;
|
||||||
|
int lat = (tileIndex / 72) * 5 - 90;
|
||||||
|
String slon = lon < 0 ? "W" + (-lon) : "E" + lon;
|
||||||
|
String slat = lat < 0 ? "S" + (-lat) : "N" + lat;
|
||||||
|
return slon + "_" + slat;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteRawTracks() {
|
||||||
|
File modeDir = new File(baseDir, "brouter/modes");
|
||||||
|
String[] fileNames = modeDir.list();
|
||||||
|
if (fileNames == null) return;
|
||||||
|
for (String fileName : fileNames) {
|
||||||
|
if (fileName.endsWith("_rawtrack.dat")) {
|
||||||
|
File f = new File(modeDir, fileName);
|
||||||
|
f.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancelDownload() {
|
||||||
|
downloadCanceled = true;
|
||||||
|
mDownloadInfoText.setText(getString(R.string.download_info_cancel));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void downloadAll(ArrayList<Integer> downloadList) {
|
||||||
|
ArrayList<String> urlparts = new ArrayList<>();
|
||||||
|
for (Integer i : downloadList) {
|
||||||
|
urlparts.add(baseNameForTile(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
mBInstallerView.setVisibility(View.GONE);
|
||||||
|
mDownloadInfo.setVisibility(View.VISIBLE);
|
||||||
|
downloadCanceled = false;
|
||||||
|
mDownloadInfoText.setText(R.string.download_info_start);
|
||||||
|
|
||||||
|
Intent intent = new Intent(this, DownloadService.class);
|
||||||
|
intent.putExtra("dir", baseDir.getAbsolutePath() + "/brouter/");
|
||||||
|
intent.putExtra("urlparts", urlparts);
|
||||||
|
startService(intent);
|
||||||
|
|
||||||
|
deleteRawTracks(); // invalidate raw-tracks after data update
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -99,7 +161,12 @@ public class BInstallerActivity extends Activity {
|
||||||
if (intent.hasExtra("txt")) {
|
if (intent.hasExtra("txt")) {
|
||||||
String txt = intent.getStringExtra("txt");
|
String txt = intent.getStringExtra("txt");
|
||||||
boolean ready = intent.getBooleanExtra("ready", false);
|
boolean ready = intent.getBooleanExtra("ready", false);
|
||||||
mBInstallerView.setState(txt, ready);
|
if (!ready) {
|
||||||
|
mBInstallerView.setVisibility(View.VISIBLE);
|
||||||
|
mDownloadInfo.setVisibility(View.GONE);
|
||||||
|
scanExistingFiles();
|
||||||
|
}
|
||||||
|
mDownloadInfoText.setText(txt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package btools.routingapp;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
|
@ -28,7 +27,12 @@ public class BInstallerView extends View {
|
||||||
private static final int MASK_DELETED_RD5 = 2;
|
private static final int MASK_DELETED_RD5 = 2;
|
||||||
private static final int MASK_INSTALLED_RD5 = 4;
|
private static final int MASK_INSTALLED_RD5 = 4;
|
||||||
private static final int MASK_CURRENT_RD5 = 8;
|
private static final int MASK_CURRENT_RD5 = 8;
|
||||||
public static boolean downloadCanceled = false;
|
private final File baseDir;
|
||||||
|
private final File segmentDir;
|
||||||
|
private final Matrix mat;
|
||||||
|
private final Bitmap bmp;
|
||||||
|
private final float viewscale;
|
||||||
|
private final int[] tileStatus;
|
||||||
private final int imgwOrig;
|
private final int imgwOrig;
|
||||||
private final int imghOrig;
|
private final int imghOrig;
|
||||||
private final float scaleOrig;
|
private final float scaleOrig;
|
||||||
|
@ -36,12 +40,6 @@ public class BInstallerView extends View {
|
||||||
private final int imgh;
|
private final int imgh;
|
||||||
private final float[] testVector = new float[2];
|
private final float[] testVector = new float[2];
|
||||||
private final Matrix matText;
|
private final Matrix matText;
|
||||||
private final File baseDir;
|
|
||||||
private final File segmentDir;
|
|
||||||
private final Matrix mat;
|
|
||||||
private final Bitmap bmp;
|
|
||||||
private final float viewscale;
|
|
||||||
private final int[] tileStatus;
|
|
||||||
Paint pnt_1 = new Paint();
|
Paint pnt_1 = new Paint();
|
||||||
Paint pnt_2 = new Paint();
|
Paint pnt_2 = new Paint();
|
||||||
Paint paint = new Paint();
|
Paint paint = new Paint();
|
||||||
|
@ -53,9 +51,6 @@ public class BInstallerView extends View {
|
||||||
private float lastDownY;
|
private float lastDownY;
|
||||||
private boolean tilesVisible = false;
|
private boolean tilesVisible = false;
|
||||||
private long availableSize;
|
private long availableSize;
|
||||||
private boolean isDownloading = false;
|
|
||||||
private volatile String currentDownloadOperation = "";
|
|
||||||
private String downloadAction = "";
|
|
||||||
private long totalSize = 0;
|
private long totalSize = 0;
|
||||||
private long rd5Tiles = 0;
|
private long rd5Tiles = 0;
|
||||||
private long delTiles = 0;
|
private long delTiles = 0;
|
||||||
|
@ -130,12 +125,6 @@ public class BInstallerView extends View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toggleDownload() {
|
private void toggleDownload() {
|
||||||
if (isDownloading) {
|
|
||||||
downloadCanceled = true;
|
|
||||||
downloadAction = "Canceling...";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (delTiles > 0) {
|
if (delTiles > 0) {
|
||||||
((BInstallerActivity) getContext()).showConfirmDelete();
|
((BInstallerActivity) getContext()).showConfirmDelete();
|
||||||
return;
|
return;
|
||||||
|
@ -159,8 +148,8 @@ public class BInstallerView extends View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (downloadList.size() > 0) {
|
if (downloadList.size() > 0) {
|
||||||
isDownloading = true;
|
// isDownloading = true;
|
||||||
downloadAll(downloadList);
|
((BInstallerActivity) getContext()).downloadAll(downloadList);
|
||||||
for (Integer i : downloadList) {
|
for (Integer i : downloadList) {
|
||||||
tileStatus[i] ^= tileStatus[i] & MASK_SELECTED_RD5;
|
tileStatus[i] ^= tileStatus[i] & MASK_SELECTED_RD5;
|
||||||
}
|
}
|
||||||
|
@ -168,35 +157,6 @@ public class BInstallerView extends View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void downloadAll(ArrayList<Integer> downloadList) {
|
|
||||||
ArrayList<String> urlparts = new ArrayList<>();
|
|
||||||
for (Integer i : downloadList) {
|
|
||||||
urlparts.add(baseNameForTile(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
currentDownloadOperation = "Start download ...";
|
|
||||||
downloadAction = "";
|
|
||||||
downloadCanceled = false;
|
|
||||||
isDownloading = true;
|
|
||||||
|
|
||||||
Intent intent = new Intent(mActivity, DownloadService.class);
|
|
||||||
intent.putExtra("dir", baseDir.getAbsolutePath() + "/brouter/");
|
|
||||||
intent.putExtra("urlparts", urlparts);
|
|
||||||
mActivity.startService(intent);
|
|
||||||
|
|
||||||
deleteRawTracks(); // invalidate raw-tracks after data update
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setState(String txt, boolean b) {
|
|
||||||
currentDownloadOperation = txt;
|
|
||||||
downloadAction = "";
|
|
||||||
isDownloading = b;
|
|
||||||
if (!b) {
|
|
||||||
scanExistingFiles();
|
|
||||||
}
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private int tileIndex(float x, float y) {
|
private int tileIndex(float x, float y) {
|
||||||
int ix = (int) (72.f * x / bmp.getWidth());
|
int ix = (int) (72.f * x / bmp.getWidth());
|
||||||
int iy = (int) (36.f * y / bmp.getHeight());
|
int iy = (int) (36.f * y / bmp.getHeight());
|
||||||
|
@ -220,18 +180,6 @@ public class BInstallerView extends View {
|
||||||
return testVector[1] / viewscale;
|
return testVector[1] / viewscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteRawTracks() {
|
|
||||||
File modeDir = new File(baseDir, "brouter/modes");
|
|
||||||
String[] fileNames = modeDir.list();
|
|
||||||
if (fileNames == null) return;
|
|
||||||
for (String fileName : fileNames) {
|
|
||||||
if (fileName.endsWith("_rawtrack.dat")) {
|
|
||||||
File f = new File(modeDir, fileName);
|
|
||||||
f.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void scanExistingFiles() {
|
private void scanExistingFiles() {
|
||||||
clearTileSelection(MASK_INSTALLED_RD5 | MASK_CURRENT_RD5);
|
clearTileSelection(MASK_INSTALLED_RD5 | MASK_CURRENT_RD5);
|
||||||
|
|
||||||
|
@ -271,10 +219,8 @@ public class BInstallerView extends View {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDraw(Canvas canvas) {
|
protected void onDraw(Canvas canvas) {
|
||||||
if (!isDownloading) {
|
canvas.setMatrix(mat);
|
||||||
canvas.setMatrix(mat);
|
canvas.drawBitmap(bmp, 0, 0, null);
|
||||||
canvas.drawBitmap(bmp, 0, 0, null);
|
|
||||||
}
|
|
||||||
// draw 5*5 lattice starting at scale=3
|
// draw 5*5 lattice starting at scale=3
|
||||||
|
|
||||||
int iw = bmp.getWidth();
|
int iw = bmp.getWidth();
|
||||||
|
@ -282,9 +228,7 @@ public class BInstallerView extends View {
|
||||||
float fw = iw / 72.f;
|
float fw = iw / 72.f;
|
||||||
float fh = ih / 36.f;
|
float fh = ih / 36.f;
|
||||||
|
|
||||||
boolean drawGrid = tilesVisible && !isDownloading;
|
if (tilesVisible) {
|
||||||
|
|
||||||
if (drawGrid) {
|
|
||||||
pnt_1.setColor(Color.GREEN);
|
pnt_1.setColor(Color.GREEN);
|
||||||
pnt_1.setStyle(Paint.Style.STROKE);
|
pnt_1.setStyle(Paint.Style.STROKE);
|
||||||
for (int ix = 0; ix < 72; ix++) {
|
for (int ix = 0; ix < 72; ix++) {
|
||||||
|
@ -307,19 +251,19 @@ public class BInstallerView extends View {
|
||||||
pnt_2.setStyle(Paint.Style.STROKE);
|
pnt_2.setStyle(Paint.Style.STROKE);
|
||||||
pnt_2.setColor(Color.GRAY);
|
pnt_2.setColor(Color.GRAY);
|
||||||
pnt_2.setStrokeWidth(1);
|
pnt_2.setStrokeWidth(1);
|
||||||
drawSelectedTiles(canvas, pnt_2, fw, fh, MASK_INSTALLED_RD5, mask3, false, false, drawGrid);
|
drawSelectedTiles(canvas, pnt_2, fw, fh, MASK_INSTALLED_RD5, mask3, false, false, tilesVisible);
|
||||||
pnt_2.setColor(Color.BLUE);
|
pnt_2.setColor(Color.BLUE);
|
||||||
pnt_2.setStrokeWidth(1);
|
pnt_2.setStrokeWidth(1);
|
||||||
drawSelectedTiles(canvas, pnt_2, fw, fh, MASK_INSTALLED_RD5 | MASK_CURRENT_RD5, mask3, false, false, drawGrid);
|
drawSelectedTiles(canvas, pnt_2, fw, fh, MASK_INSTALLED_RD5 | MASK_CURRENT_RD5, mask3, false, false, tilesVisible);
|
||||||
pnt_2.setColor(Color.GREEN);
|
pnt_2.setColor(Color.GREEN);
|
||||||
pnt_2.setStrokeWidth(2);
|
pnt_2.setStrokeWidth(2);
|
||||||
drawSelectedTiles(canvas, pnt_2, fw, fh, MASK_SELECTED_RD5, mask2, true, false, drawGrid);
|
drawSelectedTiles(canvas, pnt_2, fw, fh, MASK_SELECTED_RD5, mask2, true, false, tilesVisible);
|
||||||
pnt_2.setColor(Color.YELLOW);
|
pnt_2.setColor(Color.YELLOW);
|
||||||
pnt_2.setStrokeWidth(2);
|
pnt_2.setStrokeWidth(2);
|
||||||
drawSelectedTiles(canvas, pnt_2, fw, fh, MASK_SELECTED_RD5 | MASK_INSTALLED_RD5, mask2, true, false, drawGrid);
|
drawSelectedTiles(canvas, pnt_2, fw, fh, MASK_SELECTED_RD5 | MASK_INSTALLED_RD5, mask2, true, false, tilesVisible);
|
||||||
pnt_2.setColor(Color.RED);
|
pnt_2.setColor(Color.RED);
|
||||||
pnt_2.setStrokeWidth(2);
|
pnt_2.setStrokeWidth(2);
|
||||||
drawSelectedTiles(canvas, pnt_2, fw, fh, MASK_DELETED_RD5 | MASK_INSTALLED_RD5, mask2, false, true, drawGrid);
|
drawSelectedTiles(canvas, pnt_2, fw, fh, MASK_DELETED_RD5 | MASK_INSTALLED_RD5, mask2, false, true, tilesVisible);
|
||||||
|
|
||||||
canvas.setMatrix(matText);
|
canvas.setMatrix(matText);
|
||||||
|
|
||||||
|
@ -327,13 +271,7 @@ public class BInstallerView extends View {
|
||||||
|
|
||||||
long mb = 1024 * 1024;
|
long mb = 1024 * 1024;
|
||||||
|
|
||||||
if (isDownloading) {
|
if (!this.tilesVisible) {
|
||||||
paint.setTextSize(30);
|
|
||||||
canvas.drawText(currentDownloadOperation, 30, (imgh / 3) * 2 - 30, paint);
|
|
||||||
// canvas.drawText( currentDownloadOperation + " " + currentDownloadFile + sizeHint, 30, (imgh/3)*2-30, paint);
|
|
||||||
canvas.drawText(downloadAction, 30, (imgh / 3) * 2, paint);
|
|
||||||
}
|
|
||||||
if (!tilesVisible && !isDownloading) {
|
|
||||||
paint.setTextSize(35);
|
paint.setTextSize(35);
|
||||||
canvas.drawText("Touch region to zoom in!", 30, (imgh / 3) * 2, paint);
|
canvas.drawText("Touch region to zoom in!", 30, (imgh / 3) * 2, paint);
|
||||||
}
|
}
|
||||||
|
@ -347,10 +285,9 @@ public class BInstallerView extends View {
|
||||||
|
|
||||||
|
|
||||||
String btnText = null;
|
String btnText = null;
|
||||||
if (isDownloading) btnText = "Cancel Download";
|
if (delTiles > 0) btnText = "Delete " + delTiles + " tiles";
|
||||||
else if (delTiles > 0) btnText = "Delete " + delTiles + " tiles";
|
|
||||||
else if (rd5Tiles > 0) btnText = "Start Download";
|
else if (rd5Tiles > 0) btnText = "Start Download";
|
||||||
else if (tilesVisible &&
|
else if (this.tilesVisible &&
|
||||||
rd5Tiles == 0 &&
|
rd5Tiles == 0 &&
|
||||||
RoutingHelper.hasDirectoryAnyDatafiles(segmentDir)) btnText = "Update all";
|
RoutingHelper.hasDirectoryAnyDatafiles(segmentDir)) btnText = "Update all";
|
||||||
|
|
||||||
|
@ -420,7 +357,6 @@ public class BInstallerView extends View {
|
||||||
}
|
}
|
||||||
case MotionEvent.ACTION_MOVE: { // a pointer was moved
|
case MotionEvent.ACTION_MOVE: { // a pointer was moved
|
||||||
|
|
||||||
if (isDownloading) break;
|
|
||||||
int np = event.getPointerCount();
|
int np = event.getPointerCount();
|
||||||
int nh = event.getHistorySize();
|
int nh = event.getHistorySize();
|
||||||
if (nh == 0) break;
|
if (nh == 0) break;
|
||||||
|
@ -482,7 +418,7 @@ public class BInstallerView extends View {
|
||||||
}
|
}
|
||||||
|
|
||||||
// download button?
|
// download button?
|
||||||
if ((delTiles > 0 || rd5Tiles >= 0 || isDownloading) && event.getX() > imgwOrig - btnw * scaleOrig && event.getY() > imghOrig - btnh * scaleOrig) {
|
if ((delTiles > 0 || rd5Tiles >= 0) && event.getX() > imgwOrig - btnw * scaleOrig && event.getY() > imghOrig - btnh * scaleOrig) {
|
||||||
if (rd5Tiles == 0) {
|
if (rd5Tiles == 0) {
|
||||||
for (int ix = 0; ix < 72; ix++) {
|
for (int ix = 0; ix < 72; ix++) {
|
||||||
for (int iy = 0; iy < 36; iy++) {
|
for (int iy = 0; iy < 36; iy++) {
|
||||||
|
@ -511,8 +447,6 @@ public class BInstallerView extends View {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDownloading) break;
|
|
||||||
|
|
||||||
Matrix imat = new Matrix();
|
Matrix imat = new Matrix();
|
||||||
if (mat.invert(imat)) {
|
if (mat.invert(imat)) {
|
||||||
float[] touchpoint = new float[2];
|
float[] touchpoint = new float[2];
|
||||||
|
|
|
@ -481,7 +481,7 @@ public class DownloadService extends Service implements ProgressListener {
|
||||||
|
|
||||||
|
|
||||||
public boolean isCanceled() {
|
public boolean isCanceled() {
|
||||||
return BInstallerView.downloadCanceled;
|
return BInstallerActivity.downloadCanceled;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,40 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<btools.routingapp.BInstallerView
|
<btools.routingapp.BInstallerView
|
||||||
android:id="@+id/BInstallerView"
|
android:id="@+id/BInstallerView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/view_download_progress"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textViewDownloadProgress"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="34sp" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/buttonDownloadCancel"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|end"
|
||||||
|
android:text="@string/cancel_download" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">BRouter</string>
|
<string name="app_name">BRouter</string>
|
||||||
|
<string name="cancel_download">Cancel Download</string>
|
||||||
<string name="import_profile">Import Profile</string>
|
<string name="import_profile">Import Profile</string>
|
||||||
<string name="profile_filename_example">filename.brf</string>
|
<string name="profile_filename_example">filename.brf</string>
|
||||||
|
<string name="download_info_start">Starting download…</string>
|
||||||
|
<string name="download_info_cancel">Cancelling…</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue