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
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())
}
}
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!
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
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)
}
}
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}"
}