mirror of
https://github.com/videolan/vlc-android
synced 2024-12-04 15:23:51 +08:00
Display fine permission explanation in empty views
This commit is contained in:
parent
61eeb101c2
commit
7d9760aab6
@ -839,6 +839,8 @@
|
||||
<string name="welcome_title">Welcome to VLC!</string>
|
||||
<string name="welcome_subtitle">The free and open source multimedia player</string>
|
||||
<string name="permission_media">VLC needs your permission to access media on your device</string>
|
||||
<string name="permission_video">VLC needs your permission to access video media on your device</string>
|
||||
<string name="permission_audio">VLC needs your permission to access audio media on your device</string>
|
||||
<string name="medialibrary_scan_explanation">VLC can automatically scan your device to organize your media collection.</string>
|
||||
<string name="onboarding_theme_title">Make yourself at home</string>
|
||||
<string name="done">Done</string>
|
||||
|
@ -61,31 +61,28 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/changelog" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/remote_access_hash_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:text="@string/remote_access_hash_title"
|
||||
android:textColor="?attr/font_light"
|
||||
android:maxWidth="150dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/remote_access_revision"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/remote_access_version" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/remote_access"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/remote_access_version_title"
|
||||
android:textColor="?attr/font_light"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/remote_access_version"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/divider2" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/remote_access_hash_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:text="@string/remote_access_hash_title"
|
||||
android:textColor="?attr/font_light"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/compilation_barrier"
|
||||
app:layout_constraintHorizontal_bias="1.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/remote_access" />
|
||||
app:layout_constraintTop_toTopOf="@+id/remote_access_version" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView28"
|
||||
@ -281,7 +278,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="end"
|
||||
app:constraint_referenced_ids="remote_access,textView28,textView30,textView29" />
|
||||
app:constraint_referenced_ids="remote_access_hash_title,remote_access,textView28,textView30,textView29" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
@ -25,6 +25,7 @@ import android.annotation.TargetApi
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
@ -162,6 +163,19 @@ class MainActivity : ContentActivity(),
|
||||
configurationChanged(getScreenWidth())
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<String?>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
if (requestCode == 1000) {
|
||||
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
forceRefresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun prepareActionBar() {
|
||||
toolbarIcon = findViewById(R.id.toolbar_icon)
|
||||
|
@ -46,6 +46,7 @@ import kotlinx.coroutines.launch
|
||||
import org.videolan.medialibrary.interfaces.Medialibrary
|
||||
import org.videolan.medialibrary.interfaces.media.MediaWrapper
|
||||
import org.videolan.medialibrary.media.MediaLibraryItem
|
||||
import org.videolan.resources.AppContextProvider
|
||||
import org.videolan.resources.KEY_AUDIO_CURRENT_TAB
|
||||
import org.videolan.resources.KEY_AUDIO_LAST_PLAYLIST
|
||||
import org.videolan.resources.util.waitForML
|
||||
@ -359,6 +360,7 @@ class AudioBrowserFragment : BaseAudioBrowser<AudioBrowserViewModel>() {
|
||||
binding.audioEmptyLoading.emptyText = viewModel.filterQuery?.let { getString(R.string.empty_search, it) } ?: if (viewModel.providers[currentTab].onlyFavorites) getString(R.string.nofav) else getString(R.string.nomedia)
|
||||
binding.audioEmptyLoading.state = when {
|
||||
!Permissions.canReadStorage(requireActivity()) && empty -> EmptyLoadingState.MISSING_PERMISSION
|
||||
!Permissions.canReadAudios(AppContextProvider.appContext) && empty -> EmptyLoadingState.MISSING_AUDIO_PERMISSION
|
||||
viewModel.providers[currentTab].loading.value == true && empty -> EmptyLoadingState.LOADING
|
||||
emptyAt(currentTab) && viewModel.filterQuery?.isNotEmpty() == true -> EmptyLoadingState.EMPTY_SEARCH
|
||||
emptyAt(currentTab) && viewModel.providers[currentTab].onlyFavorites -> EmptyLoadingState.EMPTY_FAVORITES
|
||||
|
@ -349,6 +349,7 @@ class VideoGridFragment : MediaBrowserFragment<VideosViewModel>(), SwipeRefreshL
|
||||
binding.emptyLoading.emptyText = viewModel.filterQuery?.let { getString(R.string.empty_search, it) } ?: if (viewModel.provider.onlyFavorites) getString(R.string.nofav) else getString(R.string.nomedia)
|
||||
binding.emptyLoading.state = when {
|
||||
!Permissions.canReadStorage(AppContextProvider.appContext) && empty -> EmptyLoadingState.MISSING_PERMISSION
|
||||
!Permissions.canReadVideos(AppContextProvider.appContext) && empty -> EmptyLoadingState.MISSING_VIDEO_PERMISSION
|
||||
empty && working -> EmptyLoadingState.LOADING
|
||||
empty && !working && viewModel.provider.onlyFavorites -> EmptyLoadingState.EMPTY_FAVORITES
|
||||
empty && !working && viewModel.filterQuery == null -> EmptyLoadingState.EMPTY
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
package org.videolan.vlc.gui.view
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
@ -38,14 +39,18 @@ import android.view.View
|
||||
import android.widget.*
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.constraintlayout.widget.ConstraintSet
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.transition.TransitionManager
|
||||
import kotlinx.coroutines.launch
|
||||
import org.videolan.resources.ACTIVITY_RESULT_PREFERENCES
|
||||
import org.videolan.tools.AppScope
|
||||
import org.videolan.vlc.R
|
||||
import org.videolan.vlc.gui.BaseActivity
|
||||
import org.videolan.vlc.gui.SecondaryActivity
|
||||
import org.videolan.vlc.gui.helpers.getBitmapFromDrawable
|
||||
import org.videolan.vlc.gui.helpers.hf.StoragePermissionsDelegate.Companion.askStoragePermission
|
||||
import org.videolan.vlc.gui.helpers.hf.StoragePermissionsDelegate.Companion.getStoragePermission
|
||||
|
||||
class EmptyLoadingStateView : FrameLayout {
|
||||
|
||||
@ -74,13 +79,23 @@ class EmptyLoadingStateView : FrameLayout {
|
||||
loadingFlipper.visibility = if (value == EmptyLoadingState.LOADING) View.VISIBLE else View.GONE
|
||||
loadingTitle.visibility = if (value == EmptyLoadingState.LOADING) View.VISIBLE else View.GONE
|
||||
emptyTextView.visibility = if (value in arrayOf(EmptyLoadingState.EMPTY, EmptyLoadingState.EMPTY_SEARCH, EmptyLoadingState.EMPTY_FAVORITES)) View.VISIBLE else View.GONE
|
||||
emptyImageView.visibility = if (value in arrayOf(EmptyLoadingState.EMPTY,EmptyLoadingState.MISSING_PERMISSION, EmptyLoadingState.EMPTY_SEARCH, EmptyLoadingState.EMPTY_FAVORITES)) View.VISIBLE else View.GONE
|
||||
emptyImageView.visibility = if (value in arrayOf(EmptyLoadingState.EMPTY,EmptyLoadingState.MISSING_PERMISSION,EmptyLoadingState.MISSING_VIDEO_PERMISSION, EmptyLoadingState.MISSING_AUDIO_PERMISSION, EmptyLoadingState.EMPTY_SEARCH, EmptyLoadingState.EMPTY_FAVORITES)) View.VISIBLE else View.GONE
|
||||
emptyImageView.setImageBitmap(context.getBitmapFromDrawable(if (value == EmptyLoadingState.EMPTY_FAVORITES) R.drawable.ic_fav_empty else if (value in arrayOf(EmptyLoadingState.EMPTY, EmptyLoadingState.EMPTY_SEARCH, EmptyLoadingState.EMPTY_FAVORITES)) R.drawable.ic_empty else R.drawable.ic_empty_warning))
|
||||
permissionTitle.visibility = if (value == EmptyLoadingState.MISSING_PERMISSION) View.VISIBLE else View.GONE
|
||||
permissionTextView.visibility = if (value == EmptyLoadingState.MISSING_PERMISSION) View.VISIBLE else View.GONE
|
||||
grantPermissionButton.visibility = if (value == EmptyLoadingState.MISSING_PERMISSION) View.VISIBLE else View.GONE
|
||||
pickFileButton.visibility = if (value == EmptyLoadingState.MISSING_PERMISSION && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) View.VISIBLE else View.GONE
|
||||
permissionTitle.visibility = if (value in arrayOf(EmptyLoadingState.MISSING_PERMISSION, EmptyLoadingState.MISSING_VIDEO_PERMISSION, EmptyLoadingState.MISSING_AUDIO_PERMISSION)) View.VISIBLE else View.GONE
|
||||
permissionTextView.visibility = if (value in arrayOf(EmptyLoadingState.MISSING_PERMISSION, EmptyLoadingState.MISSING_VIDEO_PERMISSION, EmptyLoadingState.MISSING_AUDIO_PERMISSION)) View.VISIBLE else View.GONE
|
||||
grantPermissionButton.visibility = if (value in arrayOf(EmptyLoadingState.MISSING_PERMISSION, EmptyLoadingState.MISSING_VIDEO_PERMISSION, EmptyLoadingState.MISSING_AUDIO_PERMISSION)) View.VISIBLE else View.GONE
|
||||
pickFileButton.visibility = if (value in arrayOf(EmptyLoadingState.MISSING_PERMISSION, EmptyLoadingState.MISSING_VIDEO_PERMISSION, EmptyLoadingState.MISSING_AUDIO_PERMISSION) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) View.VISIBLE else View.GONE
|
||||
noMediaButton.visibility = if (showNoMedia && value == EmptyLoadingState.EMPTY) View.VISIBLE else if (value == EmptyLoadingState.EMPTY_FAVORITES) View.INVISIBLE else View.GONE
|
||||
permissionTextView.text = when (state) {
|
||||
EmptyLoadingState.MISSING_VIDEO_PERMISSION -> context.getString(R.string.permission_video)
|
||||
EmptyLoadingState.MISSING_AUDIO_PERMISSION -> context.getString(R.string.permission_audio)
|
||||
else ->
|
||||
buildString {
|
||||
append(context.getString(R.string.permission_expanation_no_allow))
|
||||
append("\n\n")
|
||||
append(context.getString(R.string.permission_expanation_allow))
|
||||
}
|
||||
}
|
||||
field = value
|
||||
}
|
||||
|
||||
@ -139,15 +154,29 @@ class EmptyLoadingStateView : FrameLayout {
|
||||
noMediaClickListener?.invoke()
|
||||
}
|
||||
grantPermissionButton.setOnClickListener {
|
||||
(context as? FragmentActivity)?.askStoragePermission(false, null)
|
||||
when (state) {
|
||||
EmptyLoadingState.MISSING_AUDIO_PERMISSION -> ActivityCompat.requestPermissions(
|
||||
context as Activity, arrayOf(
|
||||
Manifest.permission.READ_MEDIA_AUDIO
|
||||
), 1000
|
||||
)
|
||||
|
||||
EmptyLoadingState.MISSING_VIDEO_PERMISSION -> ActivityCompat.requestPermissions(
|
||||
context as Activity, arrayOf(
|
||||
Manifest.permission.READ_MEDIA_VIDEO,
|
||||
Manifest.permission.READ_MEDIA_IMAGES
|
||||
), 1000
|
||||
)
|
||||
|
||||
else -> (context as? FragmentActivity)?.askStoragePermission(false, null)
|
||||
|
||||
}
|
||||
}
|
||||
pickFileButton.setOnClickListener {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
(context as BaseActivity).openFile(Uri.parse(""))
|
||||
}
|
||||
}
|
||||
|
||||
permissionTextView.text = "${context.getString(R.string.permission_expanation_no_allow)}\n\n${context.getString(R.string.permission_expanation_allow)}"
|
||||
}
|
||||
|
||||
private fun applyCompactMode() {
|
||||
@ -172,5 +201,5 @@ class EmptyLoadingStateView : FrameLayout {
|
||||
}
|
||||
|
||||
enum class EmptyLoadingState {
|
||||
LOADING, EMPTY, EMPTY_SEARCH, NONE, MISSING_PERMISSION, EMPTY_FAVORITES
|
||||
LOADING, EMPTY, EMPTY_SEARCH, NONE, MISSING_PERMISSION, MISSING_VIDEO_PERMISSION, MISSING_AUDIO_PERMISSION, EMPTY_FAVORITES
|
||||
}
|
@ -108,6 +108,23 @@ object Permissions {
|
||||
) == PackageManager.PERMISSION_GRANTED || isExternalStorageManager()
|
||||
}
|
||||
|
||||
fun canReadVideos(context: Context): Boolean {
|
||||
return Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || isExternalStorageManager() ||
|
||||
ContextCompat.checkSelfPermission(
|
||||
context,
|
||||
Manifest.permission.READ_MEDIA_VIDEO
|
||||
) == PackageManager.PERMISSION_GRANTED
|
||||
|
||||
}
|
||||
fun canReadAudios(context: Context): Boolean {
|
||||
return Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || isExternalStorageManager() ||
|
||||
ContextCompat.checkSelfPermission(
|
||||
context,
|
||||
Manifest.permission.READ_MEDIA_AUDIO
|
||||
) == PackageManager.PERMISSION_GRANTED
|
||||
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
||||
private fun isAnyFileFinePermissionGranted(context: Context) = (
|
||||
ContextCompat.checkSelfPermission(
|
||||
|
Loading…
Reference in New Issue
Block a user