forked from organicmaps/organicmaps
[android] Added download catalog component
This commit is contained in:
parent
de9dc6ec1f
commit
0e07e10e42
7 changed files with 366 additions and 0 deletions
|
@ -236,6 +236,12 @@
|
|||
android:configChanges="orientation|screenLayout|screenSize"
|
||||
android:label="@string/app_name"/>
|
||||
|
||||
<!--
|
||||
<activity
|
||||
android:name="com.mapswithme.maps.bookmarks.BookmarksCatalogActivity"
|
||||
android:label="@string/routes_and_bookmarks"/>
|
||||
-->
|
||||
|
||||
<activity-alias
|
||||
android:name="com.mapswithme.maps.DownloadResourcesActivity"
|
||||
android:label="@string/app_name"
|
||||
|
@ -497,6 +503,19 @@
|
|||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver
|
||||
android:name="com.mapswithme.maps.bookmarks.SystemDownloadCompletedReceiver"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service
|
||||
android:name="com.mapswithme.maps.bookmarks.SystemDownloadCompletedService"
|
||||
android:exported="false">
|
||||
</service>
|
||||
|
||||
<!-- Took this legacy code from https://www.pushwoosh.com/docs/gcm-integration-legacy.
|
||||
Remove it after Pushwoosh is removed. -->
|
||||
<service
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
package com.mapswithme.maps.bookmarks;
|
||||
|
||||
import android.app.DownloadManager;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.mapswithme.maps.bookmarks.data.BookmarkManager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
public class BookmarksDownloadManager
|
||||
{
|
||||
private static final String QUERY_PARAM_ID_KEY = "id";
|
||||
private static final String QUERY_PARAM_NAME_KEY = "name";
|
||||
|
||||
@NonNull
|
||||
private final Context mContext;
|
||||
@Nullable
|
||||
private final DownloadManager mWrapped;
|
||||
|
||||
private BookmarksDownloadManager(@NonNull Context context)
|
||||
{
|
||||
mContext = context.getApplicationContext();
|
||||
mWrapped = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||
}
|
||||
|
||||
public long enqueueRequest(@NonNull String url) throws IOException
|
||||
{
|
||||
if (mWrapped == null){
|
||||
throw new IOException("system DownloadManager is null");
|
||||
}
|
||||
|
||||
Pair<Uri, Uri> uriPair = onPrepareUriPair(url);
|
||||
Uri srcUri = uriPair.first;
|
||||
Uri dstUri = uriPair.second;
|
||||
|
||||
String title = getTitle(srcUri);
|
||||
DownloadManager.Request request = new DownloadManager
|
||||
.Request(dstUri)
|
||||
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
|
||||
.setTitle(title)
|
||||
.setDestinationInExternalFilesDir(
|
||||
mContext,
|
||||
null,
|
||||
dstUri.getLastPathSegment());
|
||||
return mWrapped.enqueue(request);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String getTitle(Uri srcUri)
|
||||
{
|
||||
String title;
|
||||
return TextUtils.isEmpty((title = srcUri.getQueryParameter(QUERY_PARAM_NAME_KEY)))
|
||||
? srcUri.getQueryParameter(QUERY_PARAM_ID_KEY)
|
||||
: title;
|
||||
}
|
||||
|
||||
private Pair<Uri, Uri> onPrepareUriPair(String url)
|
||||
{
|
||||
Uri srcUri = Uri.parse(url);
|
||||
String fileId = srcUri.getQueryParameter(QUERY_PARAM_ID_KEY);
|
||||
if (TextUtils.isEmpty(fileId)){
|
||||
throw new IllegalArgumentException("query param id not found");
|
||||
}
|
||||
String downloadUrl = BookmarkManager.INSTANCE.getCatalogDownloadUrl(fileId);
|
||||
Uri.Builder builder = Uri.parse(downloadUrl).buildUpon();
|
||||
|
||||
Set<String> paramNames = srcUri.getQueryParameterNames();
|
||||
for (String each : paramNames){
|
||||
builder.appendQueryParameter(each, srcUri.getQueryParameter(each));
|
||||
}
|
||||
Uri dstUri = builder.build();
|
||||
return new Pair<>(srcUri, dstUri);
|
||||
}
|
||||
|
||||
public static BookmarksDownloadManager from(Context context)
|
||||
{
|
||||
return new BookmarksDownloadManager(context);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
package com.mapswithme.maps.bookmarks;
|
||||
|
||||
import android.app.DownloadManager;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.mapswithme.maps.bookmarks.data.BookmarkManager;
|
||||
import com.mapswithme.util.Utils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
class GetFileMetaDataTask extends AsyncTask<Intent, Void, OperationStatus<GetFileMetaDataTask.Result,
|
||||
GetFileMetaDataTask.Error>>
|
||||
{
|
||||
@NonNull
|
||||
private final DownloadManager mDownloadManager;
|
||||
|
||||
private GetFileMetaDataTask(@NonNull DownloadManager downloadManager)
|
||||
{
|
||||
mDownloadManager = downloadManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OperationStatus<Result, Error> doInBackground(Intent... intents)
|
||||
{
|
||||
Intent intent = intents[0];
|
||||
try
|
||||
{
|
||||
Result result = doInBackgroundInternal(intent);
|
||||
return new OperationStatus<>(result, null);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return new OperationStatus<>(null, new Error(e));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(OperationStatus<Result, Error> status)
|
||||
{
|
||||
if (status.isOk())
|
||||
{
|
||||
Result result = status.getResult();
|
||||
BookmarkManager.INSTANCE.importFromCatalog(result.getArchiveId(), result.getFilePath());
|
||||
}
|
||||
}
|
||||
|
||||
public static GetFileMetaDataTask create(DownloadManager manager)
|
||||
{
|
||||
return new GetFileMetaDataTask(manager);
|
||||
}
|
||||
|
||||
public static class Result
|
||||
{
|
||||
@Nullable
|
||||
private final String mFilePath;
|
||||
@Nullable
|
||||
private final String mArchiveId;
|
||||
|
||||
public Result(@Nullable String filePath, @Nullable String archiveId)
|
||||
{
|
||||
mFilePath = filePath;
|
||||
mArchiveId = archiveId;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getFilePath()
|
||||
{
|
||||
return mFilePath;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getArchiveId()
|
||||
{
|
||||
return mArchiveId;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Error
|
||||
{
|
||||
@Nullable
|
||||
private Throwable mThrowable;
|
||||
|
||||
public Error(@Nullable Throwable throwable)
|
||||
{
|
||||
mThrowable = throwable;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Throwable getThrowable()
|
||||
{
|
||||
return mThrowable;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Result doInBackgroundInternal(@NonNull Intent intent) throws IOException
|
||||
{
|
||||
Cursor cursor = null;
|
||||
try
|
||||
{
|
||||
final long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
|
||||
DownloadManager.Query query = new DownloadManager.Query().setFilterById(id);
|
||||
cursor = mDownloadManager.query(query);
|
||||
if (cursor.moveToFirst())
|
||||
{
|
||||
String filePath = getFilePath(cursor);
|
||||
String archiveId = getArchiveId(cursor);
|
||||
return new Result(filePath, archiveId);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException("Failed to move the cursor at first row");
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Utils.closeSafely(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
private String getFilePath(Cursor cursor) throws IOException
|
||||
{
|
||||
return getColumnValue(cursor, DownloadManager.COLUMN_LOCAL_FILENAME);
|
||||
}
|
||||
|
||||
private String getArchiveId(Cursor cursor) throws IOException
|
||||
{
|
||||
return Uri.parse(getColumnValue(cursor, DownloadManager.COLUMN_URI)).getLastPathSegment();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getColumnValue(@NonNull Cursor cursor, @NonNull String columnName)
|
||||
throws IOException
|
||||
{
|
||||
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
|
||||
if (status == DownloadManager.STATUS_SUCCESSFUL)
|
||||
{
|
||||
return cursor.getString(cursor.getColumnIndex(columnName));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException(new StringBuilder().append("Failed to download archive, status code = ")
|
||||
.append(status)
|
||||
.toString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.mapswithme.maps.bookmarks;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
public class OperationStatus<R, E> {
|
||||
@Nullable private final R mResult;
|
||||
@Nullable private final E mError;
|
||||
|
||||
OperationStatus(@Nullable R result, @Nullable E error) {
|
||||
mResult = result;
|
||||
mError = error;
|
||||
}
|
||||
|
||||
public boolean isOk() {
|
||||
return mError == null;
|
||||
}
|
||||
|
||||
public boolean isNotOk() {
|
||||
return !isOk();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public R getResult() {
|
||||
return mResult;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public E getError() {
|
||||
return mError;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.mapswithme.maps.bookmarks;
|
||||
|
||||
import android.app.DownloadManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
public class SystemDownloadCompletedReceiver extends BroadcastReceiver
|
||||
{
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||
if (manager == null
|
||||
|| intent == null
|
||||
|| !DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
intent.setClass(context, SystemDownloadCompletedService.class);
|
||||
context.startService(intent);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.mapswithme.maps.bookmarks;
|
||||
|
||||
import android.app.DownloadManager;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
public class SystemDownloadCompletedService extends Service
|
||||
{
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId)
|
||||
{
|
||||
requestArchiveMetadata(intent);
|
||||
return START_REDELIVER_INTENT;
|
||||
}
|
||||
|
||||
private void requestArchiveMetadata(Intent intent)
|
||||
{
|
||||
DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
|
||||
if (manager != null)
|
||||
{
|
||||
GetFileMetaDataTask.create(manager).execute(intent);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -233,6 +233,28 @@ public class Utils
|
|||
}
|
||||
}
|
||||
|
||||
public static <T> T castTo(Object instance)
|
||||
{
|
||||
return (T)instance;
|
||||
}
|
||||
|
||||
public static void closeSafely(Closeable... closeable)
|
||||
{
|
||||
for (Closeable each : closeable){
|
||||
if (each != null){
|
||||
try
|
||||
{
|
||||
each.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOGGER.e(TAG, "there's something wrong = " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void sendSupportMail(@NonNull Activity activity, @NonNull String subject)
|
||||
{
|
||||
LoggerFactory.INSTANCE.zipLogs(new OnZipCompletedCallback(activity, subject));
|
||||
|
|
Loading…
Add table
Reference in a new issue