How to print image in thermal printer using Android? - android

I need to print a image using thermal printer. Now I am able to print text using below code,
private fun printBill() {
Thread {
try {
val sock = Socket("192.168.100.99", 9100)
val oStream = PrintWriter(sock.getOutputStream())
oStream.printf("%-35s %-5s %5s\n", "Jihin Raju", 10.00, 100.00)
oStream.println(charArrayOf(0x1D.toChar(), 0x56.toChar(), 0x41.toChar(), 0x10.toChar()))
oStream.close()
sock.close()
} catch (e: UnknownHostException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
}
runOnUiThread {
Toast.makeText(this#MainActivity, "Printed ", Toast.LENGTH_SHORT).show()
}
}.start()
}
Is there any way to print image

Related

hubConnection.on() is not working In Android Kotlin

i am implementing SignalR on client side with android using kotlin. I can connect and can get connection id its mean connection established succeeded after that invoke and subscribed it, when i call hubConnection.on() it could not move inside any log or nor catch any exception. where i have done mistake any help is appreciated
lifecycle.coroutineScope.launchWhenCreated {
hubConnection =
HubConnectionBuilder.create("baseurl",)
.build()
hubConnection.start().blockingAwait()
Log.e("123**** ", "Established connection......" + hubConnection.connectionId)
val userID = "Model.user_id"
try {
hubConnection.invoke(
"Subscribe",
hubConnection.connectionId,
arrayListOf(
userID,
"$userID+_messaging",
"$userID+_notification",
"$userID+_setting",
"$userID+_plan",
"$userID+_refresh"
)
).subscribe()
} catch (e: Exception) {
Log.e("ExceptionDone: ", e.toString())
}
try {
hubConnection.on("ReceiveSimplifiedRealTime", { response: String ->
// runOnUiThread {
Log.e("Receive123**** ", response)
//}
}, String::class.java)
} catch (e: Exception) {
Log.e("Receive123**** ", e.toString())
} catch (e: ExecutionException) {
Log.e("Receive123**** ", e.toString())
}
}

Get EMUI version of a device programmatically

During my application execution, how can I get EMUI version?
Is there any system method to get EMUI version?
It is possible through accessing system properties like:
#SuppressLint("PrivateApi")
private fun Any?.readEMUIVersion() : String {
try {
val propertyClass = Class.forName("android.os.SystemProperties")
val method: Method = propertyClass.getMethod("get", String::class.java)
var versionEmui = method.invoke(propertyClass, "ro.build.version.emui") as String
if (versionEmui.startsWith("EmotionUI_")) {
versionEmui = versionEmui.substring(10, versionEmui.length)
}
return versionEmui
} catch (e: ClassNotFoundException) {
e.printStackTrace()
} catch (e: NoSuchMethodException) {
e.printStackTrace()
} catch (e: IllegalAccessException) {
e.printStackTrace()
} catch (e: InvocationTargetException) {
e.printStackTrace()
}
return ""
}
However, this is a private Api and if it is not suitable in your case, you can possibly use this workaround (would work for EMUI 9 and 10, however definitely wouldn't for EMUI 5 or below (~android 7)):
#TargetApi(3)
fun Any?.extractEmuiVersion() : String {
return try {
val line: String = Build.DISPLAY
val spaceIndex = line.indexOf(" ")
val lastIndex = line.indexOf("(")
if (lastIndex != -1) {
line.substring(spaceIndex, lastIndex)
} else line.substring(spaceIndex)
} catch (e: Exception) { "" }
}
Any suggestions how to improve the answer are highly appreciated!

Handle no internet connection error of retrofit 2.6 with kotlin coroutines

I'm using retrofit 2.6 with kotlin coroutines to make API call without block the UI thread, I got it work but the app crashes when I switch off the internet connection. The logcat error is: E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
Here is my code:
private fun handleIntent(slug: String) {
val service = UtilityMethods.migrationTimeService()
UtilityMethods.showView(loading_view)
UtilityMethods.hideView(network_error_msg)
CoroutineScope(Dispatchers.IO).launch {
val res = service.getPostBySlug(slug)
try {
withContext(Dispatchers.Main) {
//Do something with response e.g show to the UI.
val post = res.body()!!.first()
UtilityMethods.hideView(loading_view)
val title = post.title?.rendered
val content = post.content?.rendered
val imageUrl = post.jetPackFeaturedMediaUrl
title_txtView.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
Html.fromHtml(title, Html.FROM_HTML_MODE_COMPACT).toString()
else
Html.fromHtml(title).toString()
content_txtView.loadData(content.toString(), "text/html", "UTF-8")
Picasso.get().load(imageUrl).fit().centerCrop().into(thumbnail_imgview)
}
} catch (e: HttpException) {
UtilityMethods.showView(network_error_msg)
} catch (e: Throwable) {
Toast.makeText(this#PostContentActivity, "Ooops: Something else went wrong", Toast.LENGTH_LONG)
}
}
}
I've got the code working, the new code is:
private fun handleIntent(slug: String) = GlobalScope.launch(Dispatchers.Main) {
val service = UtilityMethods.migrationTimeService()
UtilityMethods.showView(loading_view)
UtilityMethods.hideView(network_error_msg)
try {
val res = withContext(Dispatchers.IO) {
service.getPostBySlug(slug)
}
//Do something with response e.g show to the UI.
val post = res.body()!!.first()
UtilityMethods.hideView(loading_view)
val title = post.title?.rendered
val content = post.content?.rendered
val imageUrl = post.jetPackFeaturedMediaUrl
title_txtView.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
Html.fromHtml(title, Html.FROM_HTML_MODE_COMPACT).toString()
else
Html.fromHtml(title).toString()
content_txtView.loadData(content.toString(), "text/html", "UTF-8")
Picasso.get().load(imageUrl).fit().centerCrop().into(thumbnail_imgview)
}
catch (e: HttpException) {
Toast.makeText(this#PostContentActivity, "Exception ${e.message}", Toast.LENGTH_LONG).show()
}catch (e: IOException) {
UtilityMethods.hideView(loading_view)
UtilityMethods.showView(network_error_msg)
} catch (e: Throwable) {
Toast.makeText(this#PostContentActivity, "Ooops: Something else went wrong ${e.message}", Toast.LENGTH_LONG).show()
}
}
So while looking into stacktrace I found that ConnectException is thrown when network is unavailable
And that's how I do it in kotlin and it works for me,
suspend fun<T: Any> safeAPICall(call: suspend () -> Response<T>) : T{
val response = try {
call.invoke()
}
catch (e:java.lang.Exception){
e.printStackTrace()
val message = if( e is ConnectException) "Connection Error" else "Something went wrong. Please try again."
throw IOException(ResponseError(message, 500).convertToJsonString())
}
// When connection is OK
if(response.isSuccessful){
return response.body()!!
}else{
val error = response.errorBody()?.string()
error?.let{
val message = JSONObject(it).optString("message", "Something went wrong")
val responseError = ResponseError(message, response.code())
throw IOException(responseError.convertToJsonString())
}
throw IOException(ResponseError("Something went wrong. Please try again.", 500).convertToJsonString())
}
}
The data class that I use
data class ResponseError(val message:String, val errorCode:Int)
Usage:
try {
val response = safeAPICall {APIClient.planner.viewSites(view.context.authToken)}
}
catch (e:Exception){
view.snack(e.message?.toModel<ResponseError>()?.message?: unspecified_error)
}
Bonus:
inline fun <reified T> JSONObject.toModel(): T? = this.run {
try {
Gson().fromJson<T>(this.toString(), T::class.java)
}
catch (e:java.lang.Exception){ e.printStackTrace(); null }
}
inline fun <reified T> String.toModel(): T? = this.run {
try {
JSONObject(this).toModel<T>()
}
catch (e:java.lang.Exception){ null }
}
Instead of this:
CoroutineScope(Dispatchers.IO).launch {
val res = service.getPostBySlug(slug)
try {
withContext(Dispatchers.Main) {
Try this one:
CoroutineScope(Dispatchers.Main).launch {
val res = service.getPostBySlug(slug)
withContext(Dispatchers.IO) {
try {
wrap your 'try and catch' block code within Dispatchers.IO instead of wraping your Dispatchers.IO with in yout try block

How to simply pass a string from android studio (kotlin) to arduino serial bluetooth module (HC-05)?

I'm making an android app for a school project, using Android Studio (Kotlin).
I need to send strings to an Arduino Genuino Uno module, passing by a HC-05 bluetooth module.
The Arduino will already be connected (paired) to my android device when the app will be launched.
Can someone help me to find a right and easy way to only SEND these datas ?
Thanks a lot.
I finally got the answer, I did that :
private fun CheckBt() {
Toast.makeText(applicationContext, "It has started", Toast.LENGTH_SHORT).show()
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
if (!mBluetoothAdapter.enable()) {
Toast.makeText(applicationContext, "Bluetooth Disabled !", Toast.LENGTH_SHORT).show()
/* It tests if the bluetooth is enabled or not, if not the app will show a message. */
finish()
}
if (mBluetoothAdapter == null) {
Toast.makeText(applicationContext, "Bluetooth null !", Toast.LENGTH_SHORT).show()
}
}
fun Connect() {
val device = mBluetoothAdapter.getRemoteDevice("98:D3:32:71:17:DE")
Log.d("", "Connecting to ... $device")
Toast.makeText(applicationContext, "Connecting to ... ${device.name} mac: ${device.uuids[0]} address: ${device.address}", Toast.LENGTH_LONG).show()
mBluetoothAdapter.cancelDiscovery()
try {
btSocket = device.createRfcommSocketToServiceRecord(myUUID)
/* Here is the part the connection is made, by asking the device to create a RfcommSocket (Unsecure socket I guess), It map a port for us or something like that */
btSocket.connect()
Log.d("", "Connection made.")
Toast.makeText(applicationContext, "Connection made.", Toast.LENGTH_SHORT).show()
} catch (e: IOException) {
try {
btSocket.close()
} catch (e2: IOException) {
Log.d("", "Unable to end the connection")
Toast.makeText(applicationContext, "Unable to end the connection", Toast.LENGTH_SHORT).show()
}
Log.d("", "Socket creation failed")
Toast.makeText(applicationContext, "Socket creation failed", Toast.LENGTH_SHORT).show()
}
//beginListenForData()
/* this is a method used to read what the Arduino says for example when you write Serial.print("Hello world.") in your Arduino code */
}
private fun writeData(data: String) {
var outStream = btSocket.outputStream
try {
outStream = btSocket.outputStream
} catch (e: IOException) {
//Log.d(FragmentActivity.TAG, "Bug BEFORE Sending stuff", e)
}
val msgBuffer = data.toByteArray()
try {
outStream.write(msgBuffer)
} catch (e: IOException) {
//Log.d(FragmentActivity.TAG, "Bug while sending stuff", e)
}
}

How to wait for khttp (kotlin) response in Android

I've been trying to use khttp to send an .jpg file in an android activity but haven't been able to make it work.
fun sendImage(view: View) {
try {
var bmp = (imageView?.drawable as BitmapDrawable).bitmap
var bos = ByteArrayOutputStream()
bmp.compress(Bitmap.CompressFormat.JPEG, 0, bos)
var response: Response? = null
findViewById<TextView>(R.id.image_desc).text = "Connecting to " + SERVER_URL;
try {
val job=GlobalScope.launch {
response = post(SERVER_URL, files = listOf(File(path).fileLike(name = "Image.jpg")))
}
findViewById<TextView>(R.id.image_desc).text = "Image contains: ${response?.text}"
} catch (e: Exception) {
findViewById<TextView>(R.id.image_desc).text = "Connection failed - please check fields are valid"
findViewById<TextView>(R.id.image_desc).text = e.toString()
}
} catch (e: UnknownHostException) {
findViewById<TextView>(R.id.image_desc).text = "Unknown host :("
e.printStackTrace()
} catch (e: IOException) {
findViewById<TextView>(R.id.image_desc).text = "IO exceptiion :("
e.printStackTrace()
} catch (e: Exception) {
findViewById<TextView>(R.id.image_desc).text = "Other exception :("
e.printStackTrace()
}
}
As soon as i send the image, image_desc textView's text change to Image contains: null. I'm sure the server isn't the problem, since when I test it with this python code:
import requests
url=...
files = {'file': open('./test/cat.jpg', 'rb')}
r=requests.post(url,files=files)
print (r.text)
I get the desired response after a short delay. I've tried turning sendImage to a suspend func and writing job.join() but that crashes the app. How should fix this?
Try next code:
val job = GlobalScope.launch(Dispatchers.Main) {
val postOperation = async(Dispatchers.IO) { // <- extension on launch scope, launched in IO dispatcher
// blocking I/O operation
post(SERVER_URL, files = listOf(File(path).fileLike(name = "Image.jpg")))
}
response = postOperation.await() // wait for result of I/O operation without blocking the main thread
findViewById<TextView>(R.id.image_desc).text = "Image contains: ${response?.text}"
}
Also add next line to app's build.gradle dependency:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.1'
Note that GlobalScope is discouraged to use, to launch a coroutine use an instance of CoroutineScope, or existing instance like viewModelScope or lifecycleScope.
UPDATE:
The correct approach would be to use lifecycleScope in Activity:
lifecycleScope.launch { // uses Dispatchers.Main context
val response = withContext(Dispatchers.IO) { // change context to background thread
// blocking I/O operation
post(SERVER_URL, files = listOf(File(path).fileLike(name = "Image.jpg")))
}
findViewById<TextView>(R.id.image_desc).text = "Image contains: ${response?.text}"
}

Categories

Resources