diff --git a/app/build.gradle b/app/build.gradle index e5b802d48..784e54418 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,13 +3,13 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { - compileSdkVersion 25 - buildToolsVersion "25.0.3" + compileSdkVersion 26 + buildToolsVersion "26.0.2" defaultConfig { applicationId "com.simplemobiletools.gallery" minSdkVersion 16 - targetSdkVersion 23 + targetSdkVersion 26 versionCode 137 versionName "2.16.1" } @@ -37,7 +37,7 @@ android { } dependencies { - compile 'com.simplemobiletools:commons:2.32.0' + compile 'com.simplemobiletools:commons:2.32.4' compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.6.0' compile 'com.theartofdev.edmodo:android-image-cropper:2.4.0' compile 'com.bignerdranch.android:recyclerview-multiselect:0.2' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index fb8ba91aa..ff7ff3399 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -83,16 +83,16 @@ android:label="@string/third_party_licences" android:parentActivityName="com.simplemobiletools.commons.activities.AboutActivity"/> - - + + @@ -137,10 +121,10 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList return true when (item.itemId) { - R.id.menu_set_as -> trySetAs(File(mMedium!!.path)) - R.id.menu_open_with -> openWith(File(mMedium!!.path)) - R.id.menu_share -> shareUri(mMedium!!, mUri) - R.id.menu_edit -> openFileEditor(File(mMedium!!.path)) + R.id.menu_set_as -> setAs(mUri) + R.id.menu_open_with -> openFile(mUri) + R.id.menu_share -> shareUri(mUri) + R.id.menu_edit -> openEditor(mUri) else -> return super.onOptionsItemSelected(item) } return true diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/VideoActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/VideoActivity.kt index fa38734e3..7ca92e902 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/VideoActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/VideoActivity.kt @@ -5,7 +5,7 @@ import android.os.Bundle class VideoActivity : PhotoVideoActivity() { override fun onCreate(savedInstanceState: Bundle?) { - PhotoVideoActivity.mIsVideo = true + mIsVideo = true super.onCreate(savedInstanceState) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt index c56d37d31..5db29688f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt @@ -246,18 +246,18 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View return true when (item.itemId) { - R.id.menu_set_as -> trySetAs(getCurrentFile()) + R.id.menu_set_as -> setAs(Uri.fromFile(getCurrentFile())) R.id.slideshow -> initSlideshow() R.id.menu_copy_to -> copyMoveTo(true) R.id.menu_move_to -> copyMoveTo(false) - R.id.menu_open_with -> openWith(getCurrentFile()) + R.id.menu_open_with -> openFile(Uri.fromFile(getCurrentFile())) R.id.menu_hide -> toggleFileVisibility(true) R.id.menu_unhide -> toggleFileVisibility(false) R.id.menu_share_1 -> shareMedium(getCurrentMedium()!!) R.id.menu_share_2 -> shareMedium(getCurrentMedium()!!) R.id.menu_delete -> checkDeleteConfirmation() R.id.menu_rename -> renameFile() - R.id.menu_edit -> openFileEditor(getCurrentFile()) + R.id.menu_edit -> openEditor(Uri.fromFile(getCurrentFile())) R.id.menu_properties -> showProperties() R.id.show_on_map -> showOnMap() R.id.menu_rotate -> rotateImage() diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt index d1918aaad..1be8d7856 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt @@ -1,6 +1,7 @@ package com.simplemobiletools.gallery.adapters import android.graphics.PorterDuff +import android.net.Uri import android.os.Build import android.support.v7.view.ActionMode import android.support.v7.widget.RecyclerView @@ -159,7 +160,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList, } private fun editFile() { - activity.openFileEditor(getCurrentFile()) + activity.openEditor(Uri.fromFile(getCurrentFile())) actMode?.finish() } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/activity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/activity.kt index 4fe4d6180..32cd94836 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/activity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/activity.kt @@ -2,16 +2,10 @@ package com.simplemobiletools.gallery.extensions import android.app.Activity import android.content.Intent -import android.database.Cursor import android.net.Uri -import android.os.Build import android.provider.MediaStore import android.support.v7.app.AppCompatActivity -import android.util.DisplayMetrics -import android.view.KeyCharacterMap -import android.view.KeyEvent import android.view.View -import android.view.ViewConfiguration import com.bumptech.glide.Glide import com.bumptech.glide.load.DecodeFormat import com.bumptech.glide.load.engine.DiskCacheStrategy @@ -34,12 +28,12 @@ import com.simplemobiletools.gallery.views.MySquareImageView import java.io.File import java.util.* -fun Activity.shareUri(medium: Medium, uri: Uri) { +fun Activity.shareUri(uri: Uri) { val shareTitle = resources.getString(R.string.share_via) Intent().apply { action = Intent.ACTION_SEND - putExtra(Intent.EXTRA_STREAM, uri) - type = medium.getMimeType() + putExtra(Intent.EXTRA_STREAM, ensurePublicUri(uri)) + type = getMimeTypeFromUri(uri) addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) startActivity(Intent.createChooser(this, shareTitle)) } @@ -48,12 +42,12 @@ fun Activity.shareUri(medium: Medium, uri: Uri) { fun Activity.shareMedium(medium: Medium) { val shareTitle = resources.getString(R.string.share_via) val file = File(medium.path) - val uri = Uri.fromFile(file) + val uri = getFilePublicUri(file, BuildConfig.APPLICATION_ID) Intent().apply { action = Intent.ACTION_SEND putExtra(Intent.EXTRA_STREAM, uri) - type = medium.getMimeType() + type = getMimeTypeFromUri(uri) addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) startActivity(Intent.createChooser(this, shareTitle)) } @@ -61,7 +55,7 @@ fun Activity.shareMedium(medium: Medium) { fun Activity.shareMedia(media: List) { val shareTitle = resources.getString(R.string.share_via) - val uris = media.map { Uri.fromFile(File(it.path)) } as ArrayList + val uris = media.map { getFilePublicUri(File(it.path), BuildConfig.APPLICATION_ID) } as ArrayList Intent().apply { action = Intent.ACTION_SEND_MULTIPLE @@ -72,119 +66,55 @@ fun Activity.shareMedia(media: List) { } } -fun Activity.trySetAs(file: File) { - try { - var uri = Uri.fromFile(file) - if (!setAs(uri, file)) { - uri = getFileContentUri(file) - setAs(uri, file, false) - } - } catch (e: Exception) { - toast(R.string.unknown_error_occurred) - } -} - -fun Activity.setAs(uri: Uri, file: File, showToast: Boolean = true): Boolean { - var success = false +fun Activity.setAs(uri: Uri) { + val newUri = ensurePublicUri(uri) Intent().apply { action = Intent.ACTION_ATTACH_DATA - setDataAndType(uri, file.getMimeType()) + setDataAndType(newUri, getMimeTypeFromUri(newUri)) addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) val chooser = Intent.createChooser(this, getString(R.string.set_as)) - success = if (resolveActivity(packageManager) != null) { + if (resolveActivity(packageManager) != null) { startActivityForResult(chooser, REQUEST_SET_AS) - true } else { - if (showToast) { - toast(R.string.no_capable_app_found) - } - false + toast(R.string.no_capable_app_found) } } - - return success } -fun Activity.getFileContentUri(file: File): Uri? { - val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI - val projection = arrayOf(MediaStore.Images.Media._ID) - val selection = "${MediaStore.Images.Media.DATA} = ?" - val selectionArgs = arrayOf(file.absolutePath) - - var cursor: Cursor? = null - try { - cursor = contentResolver.query(uri, projection, selection, selectionArgs, null) - if (cursor?.moveToFirst() == true) { - val id = cursor.getIntValue(MediaStore.Images.Media._ID) - return Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "$id") - } - } finally { - cursor?.close() - } - return null -} - -fun Activity.openWith(file: File, forceChooser: Boolean = true) { - val uri = Uri.fromFile(file) +fun Activity.openFile(uri: Uri) { + val newUri = ensurePublicUri(uri) Intent().apply { action = Intent.ACTION_VIEW - setDataAndType(uri, file.getMimeType()) + setDataAndType(newUri, getMimeTypeFromUri(newUri)) addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) putExtra(IS_FROM_GALLERY, true) if (resolveActivity(packageManager) != null) { val chooser = Intent.createChooser(this, getString(R.string.open_with)) - startActivity(if (forceChooser) chooser else this) + startActivity(chooser) } else { toast(R.string.no_app_found) } } } -fun Activity.openFileEditor(file: File) { - openEditor(Uri.fromFile(file)) -} - -fun Activity.openEditor(uri: Uri, forceChooser: Boolean = false) { +fun Activity.openEditor(uri: Uri) { + val newUri = ensurePublicUri(uri) Intent().apply { action = Intent.ACTION_EDIT - setDataAndType(uri, "image/*") + setDataAndType(newUri, getMimeTypeFromUri(newUri)) addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) if (resolveActivity(packageManager) != null) { val chooser = Intent.createChooser(this, getString(R.string.edit_image_with)) - startActivityForResult(if (forceChooser) chooser else this, REQUEST_EDIT_IMAGE) + startActivityForResult(chooser, REQUEST_EDIT_IMAGE) } else { toast(R.string.no_editor_found) } } } -fun Activity.hasNavBar(): Boolean { - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - val display = windowManager.defaultDisplay - - val realDisplayMetrics = DisplayMetrics() - display.getRealMetrics(realDisplayMetrics) - - val realHeight = realDisplayMetrics.heightPixels - val realWidth = realDisplayMetrics.widthPixels - - val displayMetrics = DisplayMetrics() - display.getMetrics(displayMetrics) - - val displayHeight = displayMetrics.heightPixels - val displayWidth = displayMetrics.widthPixels - - realWidth - displayWidth > 0 || realHeight - displayHeight > 0 - } else { - val hasMenuKey = ViewConfiguration.get(applicationContext).hasPermanentMenuKey() - val hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK) - !hasMenuKey && !hasBackKey - } -} - fun Activity.launchCamera() { val intent = Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA) if (intent.resolveActivity(packageManager) != null) { diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt index cdda71ab7..82c101a89 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt @@ -5,12 +5,18 @@ import android.content.Intent import android.content.res.Configuration import android.graphics.Point import android.media.AudioManager +import android.net.Uri import android.os.Build import android.view.WindowManager +import com.simplemobiletools.commons.extensions.getFilePublicUri +import com.simplemobiletools.commons.extensions.getMimeTypeFromPath +import com.simplemobiletools.commons.extensions.getRealPathFromURI import com.simplemobiletools.commons.extensions.humanizePath +import com.simplemobiletools.gallery.BuildConfig import com.simplemobiletools.gallery.activities.SettingsActivity import com.simplemobiletools.gallery.helpers.Config import com.simplemobiletools.gallery.models.Directory +import java.io.File val Context.portrait get() = resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT val Context.audioManager get() = getSystemService(Context.AUDIO_SERVICE) as AudioManager @@ -73,3 +79,21 @@ fun Context.getSortedDirectories(source: ArrayList): ArrayList= Build.VERSION_CODES.JELLY_BEAN_MR1) { + val display = context.windowManager.defaultDisplay + + val realDisplayMetrics = DisplayMetrics() + display.getRealMetrics(realDisplayMetrics) + + val realHeight = realDisplayMetrics.heightPixels + val realWidth = realDisplayMetrics.widthPixels + + val displayMetrics = DisplayMetrics() + display.getMetrics(displayMetrics) + + val displayHeight = displayMetrics.heightPixels + val displayWidth = displayMetrics.widthPixels + + realWidth - displayWidth > 0 || realHeight - displayHeight > 0 + } else { + val hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey() + val hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK) + !hasMenuKey && !hasBackKey + } + } + private fun setupTimeHolder() { mSeekBar!!.max = mDuration mView.video_duration.text = mDuration.getFormattedDuration()