Skip to content

Commit

Permalink
Develop (#55)
Browse files Browse the repository at this point in the history
- issues fixes and improvements.
Co-authored-by: AKASH PATEL <akash.patel@mindinventory.com>
  • Loading branch information
sanjay-mi authored Mar 3, 2022
1 parent 4934336 commit 4d37779
Show file tree
Hide file tree
Showing 23 changed files with 224 additions and 29 deletions.
25 changes: 21 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Lassi is simplest way to pick media (either image, video, audio or doc)
* Filter by particular media type
* Filter videos by min and max time
* Enable/disable camera from LassiOption
* You can open System Default view for file selection by using MediaType.FILE_TYPE_WITH_SYSTEM_VIEW

# Usage

Expand Down Expand Up @@ -51,18 +52,19 @@ Lassi is simplest way to pick media (either image, video, audio or doc)
```groovy
dependencies {
...
implementation 'com.github.Mindinventory:Lassi:0.3.0'
implementation 'com.github.Mindinventory:Lassi:X.X.X'
}
```
### Implementation
* Step 1. Add Lassi in to your activity class:
* Step 1.
To open a app color theme view then add Lassi in to your activity class:
```kotlin
val intent = Lassi(this)
.with(LassiOption.CAMERA_AND_GALLERY) // choose Option CAMERA, GALLERY or CAMERA_AND_GALLERY
.with(LassiOption.CAMERA_AND_GALLERY) // choose Option CAMERA or CAMERA_AND_GALLERY
.setMaxCount(5)
.setGridSize(3)
.setMediaType(MediaType.VIDEO) // MediaType : VIDEO IMAGE, AUDIO OR DOC
Expand Down Expand Up @@ -90,7 +92,18 @@ Lassi is simplest way to pick media (either image, video, audio or doc)
.build()
receiveData.launch(intent)
```
`OR` To open a system default view then add Lassi in to your activity class:
```kotlin
val intent = Lassi(this)
.setMediaType(MediaType.FILE_TYPE_WITH_SYSTEM_VIEW)
.setSupportedFileTypes(
"jpg", "jpeg", "png", "webp", "gif", "mp4", "mkv", "webm", "avi", "flv", "3gp",
"pdf", "odt", "doc", "docs", "docx", "txt", "ppt", "pptx", "rtf", "xlsx", "xls"
) // Filter by required media format (Mandatory)
.build()
receiveData.launch(intent)
```

* Step 2. Get Lassi result in ActivityResultCallback lambda function.

Expand All @@ -110,6 +123,10 @@ Lassi is simplest way to pick media (either image, video, audio or doc)

### Document access permission note
If Android device SDK is >= 30 and wants to access document (only for choose the non media file) then add ```android.permission.MANAGE_EXTERNAL_STORAGE``` permission in your app otherwise library won't allow to access documents. Kindly check sample app for more detail.
If you don't want to give Manage External Storage permission and wants to get files with system default view then You can use `OR` option from Step 1 and give required file type of document.

### MediaType.FILE_TYPE_WITH_SYSTEM_VIEW (for System Default View)
Using this MediaType you can choose multiple files from system default view. You can't set max count limit for file choose. Give file type into setSupportedFileTypes and you can choose only those types of file from system view.
### Guideline for contributors
Contribution towards our repository is always welcome, we request contributors to create a pull request to the **develop** branch only.
Expand All @@ -125,7 +142,7 @@ It would be great for us if the reporter can share the below things to understan
### Requirements
* minSdkVersion >= 17
* minSdkVersion >= 19
* Androidx
### Library used
Expand Down
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ android {
compileSdkVersion 32
defaultConfig {
applicationId "com.lassi.app"
minSdkVersion 17
minSdkVersion 19
targetSdkVersion 32
versionCode 1
versionName "1.0"
Expand Down
32 changes: 31 additions & 1 deletion app/src/main/java/com/lassi/app/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
btnVideoPicker.setOnClickListener(this)
btnAudioPicker.setOnClickListener(this)
btnDocPicker.setOnClickListener(this)
btnDocumentSystemIntent.setOnClickListener(this)
rvSelectedMedia.adapter = selectedMediaAdapter
rvSelectedMedia.addItemDecoration(GridSpacingItemDecoration(2, 10))
}
Expand Down Expand Up @@ -108,6 +109,36 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
R.id.btnDocPicker -> {
requestPermissionForDocument()
}
R.id.btnDocumentSystemIntent -> {
val intent = Lassi(this)
.setMediaType(MediaType.FILE_TYPE_WITH_SYSTEM_VIEW)
.setSupportedFileTypes(
"jpg",
"jpeg",
"png",
"webp",
"gif",
"mp4",
"mkv",
"webm",
"avi",
"flv",
"3gp",
"pdf",
"odt",
"doc",
"docs",
"docx",
"txt",
"ppt",
"pptx",
"rtf",
"xlsx",
"xls"
)
.build()
receiveData.launch(intent)
}
}
}

Expand Down Expand Up @@ -206,7 +237,6 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
}
}
}

else -> {
launchDocPicker()
}
Expand Down
18 changes: 18 additions & 0 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,24 @@
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnImagePicker" />

<Button
android:id="@+id/btnDocumentSystemIntent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/bg_rounded_button"
android:drawableStart="@drawable/ic_document"
android:padding="10dp"
android:text="@string/open_system_view"
android:textAllCaps="false"
android:textColor="@android:color/white"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnAudioPicker" />
</androidx.constraintlayout.widget.ConstraintLayout>

<androidx.recyclerview.widget.RecyclerView
Expand Down
Empty file modified app/src/main/res/mipmap-hdpi/ic_launcher.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified app/src/main/res/mipmap-hdpi/ic_launcher_round.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified app/src/main/res/mipmap-mdpi/ic_launcher.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified app/src/main/res/mipmap-mdpi/ic_launcher_round.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified app/src/main/res/mipmap-xhdpi/ic_launcher.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified app/src/main/res/mipmap-xxhdpi/ic_launcher.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
<string name="video">Video</string>
<string name="document">Document</string>
<string name="audio">Audio</string>
<string name="open_system_view">Open System View</string>
</resources>
6 changes: 3 additions & 3 deletions lassi/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ android {
compileSdkVersion 32

defaultConfig {
minSdkVersion 17
minSdkVersion 19
targetSdkVersion 32
versionCode 20
versionName "0.3.0"
versionCode 21
versionName "0.4.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
multiDexEnabled true
Expand Down
24 changes: 24 additions & 0 deletions lassi/src/main/java/com/lassi/common/extenstions/ContextExt.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.lassi.common.extenstions

import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.provider.OpenableColumns

fun Context.getFileName(uri: Uri): String? {
val returnCursor: Cursor? = this.contentResolver.query(uri, null, null, null, null)
val nameIndex: Int? = returnCursor?.getColumnIndex(OpenableColumns.DISPLAY_NAME)
returnCursor?.moveToFirst()
val name: String? = nameIndex?.let { returnCursor.getString(it) }
returnCursor?.close()
return name
}

fun Context.getFileSize(uri: Uri): Long {
val returnCursor: Cursor? = this.contentResolver.query(uri, null, null, null, null)
val sizeIndex: Int? = returnCursor?.getColumnIndex(OpenableColumns.SIZE)
returnCursor?.moveToFirst()
val size: Long? = sizeIndex?.let { returnCursor.getLong(it) }
returnCursor?.close()
return size ?: 0L
}
64 changes: 63 additions & 1 deletion lassi/src/main/java/com/lassi/common/utils/FilePickerUtils.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package com.lassi.common.utils

import android.content.ContentResolver
import android.content.Context
import android.media.MediaScannerConnection
import android.net.Uri
import android.util.Log
import android.webkit.MimeTypeMap
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream
import java.io.OutputStream
import java.util.*

object FilePickerUtils {
Expand All @@ -19,7 +25,7 @@ object FilePickerUtils {
context: Context,
filePath: String,
mimeType: String = "image/*",
onFileScanComplete: (uri: Uri?, path:String?) -> Unit
onFileScanComplete: (uri: Uri?, path: String?) -> Unit
) {
context.let {
MediaScannerConnection.scanFile(
Expand All @@ -32,4 +38,60 @@ object FilePickerUtils {
}
}
}
private fun getFileExtension(context: Context, uri: Uri): String? =
if (uri.scheme == ContentResolver.SCHEME_CONTENT)
MimeTypeMap.getSingleton()
.getExtensionFromMimeType(context.contentResolver.getType(uri))
else uri.path?.let {
MimeTypeMap.getFileExtensionFromUrl(
Uri.fromFile(File(it)).toString()
)
}
fun getFilePathFromUri(context: Context, uri: Uri, uniqueName: Boolean): String =
if (uri.path?.contains("file://") == true) uri.path!!
else getFileFromContentUri(context, uri, uniqueName).path
private fun getFileFromContentUri(
context: Context,
contentUri: Uri,
uniqueName: Boolean,
): File {
// Preparing Temp file name
val fileExtension = getFileExtension(context, contentUri) ?: ""
val fileName =
("file" + if (uniqueName) System.currentTimeMillis() else "") + ".$fileExtension"
// Creating Temp file
val tempFile = File(context.cacheDir, fileName)
tempFile.createNewFile()
// Initialize streams
var oStream: FileOutputStream? = null
var inputStream: InputStream? = null
try {
oStream = FileOutputStream(tempFile)
inputStream = context.contentResolver.openInputStream(contentUri)
inputStream?.let { copy(inputStream, oStream) }
oStream.flush()
} catch (e: Exception) {
e.printStackTrace()
} finally {
// Close streams
inputStream?.close()
oStream?.close()
}
return tempFile
}
private fun copy(source: InputStream, target: OutputStream) {
val buf = ByteArray(8192)
var length: Int
while (source.read(buf).also { length = it } > 0) {
target.write(buf, 0, length)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,9 @@ class MediaRepositoryImpl(private val context: Context) : MediaRepository {
MediaStore.Video.Media.DATE_ADDED
)
}
else ->{
null
}
}
}

Expand Down
1 change: 0 additions & 1 deletion lassi/src/main/java/com/lassi/domain/media/LassiOption.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ package com.lassi.domain.media

enum class LassiOption {
CAMERA,
GALLERY,
CAMERA_AND_GALLERY
}
3 changes: 2 additions & 1 deletion lassi/src/main/java/com/lassi/domain/media/MediaType.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ enum class MediaType(val value: Int) {
IMAGE(1),
VIDEO(2),
AUDIO(3),
DOC(4)
DOC(4),
FILE_TYPE_WITH_SYSTEM_VIEW(5)
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ class FolderFragment : LassiBaseViewModelFragment<FolderViewModel>() {

private val requestPermission =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { map ->
if (map.entries.all {
it.value == true
}) {
if (map.entries.all { it.value }) {
fetchFolders()
} else {
showPermissionDisableAlert()
Expand Down
Loading

0 comments on commit 4d37779

Please sign in to comment.