Fullscreen view of pictures

This commit is contained in:
leca 2024-10-01 17:54:23 +03:00
parent 743c74b2f2
commit 23549344d4
12 changed files with 178 additions and 33 deletions

View File

@ -1,15 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-feature android:name="android.hardware.camera" android:required="true"/>
<uses-feature
android:name="android.hardware.camera"
android:required="true"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:authorities="org.foxarmy.barcodescannerforemployees.providers"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
@ -17,11 +23,17 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.BarcodeScannerForEmployees"
android:authorities="org.foxarmy.barcodescannerforemployees.providers"
tools:targetApi="31">
<activity
android:name=".FullscreenActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="false"
android:label="@string/title_activity_fullscreen"
android:theme="@style/Theme.BarcodeScannerForEmployees.Fullscreen"/>
<provider
android:authorities="com.google.firebase.components.MainActivity.provider"
android:name="androidx.core.content.FileProvider"
android:authorities="com.google.firebase.components.MainActivity.provider;com.google.firebase.components.FullscreenActivity.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
@ -32,14 +44,17 @@
android:name="com.google.mlkit.vision.DEPENDENCIES"
android:value="barcode_ui">
</meta-data>
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.BarcodeScannerForEmployees">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -2,10 +2,15 @@ package org.foxarmy.barcodescannerforemployees
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat.startActivity
import java.io.File
class AbstractProductView: LinearLayout {
@ -15,7 +20,7 @@ class AbstractProductView: LinearLayout {
private var categoryField: TextView
private var unitField: TextView
constructor(activity: Activity, context: Context, productImageFile: String, productName: String, netWeight: Double, category: Int) : super(context) {
constructor(activity: Activity, context: Context, productImageHash: String, productName: String, netWeight: Double, category: Int) : super(context) {
val inflater:LayoutInflater = activity.layoutInflater
inflater.inflate(R.layout.abstract_product_view, this)
@ -26,14 +31,31 @@ class AbstractProductView: LinearLayout {
categoryField = findViewById(R.id.categoryView)
unitField = findViewById(R.id.unitView)
val picturesDir = File(context.filesDir, "pictures")
picturesDir.mkdirs()
val imageUri = getImageUri(activity, File(picturesDir, productImageFile))
val thumbnailsDir = File(context.cacheDir, "thumbnails")
thumbnailsDir.mkdirs()
val imageUri = getImageUri(activity, File(thumbnailsDir, "$productImageHash.webp"))
Log.d("QWERTYUIOP", "${productPicture.minimumWidth}x${productPicture.minimumHeight}")
productPicture.setImageURI(imageUri)
productPicture.rotation = 90f
productPicture.setOnClickListener {
Log.d("QWERTYUIOP", productImageHash)
val fullscreenIntent = Intent(activity, FullscreenActivity::class.java)
val extras = Bundle()
extras.putString("imagehash", productImageHash)
fullscreenIntent.putExtras(extras)
startActivity(context, fullscreenIntent, extras)
}
productNameField.text = productName
netWeightField.text = netWeight.toString()
//TODO: category and units
findViewById<ConstraintLayout>(R.id.productLayout).setOnClickListener {
Log.d("QWERTYUIOP", "Clicked layout")
}
}
}

View File

@ -1,6 +1,8 @@
package org.foxarmy.barcodescannerforemployees
import android.content.ContentValues
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Build
import android.os.Bundle
import android.util.Log
@ -10,6 +12,7 @@ import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.core.graphics.scale
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.google.mlkit.vision.barcode.common.Barcode
@ -17,6 +20,7 @@ import com.google.mlkit.vision.codescanner.GmsBarcodeScannerOptions
import com.google.mlkit.vision.codescanner.GmsBarcodeScanning
import org.foxarmy.barcodescannerforemployees.databinding.AddProductFragmentBinding
import java.io.File
import java.io.FileOutputStream
import java.nio.file.Files
import java.nio.file.StandardCopyOption
@ -40,12 +44,20 @@ class AddProductFragment : Fragment() {
return binding.root
}
@RequiresApi(Build.VERSION_CODES.O)
@RequiresApi(Build.VERSION_CODES.R)
val takePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) { success: Boolean ->
if (success) {
//Move picture to a proper directory according to its calculated hash
val tempfile = File(requireContext().filesDir, "image.png")
val imageHash = tempfile.inputStream().readBytes().toString(Charsets.UTF_8).md5()
val imageContent = tempfile.inputStream().readBytes()
val imageHash = imageContent.toString(Charsets.UTF_8).md5()
val thumbnailsDir = File(requireContext().cacheDir, "thumbnails")
thumbnailsDir.mkdirs()
val thumbnailFile = File(thumbnailsDir, "$imageHash.webp")
var img = BitmapFactory.decodeByteArray(imageContent, 0, imageContent.size)
img = img.scale(img.width/4,img.height/4)
img.compress(Bitmap.CompressFormat.WEBP_LOSSY, 25, FileOutputStream(thumbnailFile))
pictureFile = File(picturesPath, "$imageHash.png")
Files.move(tempfile.toPath(), pictureFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
tempfile.delete()
@ -56,7 +68,7 @@ class AddProductFragment : Fragment() {
}
}
@RequiresApi(Build.VERSION_CODES.O)
@RequiresApi(Build.VERSION_CODES.R)
fun getPicture () {
//Saving picture to a temp file for further hash calculation and moving to a proper directory
val imageFile = File(requireContext().filesDir, "image.png")
@ -67,7 +79,7 @@ class AddProductFragment : Fragment() {
takePicture.launch(imageUri)
}
@RequiresApi(Build.VERSION_CODES.O)
@RequiresApi(Build.VERSION_CODES.R)
val requestPermissionLauncher =
registerForActivityResult(
ActivityResultContracts.RequestPermission()
@ -104,7 +116,7 @@ class AddProductFragment : Fragment() {
val values = ContentValues().apply {
put(ProductContract.ProductEntry.PRODUCT_NAME, productName)
put(ProductContract.ProductEntry.PRODUCT_NET_WEIGHT, netWeight.toString())
put(ProductContract.ProductEntry.IMAGE_FILENAME, pictureFile.name)
put(ProductContract.ProductEntry.IMAGE_FILENAME, pictureFile.nameWithoutExtension)
}
db.insert(ProductContract.ProductEntry.TABLE_NAME, null, values)

View File

@ -0,0 +1,43 @@
package org.foxarmy.barcodescannerforemployees
import android.app.Activity
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.widget.ImageView
import android.widget.LinearLayout
import org.foxarmy.barcodescannerforemployees.databinding.ActivityFullscreenBinding
import java.io.File
class FullscreenActivity : Activity() {
private lateinit var binding: ActivityFullscreenBinding
private lateinit var fullscreenImageView: ImageView
private lateinit var fullscreenContentControls: LinearLayout
private val hideHandler = Handler(Looper.myLooper()!!)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_fullscreen)
fullscreenImageView = findViewById(R.id.fullscreenImageView)
val extras = intent.extras
val imageHash = extras!!.get("imagehash") as String? //extras!!.getParcelable<Parcelable>("imagehash") as String?
val picturesDir = File(filesDir, "pictures")
picturesDir.mkdirs()
Log.d("QWERTYUIOP", imageHash.toString())
val fullscreenImageFile = File(picturesDir, "$imageHash.png")
// crash. change activity
fullscreenImageView.setImageURI(getImageUri(this, fullscreenImageFile))
fullscreenImageView.setOnClickListener {
this.finish()
}
}
}

View File

@ -2,6 +2,7 @@ package org.foxarmy.barcodescannerforemployees
import android.os.Bundle
import android.provider.BaseColumns
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -39,18 +40,22 @@ class StorageFragment : Fragment() {
while(moveToNext()) {
val productName = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.PRODUCT_NAME))
val netWeight = getDouble(getColumnIndexOrThrow(ProductContract.ProductEntry.PRODUCT_NET_WEIGHT))
val pictureFilename = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.IMAGE_FILENAME))
val productImageHash = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.IMAGE_FILENAME))
getView()?.findViewById<GridLayout>(R.id.contentGridLayout)?.addView(
AbstractProductView(
val abstractProduct = AbstractProductView(
requireActivity(),
requireContext(),
productImageFile = pictureFilename,
productName = productName,
netWeight = netWeight,
category = 1
)
productImageHash,
productName,
netWeight,
1
)
getView()?.findViewById<GridLayout>(R.id.contentGridLayout)?.addView(abstractProduct)
abstractProduct.setOnClickListener {
Log.d("QWERTYUIOP", "Clicked view")
}
// getView()?.findViewById<GridView>(R.id.contentGridLayout)?
}
}

View File

@ -2,14 +2,15 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="200dp"
android:layout_height="200dp">
android:layout_height="wrap_content" app:barrierMargin="1dp" android:clickable="false">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent" android:id="@+id/productLayout" android:outlineProvider="bounds">
android:layout_height="wrap_content" android:id="@+id/productLayout" android:outlineProvider="bounds"
android:background="#00FFFEFE" android:clickable="true">
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp" app:srcCompat="@android:drawable/ic_btn_speak_now"
android:layout_height="200dp" app:srcCompat="@android:drawable/ic_btn_speak_now"
android:id="@+id/productPicture"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
@ -19,8 +20,8 @@
android:layout_height="wrap_content" android:id="@+id/productNameView"
app:layout_constraintTop_toBottomOf="@+id/productPicture"
android:layout_marginTop="15dp" app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="25dp" android:fontFamily="monospace" android:textSize="20sp"
android:maxLines="2"/>
android:fontFamily="monospace" android:textSize="20sp"
android:maxLines="2" android:layout_marginStart="10dp"/>
<TextView
android:text="@string/sample_product_net_weight"
android:layout_width="wrap_content"
@ -42,7 +43,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/categoryView"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="20dp" android:fontFamily="monospace" android:textSize="10sp"
android:layout_marginEnd="25dp" android:fontFamily="monospace" android:textSize="10sp"
app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="20dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
android:theme="@style/ThemeOverlay.BarcodeScannerForEmployees.FullscreenContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
tools:context=".FullscreenActivity">
<!-- The primary full-screen view. This can be replaced with whatever view
is needed to present your content, e.g. VideoView, SurfaceView,
TextureView, etc. -->
<!-- This FrameLayout insets its children based on system windows using
android:fitsSystemWindows. -->
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent" app:srcCompat="@android:drawable/alert_dark_frame"
android:id="@+id/fullscreenImageView" android:contentDescription="@string/fullscreen_image"/>
</FrameLayout>

View File

@ -4,4 +4,6 @@
<!-- Customize your dark theme here. -->
<!-- <item name="colorPrimary">@color/my_dark_primary</item> -->
</style>
<style name="ThemeOverlay.BarcodeScannerForEmployees.FullscreenContainer" parent="">
</style>
</resources>

View File

@ -6,4 +6,8 @@
<color name="light_blue_600">#FF039BE5</color>
<color name="gray_400">#FFBDBDBD</color>
<color name="gray_600">#FF757575</color>
<color name="light_blue_900">#FF01579B</color>
<color name="light_blue_A200">#FF40C4FF</color>
<color name="light_blue_A400">#FF00B0FF</color>
<color name="black_overlay">#66000000</color>
</resources>

View File

@ -17,4 +17,8 @@
<string name="sample_product_net_weight">1998</string>
<string name="sample_unit">g</string>
<string name="sample_category">Sample category</string>
<string name="title_activity_fullscreen">FullscreenActivity</string>
<string name="dummy_button">Dummy Button</string>
<string name="dummy_content">DUMMY\nCONTENT</string>
<string name="fullscreen_image">Fullscreen image</string>
</resources>

View File

@ -3,4 +3,12 @@
<item name="android:background">@color/gray_400</item>
<item name="exampleColor">@color/light_blue_400</item>
</style>
<style name="Widget.Theme.BarcodeScannerForEmployees.ActionBar.Fullscreen" parent="Widget.AppCompat.ActionBar">
<item name="android:background">@color/black_overlay</item>
</style>
<style name="Widget.Theme.BarcodeScannerForEmployees.ButtonBar.Fullscreen" parent="">
<item name="android:background">@color/black_overlay</item>
<item name="android:buttonBarStyle">?android:attr/buttonBarStyle</item>
</style>
</resources>

View File

@ -6,4 +6,12 @@
</style>
<style name="Theme.BarcodeScannerForEmployees" parent="Base.Theme.BarcodeScannerForEmployees"/>
<style name="Theme.BarcodeScannerForEmployees.Fullscreen" parent="Theme.BarcodeScannerForEmployees">
<item name="android:actionBarStyle">@style/Widget.Theme.BarcodeScannerForEmployees.ActionBar.Fullscreen</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">@null</item>
</style>
<style name="ThemeOverlay.BarcodeScannerForEmployees.FullscreenContainer" parent="">
</style>
</resources>