Skip to content

Commit

Permalink
v1.0.0(24) Android 13 OS support (#78)
Browse files Browse the repository at this point in the history
- Segregated mutable list for photo and video permission
- Removed unnecessary storage permission while requesting for a camera permission
- Added two buttons to capture a snapshot and record a video
- UI and Code improvement

Co-authored-by: AKASH PATEL <akash.patel@mindinventory.com>
Co-authored-by: vrajendraBhavsar <84775226+vrajendraBhavsar@users.noreply.github.com>
  • Loading branch information
3 people authored Nov 10, 2022
1 parent 1d6c791 commit 200db7f
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 43 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Lassi is simplest way to pick media (either image, video, audio or doc)

### Key features

* Android 12 support
* Android 13 support
* Simple implementation
* Set your own custom styles
* Filter by particular media type
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ apply plugin: 'kotlin-kapt'


android {
compileSdkVersion 32
compileSdkVersion 33
defaultConfig {
applicationId "com.lassi.app"
minSdkVersion 19
targetSdkVersion 32
targetSdkVersion 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Expand Down
60 changes: 60 additions & 0 deletions app/src/main/java/com/lassi/app/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
btnVideoPicker.setOnClickListener(this)
btnAudioPicker.setOnClickListener(this)
btnDocPicker.setOnClickListener(this)
btnImageCapture.setOnClickListener(this)
btnVideoCapture.setOnClickListener(this)
btnDocumentSystemIntent.setOnClickListener(this)
rvSelectedMedia.adapter = selectedMediaAdapter
rvSelectedMedia.addItemDecoration(GridSpacingItemDecoration(2, 10))
Expand Down Expand Up @@ -142,6 +144,64 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
.build()
receiveData.launch(intent)
}

R.id.btnImageCapture -> {
val intent = Lassi(this)
.with(LassiOption.CAMERA)
.setMaxCount(4)
.setGridSize(2)
.setPlaceHolder(R.drawable.ic_image_placeholder)
.setErrorDrawable(R.drawable.ic_image_placeholder)
.setSelectionDrawable(R.drawable.ic_checked_media)
.setStatusBarColor(R.color.colorPrimaryDark)
.setToolbarColor(R.color.colorPrimary)
.setToolbarResourceColor(android.R.color.white)
.setProgressBarColor(R.color.colorAccent)
.setGalleryBackgroundColor(R.color.colorGrey)
.setMediaType(MediaType.IMAGE)
.setCropType(CropImageView.CropShape.OVAL)
.setCropAspectRatio(1, 1)
.setCompressionRation(0)
.setMinFileSize(0)
.setMaxFileSize(10000)
.enableActualCircleCrop()
.setSupportedFileTypes("jpg", "jpeg", "png", "webp", "gif")
.enableFlip()
.enableRotate()
.build()
receiveData.launch(intent)
}

R.id.btnVideoCapture -> {
val intent = Lassi(this)
.with(LassiOption.CAMERA)
.setMaxCount(1)
.setGridSize(3)
.setMinTime(5)
.setMaxTime(30)
.setMinFileSize(0)
.setMaxFileSize(2000)
.setPlaceHolder(R.drawable.ic_image_placeholder)
.setErrorDrawable(R.drawable.ic_image_placeholder)
.setSelectionDrawable(R.drawable.ic_checked_media)
.setStatusBarColor(R.color.colorPrimaryDark)
.setToolbarColor(R.color.colorPrimary)
.setMediaType(MediaType.VIDEO)
.setToolbarResourceColor(android.R.color.white)
.setProgressBarColor(R.color.colorAccent)
.setGalleryBackgroundColor(R.color.colorGrey)
.setCropType(CropImageView.CropShape.OVAL)
.setCropAspectRatio(1, 1)
.setCompressionRation(0)
.setMinFileSize(0)
.setMaxFileSize(10000)
.enableActualCircleCrop()
.setSupportedFileTypes("jpg", "jpeg", "png", "webp", "gif")
.enableFlip()
.enableRotate()
.build()
receiveData.launch(intent)
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/ic_video_cam_white.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M17,10.5V7c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4z"/>
</vector>
60 changes: 53 additions & 7 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@

<Button
android:id="@+id/btnImagePicker"
android:layout_width="130dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="16dp"
android:background="@drawable/bg_rounded_button"
android:drawableStart="@drawable/ic_image"
android:padding="10dp"
Expand All @@ -35,9 +37,10 @@

<Button
android:id="@+id/btnVideoPicker"
android:layout_width="130dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:background="@drawable/bg_rounded_button"
android:drawableStart="@drawable/ic_video"
android:padding="10dp"
Expand All @@ -52,10 +55,11 @@

<Button
android:id="@+id/btnDocPicker"
android:layout_width="130dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="32dp"
android:background="@drawable/bg_rounded_button"
android:drawableStart="@drawable/ic_document"
android:padding="10dp"
Expand All @@ -71,9 +75,11 @@

<Button
android:id="@+id/btnAudioPicker"
android:layout_width="130dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginStart="32dp"
android:layout_marginEnd="16dp"
android:background="@drawable/bg_rounded_button"
android:drawableStart="@drawable/ic_audio"
android:padding="10dp"
Expand All @@ -100,10 +106,50 @@
android:textColor="@android:color/white"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnAudioPicker" />

<Button
android:id="@+id/btnImageCapture"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:background="@drawable/bg_rounded_button"
android:drawableStart="@drawable/ic_camera_white"
android:padding="10dp"
android:text="Snapshot"
android:textAllCaps="false"
android:textColor="@android:color/white"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/btnVideoCapture"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnDocumentSystemIntent" />

<Button
android:id="@+id/btnVideoCapture"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="32dp"
android:background="@drawable/bg_rounded_button"
android:drawableStart="@drawable/ic_video_cam_white"
android:padding="10dp"
android:text="Record"
android:textAllCaps="false"
android:textColor="@android:color/white"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btnImageCapture"
app:layout_constraintTop_toBottomOf="@+id/btnDocumentSystemIntent" />
</androidx.constraintlayout.widget.ConstraintLayout>

<androidx.recyclerview.widget.RecyclerView
Expand Down
8 changes: 4 additions & 4 deletions lassi/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ apply plugin: 'com.github.dcendents.android-maven'
group='com.github.Mindinventory'

android {
compileSdkVersion 32
compileSdkVersion 33

defaultConfig {
minSdkVersion 19
targetSdkVersion 32
versionCode 23
versionName "1.0.1"
targetSdkVersion 33
versionCode 24
versionName "1.1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
multiDexEnabled true
Expand Down
10 changes: 8 additions & 2 deletions lassi/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.lassi">

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

<!-- Required only if your app targets Android 13. -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />

<!-- Required to maintain app compatibility. -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:requestLegacyExternalStorage="true"
android:supportsRtl="true">
Expand Down
48 changes: 36 additions & 12 deletions lassi/src/main/java/com/lassi/presentation/camera/CameraFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.provider.Settings
import android.util.Log
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
Expand Down Expand Up @@ -110,14 +111,14 @@ class CameraFragment : LassiBaseViewModelFragment<CameraViewModel>(), View.OnCli
override fun initLiveDataObservers() {
super.initLiveDataObservers()
viewModel.startVideoRecord.observe(this, SafeObserver(this::handleVideoRecord))
viewModel.cropImageLiveData.observe(this, SafeObserver {uri->
viewModel.cropImageLiveData.observe(this, SafeObserver { uri ->
if (LassiConfig.getConfig().isCrop && LassiConfig.getConfig().maxCount <= 1) {
CropUtils.beginCrop(requireActivity(),uri)
CropUtils.beginCrop(requireActivity(), uri)
} else {
ArrayList<MiMedia>().also {
MiMedia().apply {
this.path = uri.path
it.add(this)
this.path = uri.path
it.add(this)
}
setResultOk(it)
}
Expand Down Expand Up @@ -219,8 +220,12 @@ class CameraFragment : LassiBaseViewModelFragment<CameraViewModel>(), View.OnCli
}

private fun showPermissionDisableAlert() {
val alertMessage = if (LassiConfig.getConfig().mediaType == MediaType.VIDEO) {
val alertMessage = if (LassiConfig.getConfig().mediaType == MediaType.VIDEO && Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
R.string.camera_audio_storage_permission_rational
} else if (LassiConfig.getConfig().mediaType == MediaType.VIDEO && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
R.string.camera_audio_permission_rational
} else if (LassiConfig.getConfig().mediaType == MediaType.IMAGE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
R.string.camera_permission_rational
} else {
R.string.camera_storage_permission_rational
}
Expand Down Expand Up @@ -257,11 +262,16 @@ class CameraFragment : LassiBaseViewModelFragment<CameraViewModel>(), View.OnCli
Manifest.permission.CAMERA
) != PackageManager.PERMISSION_GRANTED

needsStorage =
needsStorage && ActivityCompat.checkSelfPermission(
requireContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {

needsStorage =
needsStorage && ActivityCompat.checkSelfPermission(
requireContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
//Storage permission is not required for Tiramisu
}

if (needsAudio)
needsAudio =
Expand Down Expand Up @@ -291,12 +301,25 @@ class CameraFragment : LassiBaseViewModelFragment<CameraViewModel>(), View.OnCli
) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.READ_MEDIA_IMAGES
) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.READ_MEDIA_VIDEO
) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.READ_MEDIA_AUDIO
) != PackageManager.PERMISSION_GRANTED
) {
val permissions = mutableListOf(
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
Manifest.permission.CAMERA
)

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
}

val needsAudio =
LassiConfig.getConfig().mediaType == MediaType.VIDEO
&& cameraView.audio == Audio.ON
Expand All @@ -309,6 +332,7 @@ class CameraFragment : LassiBaseViewModelFragment<CameraViewModel>(), View.OnCli
if (needsAudio) {
permissions.add(Manifest.permission.RECORD_AUDIO)
}

requestPermission.launch(permissions.toTypedArray())
}
}
Expand Down
Loading

0 comments on commit 200db7f

Please sign in to comment.