diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/OfflineManagerTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/OfflineManagerTest.kt index dd22d28f847..f702f8dafa5 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/OfflineManagerTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/offline/OfflineManagerTest.kt @@ -1,25 +1,22 @@ package com.mapbox.mapboxsdk.testapp.offline -import android.R import android.content.Context -import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.Espresso import android.support.test.espresso.IdlingRegistry import android.support.test.espresso.UiController -import android.support.test.espresso.assertion.ViewAssertions.matches import android.support.test.espresso.idling.CountingIdlingResource -import android.support.test.espresso.matcher.ViewMatchers.isDisplayed -import android.support.test.espresso.matcher.ViewMatchers.withId import android.support.test.runner.AndroidJUnit4 import com.mapbox.mapboxsdk.maps.MapboxMap import com.mapbox.mapboxsdk.offline.OfflineManager import com.mapbox.mapboxsdk.offline.OfflineRegion +import com.mapbox.mapboxsdk.storage.FileSource import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity +import com.mapbox.mapboxsdk.testapp.utils.FileUtils import org.junit.Test import org.junit.runner.RunWith -import java.io.File -import java.io.FileOutputStream +import java.io.IOException @RunWith(AndroidJUnit4::class) class OfflineManagerTest : BaseActivityTest() { @@ -48,19 +45,26 @@ class OfflineManagerTest : BaseActivityTest() { invoke(mapboxMap) { _: UiController, _: MapboxMap -> offlineIdlingResource.increment() - copyAsset(context) - OfflineManager.getInstance(context).mergeOfflineRegions( - context.filesDir.absolutePath + "/" + TEST_DB_FILE_NAME, - object : OfflineManager.MergeOfflineRegionsCallback { - override fun onMerge(offlineRegions: Array?) { - assert(offlineRegions?.size == 1) - offlineIdlingResource.decrement() - } + FileUtils.CopyFileFromAssetsTask(rule.activity, object : FileUtils.OnFileCopiedFromAssetsListener { + override fun onFileCopiedFromAssets() { + OfflineManager.getInstance(context).mergeOfflineRegions( + FileSource.getResourcesCachePath(rule.activity) + "/" + TEST_DB_FILE_NAME, + object : OfflineManager.MergeOfflineRegionsCallback { + override fun onMerge(offlineRegions: Array?) { + assert(offlineRegions?.size == 1) + offlineIdlingResource.decrement() + } + + override fun onError(error: String?) { + throw RuntimeException("Unable to merge external offline database. $error") + } + }) + } - override fun onError(error: String?) { - throw RuntimeException("Unable to merge external offline database. $error") - } - }) + override fun onError() { + throw IOException("Unable to copy DB file.") + } + }).execute(TEST_DB_FILE_NAME, FileSource.getResourcesCachePath(rule.activity)) } invoke(mapboxMap) { _: UiController, _: MapboxMap -> @@ -94,26 +98,11 @@ class OfflineManagerTest : BaseActivityTest() { } // waiting for offline idling resource - onView(withId(R.id.content)).check(matches(isDisplayed())) + Espresso.onIdle() } override fun afterTest() { super.afterTest() IdlingRegistry.getInstance().unregister(offlineIdlingResource) } - - private fun copyAsset(context: Context) { - val bufferSize = 1024 - val assetManager = context.assets - val inputStream = assetManager.open(TEST_DB_FILE_NAME) - val outputStream = FileOutputStream(File(context.filesDir.absoluteFile, TEST_DB_FILE_NAME)) - - try { - inputStream.copyTo(outputStream, bufferSize) - } finally { - inputStream.close() - outputStream.flush() - outputStream.close() - } - } } \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/MergeOfflineRegionsActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/MergeOfflineRegionsActivity.kt index 9905733a687..fea571f1e0f 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/MergeOfflineRegionsActivity.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/MergeOfflineRegionsActivity.kt @@ -1,10 +1,6 @@ package com.mapbox.mapboxsdk.testapp.activity.offline -import android.Manifest -import android.content.pm.PackageManager import android.os.Bundle -import android.support.v4.app.ActivityCompat -import android.support.v4.content.ContextCompat import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.mapbox.mapboxsdk.Mapbox @@ -12,15 +8,15 @@ import com.mapbox.mapboxsdk.constants.Style import com.mapbox.mapboxsdk.log.Logger import com.mapbox.mapboxsdk.offline.OfflineManager import com.mapbox.mapboxsdk.offline.OfflineRegion +import com.mapbox.mapboxsdk.storage.FileSource import com.mapbox.mapboxsdk.testapp.R +import com.mapbox.mapboxsdk.testapp.utils.FileUtils import kotlinx.android.synthetic.main.activity_merge_offline_regions.* -import java.io.File -import java.io.FileOutputStream class MergeOfflineRegionsActivity : AppCompatActivity() { companion object { + private const val LOG_TAG = "Mbgl-MergeOfflineRegionsActivity" private const val TEST_DB_FILE_NAME = "offline.db" - private const val PERMISSIONS_REQUEST_CODE = 11 } override fun onCreate(savedInstanceState: Bundle?) { @@ -34,34 +30,29 @@ class MergeOfflineRegionsActivity : AppCompatActivity() { mapView.onCreate(savedInstanceState) load_region_btn.setOnClickListener { - if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) { - ActivityCompat.requestPermissions(this, - arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), PERMISSIONS_REQUEST_CODE) - } else { - mergeDb() - } + copyAsset() } } - override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - if (requestCode == PERMISSIONS_REQUEST_CODE) { - for (result in grantResults) { - if (result != PackageManager.PERMISSION_GRANTED) { - finish() - } + private fun copyAsset() { + // copy db asset to internal memory + FileUtils.CopyFileFromAssetsTask(this, object : FileUtils.OnFileCopiedFromAssetsListener { + override fun onFileCopiedFromAssets() { + mergeDb() } - mergeDb() - } + + override fun onError() { + Toast.makeText( + this@MergeOfflineRegionsActivity, + String.format("Error copying DB file."), + Toast.LENGTH_LONG).show() + } + }).execute(TEST_DB_FILE_NAME, FileSource.getResourcesCachePath(this)) } private fun mergeDb() { - // copy db asset to internal memory - copyAsset() - OfflineManager.getInstance(this).mergeOfflineRegions( - this.filesDir.absolutePath + "/" + TEST_DB_FILE_NAME, + FileSource.getResourcesCachePath(this) + "/" + TEST_DB_FILE_NAME, object : OfflineManager.MergeOfflineRegionsCallback { override fun onMerge(offlineRegions: Array) { mapView.setStyleUrl(Style.SATELLITE) @@ -72,26 +63,15 @@ class MergeOfflineRegionsActivity : AppCompatActivity() { } override fun onError(error: String) { - Logger.e("MBGL_OFFLINE_DB_MERGE", error) + Toast.makeText( + this@MergeOfflineRegionsActivity, + String.format("Offline DB merge error."), + Toast.LENGTH_LONG).show() + Logger.e(LOG_TAG, error) } }) } - private fun copyAsset() { - val bufferSize = 1024 - val assetManager = this.assets - val inputStream = assetManager.open(TEST_DB_FILE_NAME) - val outputStream = FileOutputStream(File(this.filesDir, TEST_DB_FILE_NAME)) - - try { - inputStream.copyTo(outputStream, bufferSize) - } finally { - inputStream.close() - outputStream.flush() - outputStream.close() - } - } - override fun onStart() { super.onStart() mapView.onStart() @@ -120,6 +100,9 @@ class MergeOfflineRegionsActivity : AppCompatActivity() { override fun onDestroy() { super.onDestroy() mapView.onDestroy() + + // restoring connectivity state + Mapbox.setConnected(null) } override fun onSaveInstanceState(outState: Bundle) { diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/FileUtils.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/FileUtils.kt new file mode 100644 index 00000000000..26f2a2c56be --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/FileUtils.kt @@ -0,0 +1,65 @@ +package com.mapbox.mapboxsdk.testapp.utils + +import android.content.Context +import android.os.AsyncTask +import java.io.File +import java.io.FileOutputStream +import java.lang.ref.WeakReference + +class FileUtils { + + /** + * Task that copies a file from the assets directory to a provided directory. + * The asset's name is going to be kept in the new directory. + */ + class CopyFileFromAssetsTask(context: Context, listener: OnFileCopiedFromAssetsListener) : AsyncTask() { + private val contextWeakReference: WeakReference = WeakReference(context) + private val listenerWeakReference: WeakReference = WeakReference(listener) + + override fun doInBackground(vararg strings: String): Boolean? { + val assetName = strings[0] + val destinationPath = strings[1] + + contextWeakReference.get()?.let { + try { + copyAsset(it, assetName, destinationPath) + } catch (ex: Exception) { + return false + } + } + + return true + } + + override fun onCancelled() { + listenerWeakReference.get()?.onError() + } + + override fun onPostExecute(result: Boolean) { + if (result) { + listenerWeakReference.get()?.onFileCopiedFromAssets() + } else { + listenerWeakReference.get()?.onError() + } + } + + private fun copyAsset(context: Context, assetName: String, destinationPath: String) { + val bufferSize = 1024 + val assetManager = context.assets + val inputStream = assetManager.open(assetName) + val outputStream = FileOutputStream(File(destinationPath, assetName)) + try { + inputStream.copyTo(outputStream, bufferSize) + } finally { + inputStream.close() + outputStream.flush() + outputStream.close() + } + } + } + + interface OnFileCopiedFromAssetsListener { + fun onFileCopiedFromAssets() + fun onError() + } +} \ No newline at end of file