Skip to content

Instantly share code, notes, and snippets.

@ayetolusamuel
Created November 27, 2020 15:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ayetolusamuel/cfe765433058a6d0de877b76d0065434 to your computer and use it in GitHub Desktop.
Save ayetolusamuel/cfe765433058a6d0de877b76d0065434 to your computer and use it in GitHub Desktop.
//runtime permission check for location
fun checkPermission(): Boolean{
return ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
//request permission
fun requestPermission(){
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
locationPermissionCode)
}
@ayetolusamuel
Copy link
Author

//check if gps & network is enabled
fun checkGPSNetwork():Boolean{
val lm = getSystemService(LOCATION_SERVICE) as LocationManager
var gps_enabled = false
var network_enabled = false

    try {
        gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER)
    } catch (ex: Exception) {
    }

    try {
        network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
    } catch (ex: Exception) {
    }

    if (!gps_enabled && !network_enabled) {
        // notify user

        startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
        return false
    }else
        return true
}

@ayetolusamuel
Copy link
Author

//custom toast
fun Activity.customToast(message: String = getString(R.string.invalid_login_details)) {
val inflater = layoutInflater
val layout = inflater.inflate(R.layout.custom_toast, custom_toast_container) as ViewGroup
val displayMessage = layout.findViewById(R.id.message)
val toast = Toast(applicationContext)
displayMessage.text = message
toast.setGravity(Gravity.BOTTOM, 0, 64)
toast.duration = Toast.LENGTH_SHORT
toast.view = layout
toast.show()
}

@ayetolusamuel
Copy link
Author

//validate email
fun isValidEmail(target: CharSequence?) = Patterns.EMAIL_ADDRESS.matcher(target!!).matches()

@ayetolusamuel
Copy link
Author

ayetolusamuel commented Nov 28, 2020

//hidekeyboard
fun Activity.hideKeyboard() {
try {
val inputMethodManager: InputMethodManager? =
getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager?
inputMethodManager?.hideSoftInputFromWindow(currentFocus!!.windowToken, 0)
} catch (exception: Exception) {
exception.printStackTrace()
}
}

public static void hideKeyboard(Activity activity) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
//Find the currently focused view, so we can grab the correct window token from it.
View view = activity.getCurrentFocus();
//If no view currently has focus, create a new one, just so we can grab a window token from it
if (view == null) {
view = new View(activity);
}
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

public static void hideKeyboardFrom(Context context, View view) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

// Check if no view has focus:
val view = this.currentFocus
view?.let { v ->
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
imm?.hideSoftInputFromWindow(v.windowToken, 0)
}

@ayetolusamuel
Copy link
Author

ayetolusamuel commented Nov 28, 2020

save/retrieve encrypt & decrypt

fun Context.saveDataToBeEncrypted(map: HashMap<String, ByteArray>) {
val sharedPreferences = getDefaultSharedPreferences(this)
val editor = sharedPreferences.edit()
val gSon = Gson()
val valueString = gSon.toJson(map)
editor.putString(ENCRYPTED_PREFERENCE_VALUE, valueString).apply()
}

fun Context.getDataEncrypted(): HashMap<String, ByteArray> {
val sharedPreferences = getDefaultSharedPreferences(this)
val valueString = sharedPreferences.getString(ENCRYPTED_PREFERENCE_VALUE, "")
return Gson().fromJson(
valueString,
object : TypeToken<HashMap<String?, ByteArray?>?>() {}.type
)
}

@ayetolusamuel
Copy link
Author

//bitmap to byteArray
fun convertBitmapToByteArray(bitmap: Bitmap): ByteArray {
val stream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)
val byteArray: ByteArray = stream.toByteArray()
bitmap.recycle()
return byteArray
}

@ayetolusamuel
Copy link
Author

//encrypt and decrypt
fun encrypt(encryptedValue: ByteArray): HashMap<String, ByteArray> {
val map = HashMap<String, ByteArray>()
val random = SecureRandom()
val salt = ByteArray(256)
random.nextBytes(salt)

val passwordChar = ENCRYPTED_VALUE.toCharArray()
val pbKeySpec = PBEKeySpec(passwordChar, salt, 1324, 256)
val secretKeyFactory = SecretKeyFactory.getInstance(ALGORITHM_ENCRYPTED_VALUE)

val keyBytes = secretKeyFactory.generateSecret(pbKeySpec).encoded
val keySpec = SecretKeySpec(keyBytes, ALGORITHM_VALUE)

val ivRandom = SecureRandom()
val iv = ByteArray(16)
ivRandom.nextBytes(iv)
val ivSpec = IvParameterSpec(iv)


val cipher = Cipher.getInstance(TRANSFORMATION_ENCRYPTED_VALUE)
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec)
val encrypted = cipher.doFinal(encryptedValue)

map["salt"] = salt
map["iv"] = iv
map["encrypted"] = encrypted
return map

}

fun decrypt(map: HashMap<String, ByteArray>): ByteArray {

var decrypted: ByteArray? = null
try {
    val salt = map["salt"]
    val iv = map["iv"]
    val encrypted = map["encrypted"]
    val passwordChar = ENCRYPTED_VALUE.toCharArray()
    val pbKeySpec = PBEKeySpec(passwordChar, salt, 1324, 256)
    val secretFactory = SecretKeyFactory.getInstance(ALGORITHM_ENCRYPTED_VALUE)


    val keyBytes = secretFactory.generateSecret(pbKeySpec).encoded
    val keySpec = SecretKeySpec(keyBytes, ALGORITHM_VALUE)


    val cipher = Cipher.getInstance(TRANSFORMATION_ENCRYPTED_VALUE)
    val ivSpec = IvParameterSpec(iv)
    cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec)
    decrypted = cipher.doFinal(encrypted)


} catch (e: Exception) {
    e.printStackTrace()

}
return decrypted!!

}

@ayetolusamuel
Copy link
Author

save & retrieve from sharepreference
fun Context.saveEmailToSharePreference(email: String) {
val preferences = getDefaultSharedPreferences(this)
val editor = preferences.edit()
editor.putString(AGENT_EMAIL, email)
editor.apply()
}

fun Context.getEmailFromSharePreference(): String? {
return getDefaultSharedPreferences(this)
.getString(AGENT_EMAIL, null)
}

@ayetolusamuel
Copy link
Author

//check internet access
/**

  • Check whether network is available

  • @return Whether device is connected to Network.
    */
    fun Context.checkInternetAccess(): Boolean {
    try {

     with(getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager) {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
             //Device is running on Marshmallow or later Android OS.
             with(getNetworkCapabilities(activeNetwork)) {
                 @Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
                 return this!!.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || hasTransport(
                     NetworkCapabilities.TRANSPORT_CELLULAR
                 )
             }
         } else {
             @Suppress("DEPRECATION")
             activeNetworkInfo?.let {
                 // connected to the internet
                 @Suppress("DEPRECATION")
                 return listOf(
                     ConnectivityManager.TYPE_WIFI,
                     ConnectivityManager.TYPE_MOBILE
                 ).contains(it.type)
             }
         }
     }
     return false
    

    } catch (exc: NullPointerException) {
    return false
    }

}

@ayetolusamuel
Copy link
Author

@SuppressLint("SimpleDateFormat")
fun convertLongToTime(time: Long): String {
val date = Date(time)
val format = SimpleDateFormat(DATE_TIME_FORMAT)
return format.format(date)
}

@ayetolusamuel
Copy link
Author

fun getStringFromBitmap(imageView: ImageView): Bitmap {
imageView.invalidate()
val drawable = imageView.drawable as BitmapDrawable
return drawable.bitmap
}

@ayetolusamuel
Copy link
Author

//save image to phone memory and return the path
fun Context.saveToInternalStorageForFingerprint(
enrolmentId: String,
fingerprintName: String,
bitmapImage: Bitmap
): String {
println("Bit $bitmapImage")
val cw = ContextWrapper(applicationContext)
// path to /data/data/yourapp/app_data/imageDir
val directory = cw.getDir("fingerprint", Context.MODE_PRIVATE)
// Create imageDir
val mypath = File(directory, "${Date().time}-$fingerprintName-${enrolmentId}.jpg")
var fos: FileOutputStream? = null
try {

    fos = FileOutputStream(mypath)
    // Use the compress method on the BitMap object to write image to the OutputStream
    bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos)

} catch (e: java.lang.Exception) {
    e.printStackTrace()
} finally {
    try {
        fos!!.close()
    } catch (e: IOException) {
        e.printStackTrace()
    }
}


return mypath.absolutePath

}

@ayetolusamuel
Copy link
Author

ayetolusamuel commented Nov 28, 2020

//check if the device is rooted
fun findBinary(binaryName: String): Boolean {
var found = false
if (!found) {
val places = arrayOf("/sbin/", "/system/bin/", "/system/xbin/",
"/data/local/xbin/", "/data/local/bin/",
"/system/sd/xbin/", "/system/bin/failsafe/", "/data/local/")
for (where in places) {
if (File(where + binaryName).exists()) {
found = true
break
}
}
}
return found
}

fun isRooted(): Boolean {
return findBinary("su")
}

@ayetolusamuel
Copy link
Author

//initdate picker

fun Context.initDatePicker(dateEditText: EditText, calendar: Calendar) {

val date =
    DatePickerDialog.OnDateSetListener { view, year, monthOfYear, dayOfMonth -> // TODO Auto-generated method stub
        calendar.set(Calendar.YEAR, year)
        calendar.set(Calendar.MONTH, monthOfYear)
        calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth)
        updateLabel(dateEditText, calendar)
    }


dateEditText.setOnClickListener {
    val datePickerDialog = DatePickerDialog(this,
        date,
        calendar.get(Calendar.YEAR),
        calendar.get(Calendar.MONTH),
        calendar.get(
            Calendar.DAY_OF_MONTH))
    datePickerDialog.show()
    datePickerDialog.getButton(DatePickerDialog.BUTTON_NEGATIVE).setTextColor(Color.GRAY);
    datePickerDialog.getButton(DatePickerDialog.BUTTON_POSITIVE).setTextColor(Color.GRAY);
}

}

private fun updateLabel(dateField: EditText, calendar: Calendar) {
val myFormat = "dd/MM/yyyy"

val sdf = SimpleDateFormat(myFormat, Locale.US)

dateField.setText(sdf.format(calendar.time))

}

@ayetolusamuel
Copy link
Author

//round off decimal
fun roundOffDecimal(number: Double): Double? {
val df = DecimalFormat("#.##")
df.roundingMode = RoundingMode.CEILING
return df.format(number).toDouble()
}

@ayetolusamuel
Copy link
Author

//convert string to base64

fun convertBase64ToImage(encodedImage: String): Bitmap{
val pureEncodedImage = encodedImage.substring(encodedImage.indexOf(",") + 1)
val decodedString: ByteArray = Base64.decode(pureEncodedImage, Base64.DEFAULT)
return BitmapFactory.decodeByteArray(decodedString, 0, decodedString.size)
}

fun convertImageToBase64(bitmapImage: Bitmap):String{
val baos = ByteArrayOutputStream()
bitmapImage.compress(Bitmap.CompressFormat.JPEG, 100, baos) // bm is the bitmap object
val b: ByteArray = baos.toByteArray()
return Base64.encodeToString(b, Base64.DEFAULT)

}

@ayetolusamuel
Copy link
Author

//generate random number
fun generateProjectPrimaryNumber(): String? {
val random = Random()
val number = random.nextInt(9999999)
return String.format("%07d", number)
}

@ayetolusamuel
Copy link
Author

fun getImageFromInternalStorage(context: Context, imageFileName: String): Bitmap? {
        val directory = context.filesDir
        val file = File(directory, imageFileName)
        return BitmapFactory.decodeStream(FileInputStream(file))
    }

@ayetolusamuel
Copy link
Author

   fun deleteImageFromInternalStorage(context: Context, imageFileName: String): Boolean {
        val dir = context.filesDir
        val file = File(dir, imageFileName)
        return file.delete()
    }

@ayetolusamuel
Copy link
Author

//phone resolution
fun Context.getPhoneResolutionValue(): String{
var result = ""
when(resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK){
Configuration.SCREENLAYOUT_SIZE_LARGE -> {
result = LARGE_SCREEN
}
Configuration.SCREENLAYOUT_SIZE_NORMAL ->{
result = NORMAL_SCREEN
}

    Configuration.SCREENLAYOUT_SIZE_SMALL ->{
        result = SMALL_SCREEN

    }
}
return result

}

@ayetolusamuel
Copy link
Author

ayetolusamuel commented Nov 30, 2020

//Camerax demo with analysis

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.Manifest
import android.content.pm.PackageManager
import android.net.Uri
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import java.util.concurrent.Executors
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import kotlinx.android.synthetic.main.activity_main.*
import java.io.File
import java.nio.ByteBuffer
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.ExecutorService
typealias LumaListener = (luma: Double) -> Unit

class MainActivity : AppCompatActivity() {
private var imageCapture: ImageCapture? = null

private lateinit var outputDirectory: File
private lateinit var cameraExecutor: ExecutorService

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Request camera permissions
    if (allPermissionsGranted()) {
        startCamera()

    } else {
        ActivityCompat.requestPermissions(
                this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)
    }

    // Set up the listener for take photo button
    camera_capture_button.setOnClickListener { takePhoto() }

    outputDirectory = getOutputDirectory()

    cameraExecutor = Executors.newSingleThreadExecutor()

}

private fun takePhoto() {

    image.visibility = View.GONE
    viewFinder.visibility = View.VISIBLE
    println("take photo")
    // Get a stable reference of the modifiable image capture use case
    println("image capture $imageCapture")
    val imageCapture = imageCapture ?: return

    // Create time-stamped output file to hold the image
    val photoFile = File(
            outputDirectory,
            SimpleDateFormat(FILENAME_FORMAT, Locale.US
            ).format(System.currentTimeMillis()) + ".jpg")

    println("File $photoFile")

    // Create output options object which contains file + metadata
    val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()
    println("output $outputOptions")

    // Set up image capture listener, which is triggered after photo has
    // been taken
    imageCapture.takePicture(
            outputOptions, ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageSavedCallback {
        override fun onError(exc: ImageCaptureException) {
            println("Error ${exc.message}")
            Log.e(TAG, "Photo capture failed: ${exc.message}", exc)
        }

        override fun onImageSaved(output: ImageCapture.OutputFileResults) {
            val savedUri = Uri.fromFile(photoFile)
            viewFinder.visibility = View.GONE
            image.visibility = View.VISIBLE
            image.setImageURI(savedUri)

             val msg = "Photo capture succeeded: $savedUri"
            println("message $msg")
            Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
            Log.d(TAG, msg)
        }
    })


}

private fun startCamera() {
    val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

    cameraProviderFuture.addListener(Runnable {
        // Used to bind the lifecycle of cameras to the lifecycle owner
        val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

        // Preview
        val preview = Preview.Builder()
                .build()
                .also {
                    it.setSurfaceProvider(viewFinder.createSurfaceProvider())
                }

        imageCapture = ImageCapture.Builder()
                .build()

        val imageAnalyzer = ImageAnalysis.Builder()
                .build()
                .also {
                    it.setAnalyzer(cameraExecutor, LuminosityAnalyzer { luma ->
                        Log.d(TAG, "Average luminosity: $luma")
                    })
                }

        // Select back camera as a default
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

        try {
            // Unbind use cases before rebinding
            cameraProvider.unbindAll()

            // Bind use cases to camera
            cameraProvider.bindToLifecycle(
                    this, cameraSelector, preview, imageCapture, imageAnalyzer)

        } catch(exc: Exception) {
            Log.e(TAG, "Use case binding failed", exc)
        }

    }, ContextCompat.getMainExecutor(this))
}

private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
    ContextCompat.checkSelfPermission(
            baseContext, it) == PackageManager.PERMISSION_GRANTED
}

private fun getOutputDirectory(): File {
    val mediaDir = externalMediaDirs.firstOrNull()?.let {
        File(it, resources.getString(R.string.enrolment_id)).apply { mkdirs() } }
    return if (mediaDir != null && mediaDir.exists())
        mediaDir else filesDir
}

override fun onDestroy() {
    super.onDestroy()
    cameraExecutor.shutdown()
}


override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<String>, grantResults:
        IntArray) {
    if (requestCode == REQUEST_CODE_PERMISSIONS) {
        if (allPermissionsGranted()) {
            startCamera()
        } else {
            Toast.makeText(this,
                    "Permissions not granted by the user.",
                    Toast.LENGTH_SHORT).show()
            finish()
        }
    }
}


companion object {
    private const val TAG = "form_capture"
   // private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
    private const val FILENAME_FORMAT = "ddMMyyyy"
    private const val ENROLMENT_ID = "123443444"
    private const val REQUEST_CODE_PERMISSIONS = 10
    private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
}

private class LuminosityAnalyzer(private val listener: LumaListener) : ImageAnalysis.Analyzer {

    private fun ByteBuffer.toByteArray(): ByteArray {
        rewind()    // Rewind the buffer to zero
        val data = ByteArray(remaining())
        get(data)   // Copy the buffer into a byte array
        return data // Return the byte array
    }

    override fun analyze(image: ImageProxy) {

        val buffer = image.planes[0].buffer
        val data = buffer.toByteArray()
        val pixels = data.map { it.toInt() and 0xFF }
        val luma = pixels.average()

        listener(luma)

        image.close()
    }
}

}

@ayetolusamuel
Copy link
Author

//Camerax demo with analysis

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.Manifest
import android.content.pm.PackageManager
import android.net.Uri
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import java.util.concurrent.Executors
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import kotlinx.android.synthetic.main.activity_main.*
import java.io.File
import java.nio.ByteBuffer
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.ExecutorService
typealias LumaListener = (luma: Double) -> Unit

class MainActivity : AppCompatActivity() {
private var imageCapture: ImageCapture? = null

private lateinit var outputDirectory: File
private lateinit var cameraExecutor: ExecutorService

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Request camera permissions
    if (allPermissionsGranted()) {
        startCamera()

    } else {
        ActivityCompat.requestPermissions(
                this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)
    }

    // Set up the listener for take photo button
    camera_capture_button.setOnClickListener { takePhoto() }

    outputDirectory = getOutputDirectory()

    cameraExecutor = Executors.newSingleThreadExecutor()

}

private fun takePhoto() {

    image.visibility = View.GONE
    viewFinder.visibility = View.VISIBLE
    println("take photo")
    // Get a stable reference of the modifiable image capture use case
    println("image capture $imageCapture")
    val imageCapture = imageCapture ?: return

    // Create time-stamped output file to hold the image
    val photoFile = File(
            outputDirectory,
            SimpleDateFormat(FILENAME_FORMAT, Locale.US
            ).format(System.currentTimeMillis()) + ".jpg")

    println("File $photoFile")

    // Create output options object which contains file + metadata
    val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()
    println("output $outputOptions")

    // Set up image capture listener, which is triggered after photo has
    // been taken
    imageCapture.takePicture(
            outputOptions, ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageSavedCallback {
        override fun onError(exc: ImageCaptureException) {
            println("Error ${exc.message}")
            Log.e(TAG, "Photo capture failed: ${exc.message}", exc)
        }

        override fun onImageSaved(output: ImageCapture.OutputFileResults) {
            val savedUri = Uri.fromFile(photoFile)
            viewFinder.visibility = View.GONE
            image.visibility = View.VISIBLE
            image.setImageURI(savedUri)

             val msg = "Photo capture succeeded: $savedUri"
            println("message $msg")
            Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
            Log.d(TAG, msg)
        }
    })


}

private fun startCamera() {
    val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

    cameraProviderFuture.addListener(Runnable {
        // Used to bind the lifecycle of cameras to the lifecycle owner
        val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

        // Preview
        val preview = Preview.Builder()
                .build()
                .also {
                    it.setSurfaceProvider(viewFinder.createSurfaceProvider())
                }

        imageCapture = ImageCapture.Builder()
                .build()

        val imageAnalyzer = ImageAnalysis.Builder()
                .build()
                .also {
                    it.setAnalyzer(cameraExecutor, LuminosityAnalyzer { luma ->
                        Log.d(TAG, "Average luminosity: $luma")
                    })
                }

        // Select back camera as a default
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

        try {
            // Unbind use cases before rebinding
            cameraProvider.unbindAll()

            // Bind use cases to camera
            cameraProvider.bindToLifecycle(
                    this, cameraSelector, preview, imageCapture, imageAnalyzer)

        } catch(exc: Exception) {
            Log.e(TAG, "Use case binding failed", exc)
        }

    }, ContextCompat.getMainExecutor(this))
}

private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
    ContextCompat.checkSelfPermission(
            baseContext, it) == PackageManager.PERMISSION_GRANTED
}

private fun getOutputDirectory(): File {
    val mediaDir = externalMediaDirs.firstOrNull()?.let {
        File(it, resources.getString(R.string.enrolment_id)).apply { mkdirs() } }
    return if (mediaDir != null && mediaDir.exists())
        mediaDir else filesDir
}

override fun onDestroy() {
    super.onDestroy()
    cameraExecutor.shutdown()
}


override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<String>, grantResults:
        IntArray) {
    if (requestCode == REQUEST_CODE_PERMISSIONS) {
        if (allPermissionsGranted()) {
            startCamera()
        } else {
            Toast.makeText(this,
                    "Permissions not granted by the user.",
                    Toast.LENGTH_SHORT).show()
            finish()
        }
    }
}


companion object {
    private const val TAG = "form_capture"
   // private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
    private const val FILENAME_FORMAT = "ddMMyyyy"
    private const val ENROLMENT_ID = "123443444"
    private const val REQUEST_CODE_PERMISSIONS = 10
    private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
}

private class LuminosityAnalyzer(private val listener: LumaListener) : ImageAnalysis.Analyzer {

    private fun ByteBuffer.toByteArray(): ByteArray {
        rewind()    // Rewind the buffer to zero
        val data = ByteArray(remaining())
        get(data)   // Copy the buffer into a byte array
        return data // Return the byte array
    }

    override fun analyze(image: ImageProxy) {

        val buffer = image.planes[0].buffer
        val data = buffer.toByteArray()
        val pixels = data.map { it.toInt() and 0xFF }
        val luma = pixels.average()

        listener(luma)

        image.close()
    }
}

}

@ayetolusamuel
Copy link
Author

//Camerax demo with analysis
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.Manifest
import android.content.pm.PackageManager
import android.net.Uri
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import java.util.concurrent.Executors
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import kotlinx.android.synthetic.main.activity_main.*
import java.io.File
import java.nio.ByteBuffer
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.ExecutorService
typealias LumaListener = (luma: Double) -> Unit
class MainActivity : AppCompatActivity() {
private var imageCapture: ImageCapture? = null

private lateinit var outputDirectory: File
private lateinit var cameraExecutor: ExecutorService

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Request camera permissions
    if (allPermissionsGranted()) {
        startCamera()

    } else {
        ActivityCompat.requestPermissions(
                this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)
    }

    // Set up the listener for take photo button
    camera_capture_button.setOnClickListener { takePhoto() }

    outputDirectory = getOutputDirectory()

    cameraExecutor = Executors.newSingleThreadExecutor()

}

private fun takePhoto() {

    image.visibility = View.GONE
    viewFinder.visibility = View.VISIBLE
    println("take photo")
    // Get a stable reference of the modifiable image capture use case
    println("image capture $imageCapture")
    val imageCapture = imageCapture ?: return

    // Create time-stamped output file to hold the image
    val photoFile = File(
            outputDirectory,
            SimpleDateFormat(FILENAME_FORMAT, Locale.US
            ).format(System.currentTimeMillis()) + ".jpg")

    println("File $photoFile")

    // Create output options object which contains file + metadata
    val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()
    println("output $outputOptions")

    // Set up image capture listener, which is triggered after photo has
    // been taken
    imageCapture.takePicture(
            outputOptions, ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageSavedCallback {
        override fun onError(exc: ImageCaptureException) {
            println("Error ${exc.message}")
            Log.e(TAG, "Photo capture failed: ${exc.message}", exc)
        }

        override fun onImageSaved(output: ImageCapture.OutputFileResults) {
            val savedUri = Uri.fromFile(photoFile)
            viewFinder.visibility = View.GONE
            image.visibility = View.VISIBLE
            image.setImageURI(savedUri)

             val msg = "Photo capture succeeded: $savedUri"
            println("message $msg")
            Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
            Log.d(TAG, msg)
        }
    })


}

private fun startCamera() {
    val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

    cameraProviderFuture.addListener(Runnable {
        // Used to bind the lifecycle of cameras to the lifecycle owner
        val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

        // Preview
        val preview = Preview.Builder()
                .build()
                .also {
                    it.setSurfaceProvider(viewFinder.createSurfaceProvider())
                }

        imageCapture = ImageCapture.Builder()
                .build()

        val imageAnalyzer = ImageAnalysis.Builder()
                .build()
                .also {
                    it.setAnalyzer(cameraExecutor, LuminosityAnalyzer { luma ->
                        Log.d(TAG, "Average luminosity: $luma")
                    })
                }

        // Select back camera as a default
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

        try {
            // Unbind use cases before rebinding
            cameraProvider.unbindAll()

            // Bind use cases to camera
            cameraProvider.bindToLifecycle(
                    this, cameraSelector, preview, imageCapture, imageAnalyzer)

        } catch(exc: Exception) {
            Log.e(TAG, "Use case binding failed", exc)
        }

    }, ContextCompat.getMainExecutor(this))
}

private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
    ContextCompat.checkSelfPermission(
            baseContext, it) == PackageManager.PERMISSION_GRANTED
}

private fun getOutputDirectory(): File {
    val mediaDir = externalMediaDirs.firstOrNull()?.let {
        File(it, resources.getString(R.string.enrolment_id)).apply { mkdirs() } }
    return if (mediaDir != null && mediaDir.exists())
        mediaDir else filesDir
}

override fun onDestroy() {
    super.onDestroy()
    cameraExecutor.shutdown()
}


override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<String>, grantResults:
        IntArray) {
    if (requestCode == REQUEST_CODE_PERMISSIONS) {
        if (allPermissionsGranted()) {
            startCamera()
        } else {
            Toast.makeText(this,
                    "Permissions not granted by the user.",
                    Toast.LENGTH_SHORT).show()
            finish()
        }
    }
}


companion object {
    private const val TAG = "form_capture"
   // private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
    private const val FILENAME_FORMAT = "ddMMyyyy"
    private const val ENROLMENT_ID = "123443444"
    private const val REQUEST_CODE_PERMISSIONS = 10
    private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
}

private class LuminosityAnalyzer(private val listener: LumaListener) : ImageAnalysis.Analyzer {

    private fun ByteBuffer.toByteArray(): ByteArray {
        rewind()    // Rewind the buffer to zero
        val data = ByteArray(remaining())
        get(data)   // Copy the buffer into a byte array
        return data // Return the byte array
    }

    override fun analyze(image: ImageProxy) {

        val buffer = image.planes[0].buffer
        val data = buffer.toByteArray()
        val pixels = data.map { it.toInt() and 0xFF }
        val luma = pixels.average()

        listener(luma)

        image.close()
    }
}

}

###CameraxApp demo without analysis
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.Manifest
import android.content.pm.PackageManager
import android.net.Uri
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import java.util.concurrent.Executors
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import kotlinx.android.synthetic.main.activity_main.*
import java.io.File
import java.nio.ByteBuffer
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.ExecutorService
typealias LumaListener = (luma: Double) -> Unit

class MainActivity : AppCompatActivity() {
private var imageCapture: ImageCapture? = null

private lateinit var outputDirectory: File
private lateinit var cameraExecutor: ExecutorService

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Request camera permissions
    if (allPermissionsGranted()) {
        startCamera()

    } else {
        ActivityCompat.requestPermissions(
                this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)
    }

    // Set up the listener for take photo button
    camera_capture_button.setOnClickListener { takePhoto() }

    outputDirectory = getOutputDirectory()

    cameraExecutor = Executors.newSingleThreadExecutor()

}

private fun takePhoto() {

    image.visibility = View.GONE
    viewFinder.visibility = View.VISIBLE
    println("take photo")
    // Get a stable reference of the modifiable image capture use case
    println("image capture $imageCapture")
    val imageCapture = imageCapture ?: return

    // Create time-stamped output file to hold the image
    val photoFile = File(
            outputDirectory,
            SimpleDateFormat(FILENAME_FORMAT, Locale.US
            ).format(System.currentTimeMillis()) + ".jpg")

    println("File $photoFile")

    // Create output options object which contains file + metadata
    val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()
    println("output $outputOptions")

    // Set up image capture listener, which is triggered after photo has
    // been taken
    imageCapture.takePicture(
            outputOptions, ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageSavedCallback {
        override fun onError(exc: ImageCaptureException) {
            println("Error ${exc.message}")
            Log.e(TAG, "Photo capture failed: ${exc.message}", exc)
        }

        override fun onImageSaved(output: ImageCapture.OutputFileResults) {
            val savedUri = Uri.fromFile(photoFile)
            viewFinder.visibility = View.GONE
            image.visibility = View.VISIBLE
            image.setImageURI(savedUri)

             val msg = "Photo capture succeeded: $savedUri"
            println("message $msg")
            Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
            Log.d(TAG, msg)
        }
    })


}

private fun startCamera() {
    val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

    cameraProviderFuture.addListener(Runnable {
        // Used to bind the lifecycle of cameras to the lifecycle owner
        val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

        // Preview
        val preview = Preview.Builder()
                .build()
                .also {
                    it.setSurfaceProvider(viewFinder.createSurfaceProvider())
                }

        imageCapture = ImageCapture.Builder()
                .build()

// val imageAnalyzer = ImageAnalysis.Builder()
// .build()
// .also {
// it.setAnalyzer(cameraExecutor, LuminosityAnalyzer { luma ->
// Log.d(TAG, "Average luminosity: $luma")
// })
// }

        // Select back camera as a default
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

        try {
            // Unbind use cases before rebinding
            cameraProvider.unbindAll()

            // Bind use cases to camera
            cameraProvider.bindToLifecycle(
                    this, cameraSelector, preview, imageCapture)

        } catch(exc: Exception) {
            Log.e(TAG, "Use case binding failed", exc)
        }

    }, ContextCompat.getMainExecutor(this))
}

private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
    ContextCompat.checkSelfPermission(
            baseContext, it) == PackageManager.PERMISSION_GRANTED
}

private fun getOutputDirectory(): File {
    val mediaDir = externalMediaDirs.firstOrNull()?.let {
        File(it, resources.getString(R.string.enrolment_id)).apply { mkdirs() } }
    return if (mediaDir != null && mediaDir.exists())
        mediaDir else filesDir
}

override fun onDestroy() {
    super.onDestroy()
    cameraExecutor.shutdown()
}


override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<String>, grantResults:
        IntArray) {
    if (requestCode == REQUEST_CODE_PERMISSIONS) {
        if (allPermissionsGranted()) {
            startCamera()
        } else {
            Toast.makeText(this,
                    "Permissions not granted by the user.",
                    Toast.LENGTH_SHORT).show()
            finish()
        }
    }
}


companion object {
    private const val TAG = "form_capture"
   // private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
    private const val FILENAME_FORMAT = "ddMMyyyy"
    private const val ENROLMENT_ID = "123443444"
    private const val REQUEST_CODE_PERMISSIONS = 10
    private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
}

private class LuminosityAnalyzer(private val listener: LumaListener) : ImageAnalysis.Analyzer {

    private fun ByteBuffer.toByteArray(): ByteArray {
        rewind()    // Rewind the buffer to zero
        val data = ByteArray(remaining())
        get(data)   // Copy the buffer into a byte array
        return data // Return the byte array
    }

    override fun analyze(image: ImageProxy) {

        val buffer = image.planes[0].buffer
        val data = buffer.toByteArray()
        val pixels = data.map { it.toInt() and 0xFF }
        val luma = pixels.average()

        listener(luma)

        image.close()
    }
}

}

@ayetolusamuel
Copy link
Author

fun Context.deleteSharePreference(key: String) {
val settings: SharedPreferences = getDefaultSharedPreferences(this)
settings.edit().remove(key).apply()
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment