This repository is a demo about using Kotlin in Flutter to perform different operations and transfer the results to Flutter.
- Reading a json file with countries and their capitals and displaying the read values as a list on the Flutter side.
- Accessing the phone's gallery, having the user select an image and showing this image on the Flutter side.
- Accessing the phone's camera with permissions, having the user take a photo and showing this photo on the Flutter side.
![](https://private-user-images.githubusercontent.com/120099096/311443719-ef088960-a206-4a1e-aa78-e4f381d07fb0.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjU3NTQ4NjgsIm5iZiI6MTcyNTc1NDU2OCwicGF0aCI6Ii8xMjAwOTkwOTYvMzExNDQzNzE5LWVmMDg4OTYwLWEyMDYtNGExZS1hYTc4LWU0ZjM4MWQwN2ZiMC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwOTA4JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDkwOFQwMDE2MDhaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1jODI5YjBhNDE5ZTk3NjUyNDYwMDcwYmZjY2I3ZmJkNzRjNTRiYTE5YzIwMDVmOWU0M2VjYzQ1ZmRhNzM4YjgzJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.55FjHXgMunDJmfDTm_Du-8E3x47ilX_FK83xb_ArMt8)
![](https://private-user-images.githubusercontent.com/120099096/311443742-a1088458-eb97-4b39-8491-8333f3394e30.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjU3NTQ4NjgsIm5iZiI6MTcyNTc1NDU2OCwicGF0aCI6Ii8xMjAwOTkwOTYvMzExNDQzNzQyLWExMDg4NDU4LWViOTctNGIzOS04NDkxLTgzMzNmMzM5NGUzMC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwOTA4JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDkwOFQwMDE2MDhaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1kNzA0OTFiZjFjODg1MDkwOWEyMGYyYmQ5ODFkMGNmZjgwZDEyNDczMDUxOGEwZjdiYjY3ZDQwMGM5MTY0OGNiJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.YSsGg64MeBrZi2yybn5Nwse_1cpCE6ZIuiQCafBAIdY)
![](https://private-user-images.githubusercontent.com/120099096/311443760-c7098f32-9f51-4e3c-a080-5c7eeff89315.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjU3NTQ4NjgsIm5iZiI6MTcyNTc1NDU2OCwicGF0aCI6Ii8xMjAwOTkwOTYvMzExNDQzNzYwLWM3MDk4ZjMyLTlmNTEtNGUzYy1hMDgwLTVjN2VlZmY4OTMxNS5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwOTA4JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDkwOFQwMDE2MDhaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT01OGFkYjUxY2JjNTgzMzVjZTM1Yzc3NDY4OTQzZjZiOWY1M2Y1ZjY0M2ExZDVhYzhhNGYwZDE4ZWM0ZjhlYTdhJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.lTLQRjtf7yCW8VSpa8WSircDt-BgjvrGS2mYbgGt1aU)
![](https://private-user-images.githubusercontent.com/120099096/311443793-dcd053a9-9e2d-425f-bed4-e68ffe100090.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjU3NTQ4NjgsIm5iZiI6MTcyNTc1NDU2OCwicGF0aCI6Ii8xMjAwOTkwOTYvMzExNDQzNzkzLWRjZDA1M2E5LTllMmQtNDI1Zi1iZWQ0LWU2OGZmZTEwMDA5MC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwOTA4JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDkwOFQwMDE2MDhaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1kY2M2MWM5Y2U5NmI1YmFlZTY5MmY5YTViYWFhMjY0YjgwNmFiMjdhZTExYTMwNzA1ZDMwMGJhNTQ4NGJhNTIzJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.ua7W0OJ29gtEKNff3vVmWDWuLBRoE6BueALTIpjO1pg)
![](https://private-user-images.githubusercontent.com/120099096/311443807-16309095-2d0a-4c73-ab81-9703aeb3c7c8.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjU3NTQ4NjgsIm5iZiI6MTcyNTc1NDU2OCwicGF0aCI6Ii8xMjAwOTkwOTYvMzExNDQzODA3LTE2MzA5MDk1LTJkMGEtNGM3My1hYjgxLTk3MDNhZWIzYzdjOC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwOTA4JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDkwOFQwMDE2MDhaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1iNmMzMDJkYmU5OTlkYzkyNzBmNmU2YmVlMDMwNzcxMDNiYTdmNjRhNGIwZTdkM2IxMDgwZDgwM2VkOTVkYzJjJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.wpXTXkCiadz-cEP0_YRYSWCEP2sDeh6CZRj7JvSDBhg)
![](https://private-user-images.githubusercontent.com/120099096/311443813-8e1d9336-dbae-476f-aa34-1c2e68734e5c.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjU3NTQ4NjgsIm5iZiI6MTcyNTc1NDU2OCwicGF0aCI6Ii8xMjAwOTkwOTYvMzExNDQzODEzLThlMWQ5MzM2LWRiYWUtNDc2Zi1hYTM0LTFjMmU2ODczNGU1Yy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwOTA4JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDkwOFQwMDE2MDhaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0yZTM5MWUxZDMyNmEzZjkxNmZjYjlmZWE0OTk5ZjNjYmZlMWFkNWVlNjZkMTcwZDA4OWM2MmZhN2JhYmY2OTA5JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.TsVq5H5XO0tAYDm-JNICHVOK8bODEeNhc9YgV--oH1I)
![](https://private-user-images.githubusercontent.com/120099096/311443816-1c99633d-4b4f-4dc3-b55d-6ae8a27f8ae0.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjU3NTQ4NjgsIm5iZiI6MTcyNTc1NDU2OCwicGF0aCI6Ii8xMjAwOTkwOTYvMzExNDQzODE2LTFjOTk2MzNkLTRiNGYtNGRjMy1iNTVkLTZhZThhMjdmOGFlMC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwOTA4JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDkwOFQwMDE2MDhaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1jYTU4MDVhMzE4NmM0NWQ4YWY2ZGQxNzU3MGMyMTc2MGQxYmEzNmRlMTBhOTRjMjU0N2MzMTlkZmNhN2YzZTgwJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.E98ZU_dPGfHouFWDAJmNKLH6tEcUzQ9nlrczr7DQoBo)
static const platform = MethodChannel('my_channel');
String jsonString = await platform.invokeMethod('getJsonStringOfCapitals');
var base64Result = await platform.invokeMethod('selectImageInAlbum');
var base64Result = await platform.invokeMethod('takePhoto');
class MainActivity: FlutterActivity() {
val CAMERA_REQUEST_CODE = 200
val GALLERY_REQUEST_CODE = 300
- reading the json file
if(call.method == "getJsonStringOfCapitals") {
lateinit var jsonString: String
try {
jsonString = context.assets.open("country-by-capital-city.json").bufferedReader().use { it.readText()}
result.success(jsonString)
} catch (ex: Exception) {
ex.printStackTrace()
}
}
We use result.success
to access the result on the Flutter side.
- open gallery
if(call.method == "selectImageInAlbum"){
mResult = result
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "image/*"
if (intent.resolveActivity(packageManager) != null) {
startActivityForResult(intent, GALLERY_REQUEST_CODE)
}
}
- onActivityResult
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
if (requestCode == GALLERY_REQUEST_CODE) {
var selectedImageUri = data?.getData()
if (selectedImageUri != null) {
val inputStream: InputStream = contentResolver.openInputStream(selectedImageUri)!!
val bytes = ByteArray(inputStream.available())
inputStream.read(bytes)
inputStream.close()
val base64Image = Base64.encodeToString(bytes, Base64.DEFAULT)
mResult.success(base64Image)
}
}
- permission control
if(call.method == "takePhoto"){
mResult = result
if (ContextCompat.checkSelfPermission(applicationContext,android.Manifest.permission.CAMERA ) == PackageManager.PERMISSION_GRANTED) {
openCamera()
} else {
ActivityCompat.requestPermissions(
this,
arrayOf(android.Manifest.permission.CAMERA),
CAMERA_REQUEST_CODE
)
}
}
- the method that opens the camera
private fun openCamera() {
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(intent, CAMERA_REQUEST_CODE)
}
- permission result
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
when (requestCode) {
CAMERA_REQUEST_CODE -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Kullanıcı kamera iznini verdi, kamera açma işlemine devam et
openCamera()
} else {
// Kullanıcı kamera iznini reddetti, hata mesajı göster veya başka bir işlem yap
mResult.error("PERMISSION_DENIED", "Kamera izni reddedildi.", null)
}
}
// Diğer izin istek kodlarını işleyebilirsiniz (gerektiğinde)
}
}
- onActivityResult
// inside of if (resultCode == RESULT_OK) {
if (requestCode == CAMERA_REQUEST_CODE ) {
val photo: Bitmap = data?.extras?.get("data") as Bitmap
val base64Image: String = convertBitmapToBase64(photo)
mResult.success(base64Image)
}