I'm trying to identify the type of cellular connection.
I've used different methods, like for example the one suggested here, but I keep getting 4G as a result, on a Samsung with Android 10 and 5G connection.
How is it possible to read the correct network type?
private fun getNetworkType(telephonyManager: TelephonyManager): String {
return when (telephonyManager.networkType) {
TelephonyManager.NETWORK_TYPE_UNKNOWN -> "unknown"
TelephonyManager.NETWORK_TYPE_GPRS,
TelephonyManager.NETWORK_TYPE_EDGE,
TelephonyManager.NETWORK_TYPE_CDMA,
TelephonyManager.NETWORK_TYPE_1xRTT,
TelephonyManager.NETWORK_TYPE_IDEN,
TelephonyManager.NETWORK_TYPE_GSM -> "2G"
TelephonyManager.NETWORK_TYPE_UMTS,
TelephonyManager.NETWORK_TYPE_EVDO_0,
TelephonyManager.NETWORK_TYPE_EVDO_A,
TelephonyManager.NETWORK_TYPE_HSDPA,
TelephonyManager.NETWORK_TYPE_HSUPA,
TelephonyManager.NETWORK_TYPE_HSPA,
TelephonyManager.NETWORK_TYPE_EVDO_B,
TelephonyManager.NETWORK_TYPE_EHRPD,
TelephonyManager.NETWORK_TYPE_HSPAP,
TelephonyManager.NETWORK_TYPE_TD_SCDMA -> "3G"
TelephonyManager.NETWORK_TYPE_LTE,
TelephonyManager.NETWORK_TYPE_IWLAN -> "4G"
TelephonyManager.NETWORK_TYPE_NR -> "5G"
else -> "something else"
}
}
private fun getRadioTechnology(telephonyManager: TelephonyManager): String {
try {
val obj = Class.forName(telephonyManager.javaClass.name)
.getDeclaredMethod("getServiceState", *arrayOfNulls(0)).invoke(telephonyManager, *arrayOfNulls(0))
val methods: Array<Method> = Class.forName(obj.javaClass.name).declaredMethods
for (method in methods) {
if (method.name == "getRadioTechnology" ) {
method.isAccessible = true
val radioTechnology = (method.invoke(obj) as Int).toInt()
return "$radioTechnology"
}
}
} catch (e: Exception) {
Log.e("Test5G", "", e)
}
return ""
}
#SuppressLint("MissingPermission")
fun getActiveSubscriptionInfoList(): String {
val subscriptionInfos = SubscriptionManager.from(this).activeSubscriptionInfoList
var ret: String = ""
for(sub in subscriptionInfos) {
val id = sub.subscriptionId
val telephonyManager = telephonyManager.createForSubscriptionId(id);
ret += getRadioTechnology(telephonyManager)
}
return ret
}
This is how I did it:
telephonyManager.listen(object : PhoneStateListener() {
override fun onServiceStateChanged(serviceState: ServiceState) {
val isNrAvailable = serviceState.toString().isNrAvailable()
// use isNrAvailable
}
}, PhoneStateListener.LISTEN_SERVICE_STATE)
Where
fun String.isNrAvailable() =
contains("nrState=CONNECTED") ||
contains("nsaState=5"))
Related
I'm using coroutines and Set the Internet Permissions in manifest Everything But cant display my data on app when INTERNET is OFF, I'm caching my API response and successfully stored it in the database but cant retrive it when the internet is off
My Code In Repository
class HomeActivityRepository(
private val photoDatabase: PhotoDatabase,
private val applicationContext: Context
) {
private var photoLiveData = MutableLiveData<List<Photos>>()
val errorMessage = MutableLiveData<String>()
var job: Job? = null
val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
onError("Exception handled: ${throwable.localizedMessage}")
}
fun getServicesAPICall(): MutableLiveData<List<Photos>> {
job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch {
val response = RetrofitClient.getInstance().create(ApiInterface::class.java)
val res = response.getServicesAPICall()
withContext(Dispatchers.Main) {
if (NetworkUtils.isInternetAvailable(applicationContext)) {
if (res.isSuccessful) {
photoDatabase.photoDao().insertMemes(res.body()!!)
photoLiveData.postValue(res.body())
} else {
onError("Error : ${res.message()}")
}
} else {
val photos = photoDatabase.photoDao().getPhotos()
photoLiveData.postValue(photos)
}
}
}
return photoLiveData
}
private fun onError(message: String) {
errorMessage.postValue(message)
}
}
I have Zebra TC510K and I am developing an app on it in Kotlin. I am using this EMDK com.symbol:emdk:9.1.1. I am trying to scan Interleaved 2of5 barcode but the scanner doesn´t response.
My code is show below. This is only place where I set decodeParams.i2of5.enabled = true. Other types of barcodes works properly. Do you have somebody some idea what should be wrong?
override fun onStatus(statusData: StatusData) {
val state = statusData.state
when (state){
StatusData.ScannerStates.IDLE -> {
statusString = statusData.friendlyName + " je zapnuty a ceka...."
if (!scanner!!.isReadPending()) {
val scannerConfig = scanner!!.config
//Log.d("scanpr","Before${scannerConfig.decoderParams.i2of5.enabled.toString()}")
scannerConfig.decoderParams.i2of5.enabled = true
scannerConfig.decoderParams.code128.enabled = true
scannerConfig.decoderParams.code39.enabled = true
scannerConfig.decoderParams.code93.enabled = true
//Log.d("scanpr","After${scannerConfig.decoderParams.i2of5.enabled.toString()}")
//scanner!!.config(scannerConfig)
try {
scanner!!.read()
} catch (e: ScannerException) {
statusString = e.message.toString()
statusTextView!!.text = statusString
}
}
}
StatusData.ScannerStates.WAITING -> {
}
StatusData.ScannerStates.SCANNING -> {
}
StatusData.ScannerStates.DISABLED -> {
}
StatusData.ScannerStates.ERROR -> {
}
else -> {
}
}
}
I forget to add one line to setDecoder functionality: scanner!!.config = scannerConfig. To set config of scanner.
if (!scanner!!.isReadPending()) {
val scannerConfig = scanner!!.config
scannerConfig.decoderParams.i2of5.enabled = true
scannerConfig.decoderParams.code128.enabled = true
scannerConfig.decoderParams.code39.enabled = true
scannerConfig.decoderParams.code93.enabled = true
scanner!!.config = scannerConfig
try {
scanner!!.read()
} catch (e: ScannerException) {
statusString = e.message.toString()
statusTextView!!.text = statusString
}
}
I know that there are a lot of posts "How to cancel Coroutines Scope" but I couldn't find the answer for my case.
I have an Array of objects that I want to send each of them to Server using Coroutines.
What I need is, if one of my requests returns error, canceling others.
Here is my code:
private fun sendDataToServer(function: () -> Unit) {
LiabilitiesWizardSessionManager.getLiabilityAddedDocuments().let { documents ->
if (documents.isEmpty().not()) {
CoroutineScope(Dispatchers.IO).launch {
documents.mapIndexed { index, docDetail ->
async {
val result = uploadFiles(docDetail)
}
}.map {
var result = it.await()
}
}
} else function.invoke()
}
}
Below is my uploadFiles() function:
private suspend fun uploadFiles(docDetail: DocDetail): ArchiveFileResponse? {
LiabilitiesWizardSessionManager.mCreateLiabilityModel.let { model ->
val file = File(docDetail.fullFilePath)
val crmCode = docDetail.docTypeCode
val desc = docDetail.docTypeDesc
val id = model.commitmentMember?.id
val idType = 1
val createArchiveFileModel = CreateArchiveFileModel(108, desc, id, idType).apply {
this.isLiability = true
this.adaSystem = 3
}
val result = mRepositoryControllerKotlin.uploadFile(file, createArchiveFileModel)
return when (result) {
is ResultWrapper.Success -> {
result.value
}
is ResultWrapper.GenericError -> {
null
}
is ResultWrapper.NetworkError -> {
null
}
}
}
}
I know, I'm missing something.
I'm using the Ktor library (io.ktor:ktor-client-android:1.2.5) for downloading files.
When I download an image everything is fine, but when I want to download an .apk, it doesn't work.
I'm using ktor 1.2.5.
This is the function that I use:
suspend fun HttpClient.downloadFile(file: OutputStream, url: String): Flow<DownloadResult> {
return flow {
try {
val response = call {
url(url)
method = HttpMethod.Get
}.response
val data = ByteArray(response.contentLength()!!.toInt())
var offset = 0
do {
val currentRead = response.content.readAvailable(data, offset, data.size)
offset += currentRead
val progress = (offset * 100f / data.size).roundToInt()
emit(DownloadResult.Progress(progress))
} while (currentRead > 0)
response.close()
if (response.status.isSuccess()) {
withContext(Dispatchers.IO) {
file.write(data)
//file.write()
}
emit(DownloadResult.Success)
} else {
emit(DownloadResult.Error("File not downloaded"))
}
} catch (e: TimeoutCancellationException) {
emit(DownloadResult.Error("Connection timed out", e))
} catch (t: Throwable) {
emit(DownloadResult.Error("Failed to connect. ${t.message}"))
}
}
}
And I use it like tthis:
private fun downloadFile(view: View, context: Context, url: String, file: Uri) {
val ktor = HttpClient(Android)
//viewModel.setDownloading(true)
context.contentResolver.openOutputStream(file)?.let { outputStream ->
CoroutineScope(Dispatchers.IO).launch {
ktor.downloadFile(outputStream, url).collect {
withContext(Dispatchers.Main) {
when (it) {
is DownloadResult.Success -> {
//viewModel.setDownloading(false)
view.custom_des_pb_progreso_descarga.progress = 0
Toast.makeText(context, "Descarga Completa", Toast.LENGTH_LONG).show()
dismiss()
viewFile(file, context)
}
is DownloadResult.Error -> {
Toast.makeText(context, "Error al descargar actualización. ${it.message} ${it.cause} ", Toast.LENGTH_LONG).show()
dismiss()
}
is DownloadResult.Progress -> {
view.custom_des_pb_progreso_descarga.progress = it.progress
view.custom_des_pb_conteo_descarga.text = "${it.progress}%"
}
}
}
}
}
}
}
Anyone know what might be happening?
I recommend starting with the simplest possible code for downloading files and then add more complexity (flow and DownloadResult) while checking every step of the way. Here is the working code that just downloads a file:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val client = HttpClient(Android)
runBlocking {
client.downloadFile(
"https://search.maven.org/remotecontent?filepath=de/sweetcode/e/1.7.2-alpha/e-1.7.2-alpha.jar",
applicationContext.openFileOutput("result.jar", MODE_PRIVATE)
)
}
}
}
suspend fun HttpClient.downloadFile(url: String, output: OutputStream) {
get<HttpStatement>(url).execute { response ->
response.content.copyTo(output)
}
}
I'm trying to upload a file to Google Drive using Google Drive REST API v3. After the upload process is completed, it returns a status code of 200 (successful). But I can't find the files in my Google Drive. Please tell me what am I doing wrong? I will really appreciate if you provide a proper illustration or better still code snippet while helping me with this problem of mine. I am really anticipating your answers.
I have tried following the documentation but I am still getting the same error. I have searched everywhere online and stackoverflow, but none seems to provide the solution to my problem.
here is the code
private val AUTHORIZATION_PARAM = "Authorization"
private val BEARER_VAL = "Bearer "
private val CONTENT_TYPE_PARAM = "Content-Type: "
private val LINE_FEED = "\r\n"
private val APP_FOLDER_ID = "appDataFolder"
fun connectAndStartOperation() {
if (mAuthCode == null) {
signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestProfile()
.requestScopes(Scope(Scopes.DRIVE_APPFOLDER))
.requestIdToken(resources.getString(R.string.gdrive_clientId))
.requestServerAuthCode(resources.getString(R.string.gdrive_clientId))
.build()
mGoogleSignInClient = GoogleSignIn.getClient(this, signInOptions!!)
startActivityForResult(mGoogleSignInClient?.signInIntent, CLOUD_STORAGE)
Log.i("mAuthCode", "false")
} else {
Log.i("mAuthCode", "true")
writeDbToDrive()
mNextGoogleApiOperation = INVALID;
}
}
fun disconnect() {
mGoogleSignInClient?.signOut()
mActivity = null
mNextGoogleApiOperation = INVALID
mAuthCode = null
mAccessToken = null
mTokenExpired = 0
}
override fun onDestroy() {
disconnect()
super.onDestroy()
}
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == CLOUD_STORAGE) {
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
.addOnSuccessListener(this)
.addOnFailureListener(this)
}
}
override fun onSuccess(googleSignInAccount: GoogleSignInAccount?) {
Log.i("mAuthCode", "Success")
val scope = "oauth2:https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.profile"
idTokenString = googleSignInAccount?.idToken
mAuthCode = googleSignInAccount?.serverAuthCode
mGoogleSignInAccount = googleSignInAccount
doAsync {
try {
mAccessToken = GoogleAuthUtil.getToken(this#SettingsActivity, mGoogleSignInAccount?.account, scope)
} catch (e: Exception) {
Log.i("Error AccessToken", "${e.message}")
e.printStackTrace()
}
uiThread {
Log.i("AccessTokenMy", "$mAccessToken")
}
}
}
override fun onFailure(p0: java.lang.Exception) {
Log.i("mAuthCode", "Failed")
p0.printStackTrace()
}
private fun writeDbToDrive() {
var conn: HttpURLConnection? = null
var os: OutputStream? = null
val accessToken = requestAccessToken(mGoogleSignInAccount!!)
if (accessToken == null)
return
try {
val boundary = "pb" + System.currentTimeMillis()
val url = URL("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart")
conn = url.openConnection() as HttpURLConnection
conn.requestMethod = "POST"
conn.useCaches = false
conn.doOutput = true
conn.doInput = true
conn.connectTimeout = 5000
conn.setRequestProperty(AUTHORIZATION_PARAM, BEARER_VAL + accessToken!!)
conn.setRequestProperty("Content-Type", "multipart/related; boundary=$boundary")
Log.i("Action", "Parameter set for server")
/////// Prepare data
//val timestamp = SimpleDateFormat("yyyy-MM-dd_HH:mm:ss", Locale.getDefault()).format(Date())
// Prepare file metadata (Change your backup file name here)
val b = StringBuilder()
b.append('{')
.append("\"name\":\"").append(exportedFileName).append('\"')
.append(',')
.append("\"mimeType\":").append("\"text\\/csv\"")
.append(',') //"\"application\\/vnd.google-apps.unknown\""
.append("\"parents\":").append("[\"").append(APP_FOLDER_ID).append("\"]")
.append('}')
val metadata = b.toString()
val data = readFile(File(filePath))
/////// Calculate body length
var bodyLength = 0
// MetaData part
b.setLength(0)
b.append("--").append(boundary).append(LINE_FEED)
b.append(CONTENT_TYPE_PARAM).append("application/json; charset=UTF-8")
.append(LINE_FEED)
b.append(LINE_FEED)
b.append(metadata).append(LINE_FEED)
b.append(LINE_FEED)
b.append("--").append(boundary).append(LINE_FEED)
b.append(CONTENT_TYPE_PARAM).append("text/csv").append(LINE_FEED)
b.append(LINE_FEED)
val beforeFilePart = b.toString().toByteArray(charset("UTF_8"))
bodyLength += beforeFilePart.size
bodyLength += data.size // File
b.setLength(0)
b.append(LINE_FEED)
b.append("--").append(boundary).append("--")
val afterFilePart = b.toString().toByteArray(charset("UTF_8"))
bodyLength += afterFilePart.size
conn.setRequestProperty("Content-Length", bodyLength.toString())
//if (BuildConfig.DEBUG_MODE) DebugHelper.log("LENGTH", bodyLength)
/////// Write to socket
os = conn.outputStream
try {
os!!.write(beforeFilePart)
os!!.write(data)
os!!.write(afterFilePart)
os!!.flush()
} catch (e: Exception) {
e.printStackTrace()
}
val msg = conn.responseMessage
val code = conn.responseCode
if (code == 200) {
Log.i("writeDbToDrive", "Exported Successfully: $code $msg")
} else {
Log.i("writeDbToDrive", "Error: $code $msg")
}
} catch (e: Exception) {
e.printStackTrace()
Log.i("writeDbToDrive", e.message!!)
} finally {
if (os != null) {
try {
os!!.close()
} catch (e: IOException) {
}
}
conn?.disconnect()
}
}
#Throws(IOException::class)
private fun readFile(file: File): ByteArray {
val f = RandomAccessFile(file, "r")
try {
val longlength = f.length()
val length = longlength.toInt()
if (length.toLong() != longlength)
throw IOException("File size >= 10 Mb")
val data = ByteArray(length)
f.readFully(data)
return data
} finally {
f.close()
}
}
private fun requestAccessToken(mGoogleSignInAccount: GoogleSignInAccount): String? {
val scope = "oauth2:https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.profile"
doAsync {
try {
mAccessToken = GoogleAuthUtil.getToken(this#SettingsActivity, mGoogleSignInAccount?.account, scope)
} catch (e: Exception) {
Log.i("Error AccessToken", "${e.message}")
e.printStackTrace()
}
uiThread {
Log.i("AccessTokenMy", "$mAccessToken")
}
}
return mAccessToken
}
After reading through this Files: create Documentation, I have finally fixed the problem. Unknown to me is that the files where being saved in the AppData folder created by my app. The AppData folder is hidden which can only be accessible by and through my app. For me to be able to save the file to My Drive folder, I removed the part of the metadata
` .append(',')
.append("\"parents\":").append("[\"").append(APP_FOLDER_ID).append("\"]")`
So the metadata part is now like this
val b = StringBuilder()
b.append('{')
.append("\"name\":\"").append(exportedFileName).append('\"')
.append(',')
.append("\"mimeType\":").append("\"text\\/csv\"")
.append('}')
val metadata = b.toString()
Every other thing remains the same