Skip to content

Commit

Permalink
542 write external storage deprecated (#543)
Browse files Browse the repository at this point in the history
* Remove permission request for caching map tiles for Android 13 and higher.
Remove @RequiresApi = M as minSDK is now 23 (=M).

* Remove permission request for storage on Android 13 when taking photo as this can be handled by the camera app.
Change READ_EXTERNAL_STORAGE to READ_MEDIA_IMAGE for Android 13 upwards.
  • Loading branch information
HilaryN authored Jan 31, 2024
1 parent 2a628f1 commit 957844c
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 24 deletions.
2 changes: 2 additions & 0 deletions cyclestreets.app/src/main/play/release-notes/en-GB/beta.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- If there are queued voice instructions, these are replaced with the latest instruction.
- Update permissions for Android 13 so map tiles can be cached and photos added.
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,31 @@ package net.cyclestreets

import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.preference.PreferenceManager
import android.util.Log
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.preference.PreferenceManager
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial

import net.cyclestreets.fragments.R
import net.cyclestreets.iconics.IconicsHelper
import net.cyclestreets.util.*
import net.cyclestreets.util.AsyncDelete
import net.cyclestreets.util.Logging
import net.cyclestreets.util.MenuHelper.createMenuItem
import net.cyclestreets.util.MenuHelper.enableMenuItem
import net.cyclestreets.util.Theme
import net.cyclestreets.util.doOrRequestPermission
import net.cyclestreets.util.requestPermissionsResultAction
import net.cyclestreets.views.CycleMapView

import org.osmdroid.config.Configuration
import org.osmdroid.config.DefaultConfigurationProvider
import org.osmdroid.views.overlay.Overlay

import java.io.File
import java.util.Date

Expand All @@ -43,7 +45,8 @@ open class CycleMapFragment : Fragment(), Undoable {

forceMenuRebuild = true

checkPermissionNoMoreThanOnceEveryFiveMinutes()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
checkPermissionNoMoreThanOnceEveryFiveMinutes()

map = CycleMapView(context, this.javaClass.name, this)
searchIcon = IconicsHelper.materialIcon(requireContext(), GoogleMaterial.Icon.gmd_search, Theme.lowlightColorInverse(context))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package net.cyclestreets.addphoto

import android.Manifest.permission.*
import android.Manifest.permission.ACCESS_FINE_LOCATION
import android.Manifest.permission.READ_EXTERNAL_STORAGE
import android.Manifest.permission.READ_MEDIA_IMAGES
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.app.Activity
import android.content.Context
import android.content.Intent
Expand All @@ -9,13 +12,26 @@ import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Point
import android.os.AsyncTask
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.view.*
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.inputmethod.InputMethodManager
import android.widget.*
import android.widget.Button
import android.widget.EditText
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.Spinner
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.FileProvider
import androidx.exifinterface.media.ExifInterface
import androidx.fragment.app.Fragment
Expand All @@ -27,15 +43,24 @@ import net.cyclestreets.api.PhotomapCategories
import net.cyclestreets.api.Upload
import net.cyclestreets.fragments.R
import net.cyclestreets.iconics.IconicsHelper.materialIcons
import net.cyclestreets.util.*
import net.cyclestreets.util.AsyncDelete
import net.cyclestreets.util.Bitmaps
import net.cyclestreets.util.Dialog
import net.cyclestreets.util.Logging
import net.cyclestreets.util.MenuHelper.createMenuItem
import net.cyclestreets.util.MenuHelper.enableMenuItem
import net.cyclestreets.util.MessageBox
import net.cyclestreets.util.ProgressDialog
import net.cyclestreets.util.Share
import net.cyclestreets.util.doOrRequestPermission
import net.cyclestreets.util.hasPermission
import net.cyclestreets.util.requestPermissionsResultAction
import net.cyclestreets.views.CycleMapView
import net.cyclestreets.views.overlay.ThereOverlay
import org.osmdroid.api.IGeoPoint
import org.osmdroid.util.GeoPoint
import java.io.File
import java.util.*
import java.util.Date


internal val TAG = Logging.getTag(AddPhotoFragment::class.java)
Expand Down Expand Up @@ -461,15 +486,24 @@ class AddPhotoFragment : Fragment(), View.OnClickListener, Undoable, ThereOverla
override fun onClick(v: View) {
when (v.id) {
R.id.takephoto_button -> doOrLogin {
doOrRequestPermission(null, this, WRITE_EXTERNAL_STORAGE) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
doOrRequestPermission(null, this, WRITE_EXTERNAL_STORAGE) {
dispatchTakePhotoIntent()
}
else
dispatchTakePhotoIntent()
}
}
R.id.chooseexisting_button -> doOrLogin {
doOrRequestPermission(null, this, READ_EXTERNAL_STORAGE) {
startActivityForResult(Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI),
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
doOrRequestPermission(null, this, READ_EXTERNAL_STORAGE) {
startActivityForResult(Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI),
CHOOSE_PHOTO)
}
else
doOrRequestPermission(null, this, READ_MEDIA_IMAGES) {
startActivityForResult(Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI),
CHOOSE_PHOTO)
}
}
R.id.textonly_button -> doOrLogin {
photo = null
Expand Down Expand Up @@ -516,6 +550,7 @@ class AddPhotoFragment : Fragment(), View.OnClickListener, Undoable, ThereOverla
/* startActivityForResult(Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI),
CHOOSE_PHOTO) */
}
READ_MEDIA_IMAGES -> requestPermissionsResultAction(grantResult, permission){}
WRITE_EXTERNAL_STORAGE -> requestPermissionsResultAction(grantResult, permission) {
// As above
//dispatchTakePhotoIntent()
Expand Down
1 change: 1 addition & 0 deletions libraries/cyclestreets-view/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.PackageManager.PERMISSION_DENIED
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.net.Uri
import android.os.Build
import android.provider.Settings
import android.util.Log
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat.startActivity
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import net.cyclestreets.CycleStreetsPreferences.*
import net.cyclestreets.GENERIC_PERMISSION_REQUEST
Expand All @@ -27,7 +25,7 @@ private val TAG = Logging.getTag(Permissions::class.java)
// Check for permissions
fun hasPermission(context: Context?, permission: String): Boolean {
return if (context != null)
context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED
ContextCompat.checkSelfPermission(context, permission) == PERMISSION_GRANTED
else false
}

Expand Down Expand Up @@ -153,7 +151,6 @@ fun requestPermissionsResultAction(grantResult: Int?, permission: String, action
}

// Go to settings - if dynamic permission requesting is no long an option
@RequiresApi(api = Build.VERSION_CODES.M)
private fun goToSettings(context: Context) {
Log.d(TAG, "Opening Settings screen to allow user to update permissions")
val androidAppSettingsIntent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:net.cyclestreets"))
Expand All @@ -172,6 +169,7 @@ private fun justification(context: Context, permission: String, justificationFor
private object Permissions {
val justifications: Map<String, Int> = hashMapOf(
Manifest.permission.READ_EXTERNAL_STORAGE to R.string.perm_justification_read_external_storage,
Manifest.permission.READ_MEDIA_IMAGES to R.string.perm_justification_read_media_images,
Manifest.permission.WRITE_EXTERNAL_STORAGE to R.string.perm_justification_write_external_storage,
Manifest.permission.ACCESS_FINE_LOCATION to R.string.perm_justification_access_fine_location,
Manifest.permission.READ_CONTACTS to R.string.perm_justification_read_contacts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import android.content.SharedPreferences;
import android.graphics.Canvas;
import android.location.Location;
import android.os.Build;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.ContextMenu;
Expand Down Expand Up @@ -72,10 +73,12 @@ public CycleMapView(final Context context, final String name, final Fragment fra

// Make sure we can save map tiles, regardless of whether we have the write-external permission granted.
boolean hasWritePermission = PermissionsKt.hasPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
// WRITE_EXTERNAL_STORAGE deprecated in Android 13. Permission not req'd for app-specific storage
boolean android13Plus = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU;
Configuration.getInstance().load(context, PreferenceManager.getDefaultSharedPreferences(context));
Log.i(TAG, "Creating map view. App has write-external permission? " + hasWritePermission +
"; osmdroid base path: " + Configuration.getInstance().getOsmdroidBasePath().getAbsolutePath() +
"; osmdroid tile cache location: " + Configuration.getInstance().getOsmdroidTileCache().getAbsolutePath());
Log.i(TAG, String.format("Creating map view" + (android13Plus ?";":". App has write-external permission? " + hasWritePermission + ";") +
" osmdroid base path: " + Configuration.getInstance().getOsmdroidBasePath().getAbsolutePath() +
"; osmdroid tile cache location: " + Configuration.getInstance().getOsmdroidTileCache().getAbsolutePath()));

mapView_ = new MapView(context, TileSource.mapTileProvider(context));
addView(mapView_);
Expand Down
5 changes: 5 additions & 0 deletions libraries/cyclestreets-view/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@
<li>&nbsp; allow you to select photographs from your image library for use in the Add Photo feature.</li>
</ul>
]]></string>
<string name="perm_justification_read_media_images" translatable="false"><![CDATA[
<ul>
<li>&nbsp; allow you to select photographs from your image library for use in the Add Photo feature.</li>
</ul>
]]></string>
<string name="perm_justification_write_external_storage" translatable="false"><![CDATA[
<ul>
<li>&nbsp; cache downloaded map tiles <b>(without this the app will function poorly and consume much more data)</b></li>
Expand Down

0 comments on commit 957844c

Please sign in to comment.