AudioTrack in android - java

I have application that is send audio track to another client by server this metho is create a buffer from microphone and sent to webSocket in the backend
I want to reverse the method to play the audio in the other client phone
Backend is django and client side is android all i need is a method to convert bytes to audio stream in the other client side something like a phonecall but only one side is streaming audio
method owner : https://blog.canopas.com/android-send-live-audio-stream-from-client-to-server-using-websocket-and-okhttp-client-ecc9f28118d9
import android.Manifest
import android.content.pm.PackageManager
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import okhttp3.*
import okio.ByteString.Companion.toByteString
import java.util.concurrent.TimeUnit
private const val RECORDER_SAMPLERATE = 44100
private val RECORDER_CHANNELS: Int = AudioFormat.CHANNEL_IN_STEREO
private val RECORDER_AUDIO_ENCODING: Int = AudioFormat.ENCODING_PCM_16BIT
private var webSocket: WebSocket? = null
private var audioRecord: AudioRecord? = null
val BUFFER_SIZE_RECORDING = AudioRecord.getMinBufferSize(
RECORDER_SAMPLERATE,
RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING
) * 4
var client: OkHttpClient? = null
var request: Request = Request.Builder().url("ws://192.168.1.3:8000/ws/chat/15/").build()
class SoundDjango : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sound_django)
client = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build()
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.RECORD_AUDIO
) != PackageManager.PERMISSION_GRANTED
) {
return
}
audioRecord = AudioRecord(
MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE, RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING, BUFFER_SIZE_RECORDING
)
audioRecord?.startRecording()
initWebSocket()
record()
}
fun initWebSocket() {
webSocket = client?.newWebSocket(request, object : WebSocketListener() {
override fun onOpen(webSocket: WebSocket, response: Response) {
super.onOpen(webSocket, response)
}
override fun onMessage(webSocket: WebSocket, text: String) {
super.onMessage(webSocket, text)
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
super.onFailure(webSocket, t, response)
}
})
}
private fun record()
{
val buf = ByteArray(BUFFER_SIZE_RECORDING)
GlobalScope.launch {
try {
do {
val byteRead = audioRecord?.read(buf,0, buf.size)?: break
if (byteRead < -1)
break
var toSend = buf.toByteString(0, byteRead)
webSocket?.send(buf.toByteString(0, byteRead))
webSocket?.send("{\"message\": \"" + toSend + "\"}")
} while (true)
} catch (e: Exception) {
stop()
}
}
}
fun stop() {
webSocket?.cancel()
audioRecord?.stop()
audioRecord?.release()
audioRecord = null
}
}
Output in backend like this :
{"message": "[size=28416 hex=04001c00fdff130002001c0005001b0000001f00ffff1800fbff1700fcff2200ffff280000002d00fcff2400f4ff1c00f6ff1400f7ff1900f5ff1f00fbff1d00…]"}
{"message": "[size=28416 hex=e5ffdfffe4ffd2ffe4ffd8ffeaffe4fff0ffe5ffebffe3ffe9ffdbffe3ffcdffe8ffccfff5ffd9fff5ffe1ffeaffe8ffe7ffe1ffe9ffd7fff2ffd2fff2ffdbff…]"}
{"message": "[size=28416 hex=12001a00100015000a001f000b001f0009002200080018000d001a0008001b000b0018000e002600110027000c002c000600220009001c000f00250006003000…]"}
{"message": "[size=28416 hex=faff0d00fcff0b00f8ff0e00f9ff1000f9ff0e00faff0e00f8ff1500f6ff0d00f4ff0f00f1ff0f00f2ff0a00f3ff0800f0ff1100f5ff1100f7ff1200f8ff1400…]"}

Related

RetryPolicy does not work with coroutines

I made a simple gRPC server in Kotlin with coroutines and a client with Java. In the cliente I enabled and configured a retry policy, but it does was not work. I speend a lot of time to find a solution, belivied that my client was broken, but the problem it was in the server. I will show you the code.
This is my proto file:
syntax = "proto3";
option java_multiple_files = true;
option java_package = "br.com.will.protoclasses";
option java_outer_classname = "NotificationProto";
package notification;
service Notification {
rpc SendPush (SendPushNotificationRequest) returns (SendPushNotificationResponse);
}
message SendPushNotificationRequest {
string title = 1;
string message = 2;
string customer_id = 3;
}
message SendPushNotificationResponse {
string message = 1;
}
This is the client:
open class NotificationClient(private val channel: ManagedChannel) {
private val stub: NotificationGrpcKt.NotificationCoroutineStub =
NotificationGrpcKt.NotificationCoroutineStub(channel)
suspend fun send() {
val request =
SendPushNotificationRequest.newBuilder().setCustomerId(UUID.randomUUID().toString()).setMessage("test")
.setTitle("test").build()
val response = stub.sendPush(request)
println("Received: ${response.message}")
}
}
suspend fun main(args: Array<String>) {
val port = System.getenv("PORT")?.toInt() ?: 50051
val retryPolicy: MutableMap<String, Any> = HashMap()
retryPolicy["maxAttempts"] = 5.0
retryPolicy["initialBackoff"] = "10s"
retryPolicy["maxBackoff"] = "30s"
retryPolicy["backoffMultiplier"] = 2.0
retryPolicy["retryableStatusCodes"] = listOf<Any>("INTERNAL")
val methodConfig: MutableMap<String, Any> = HashMap()
val name: MutableMap<String, Any> = HashMap()
name["service"] = "notification.Notification"
name["method"] = "SendPush"
methodConfig["name"] = listOf<Any>(name)
methodConfig["retryPolicy"] = retryPolicy
val serviceConfig: MutableMap<String, Any> = HashMap()
serviceConfig["methodConfig"] = listOf<Any>(methodConfig)
print(serviceConfig)
val channel = ManagedChannelBuilder.forAddress("localhost", port)
.usePlaintext()
.defaultServiceConfig(serviceConfig)
.enableRetry()
.build()
val client = NotificationClient(channel)
client.send()
}
This is a part of my gRPC service, where i was testing the retry policy (the retry policy on client does not work with this implementation):
override suspend fun sendPush(request: SendPushNotificationRequest): SendPushNotificationResponse {
val count: Int = retryCounter.incrementAndGet()
log.info("Received a call on method sendPushNotification with payload -> $request")
if (random.nextFloat() < UNAVAILABLE_PERCENTAGE) {
log.info("Returning stubbed INTERNAL error. count: $count")
throw Status.INTERNAL.withDescription("error").asRuntimeException()
}
log.info("Returning successful Hello response, count: $count")
return SendPushNotificationResponse.newBuilder().setMessage("success").build()
}
Another implementation, but now using StreamObserver (This implementation works fine):
override fun sendPush(
request: SendPushNotificationRequest?,
responseObserver: StreamObserver<SendPushNotificationResponse>?
) {
log.info("Received a call on method sendPushNotification with payload -> $request")
val count: Int = retryCounter.incrementAndGet()
if (random.nextFloat() < UNAVAILABLE_PERCENTAGE) {
log.info("Returning stubbed UNAVAILABLE error. count: $count")
responseObserver!!.onError(
Status.UNAVAILABLE.withDescription("error").asRuntimeException()
)
} else {
log.info("Returning successful Hello response, count: $count")
responseObserver!!.onNext(SendPushNotificationResponse.newBuilder().setMessage("success").build())
return responseObserver.onCompleted()
}
}
The question is, whats is wrong? Can someone help me?
Does this code is generated by gRPC:
sendPush(request: SendPushNotificationRequest): SendPushNotificationResponse
gRPC depends on StreamObserver to send response to client after call responseObserver.onCompleted() or responseObserver.onError, please make sure your code could be work correctly.

Retrofit Post on Android kotlin not working but working on postman

I am trying to Hit the API using the Retrofit Post method to put the form data but the problem is that the API returns null all the time even if I try to pass the params. I tested the API by running it in Postman it works fine and I also added internet permission and set usesCleartextTraffic to true under manifest.xml, so it would be really helpful if anyone guides me to rectify this issue.
Output When I tried to debugg
call = Unresolved reference: call
response = Unresolved reference: response
this = {MainActivity#9661}
params = {HashMap#10022} size = 5
"password" -> "Ram#123"
"countryCode" -> {Integer#10042} 91
"name" -> "Ranjith"
"mobile" -> {Long#10046} 99********
"emailID" -> "var***#gmail.com"
Response back from the API with body null all the time
response = {Response#10220} "Response{protocol=http/1.1, code=400, message=Bad Request, url=http://*.***.***.***:***0/api/v1/****/auth/register}"
body = null
errorBody = {ResponseBody$1#10224}
content = {Buffer#10228} "[text={"code":400,"error":true,"msg":"Enter a valid name"}]"
contentLength = 52
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
uploadBt.setOnClickListener {
callApi()
}
}
private fun callApi() {
val params = HashMap<String?, Any?>()
params["name"] = "Ranjith"
params["mobile"] = 99*******
params["emailID"] = "var***#gmail.com"
params["password"] = "Ram#123"
params["countryCode"] = 91
RetrofitClient.instance.registerUser(params)
.enqueue(object : Callback<DefaultResponse>{
override fun onResponse(call: Call<DefaultResponse>, response: Response<DefaultResponse>) {
print(response)
if(response.isSuccessful)
{
Toast.makeText(applicationContext, response.body()?.msg, Toast.LENGTH_SHORT).show()
}else
{
var jsonObject: JSONObject? = null
try {
jsonObject = JSONObject(response.errorBody()!!.string())
val code = jsonObject.getString("code")
val error = jsonObject.getString("error")
val message = jsonObject.getString("msg")
Toast.makeText(applicationContext, message+"\n"+code+"\n"+error, Toast.LENGTH_LONG).show()
} catch (e: JSONException) {
Toast.makeText(applicationContext, e.toString(), Toast.LENGTH_LONG).show()
e.printStackTrace()
}
}
}
override fun onFailure(call: Call<DefaultResponse>, t: Throwable) {
Toast.makeText(applicationContext, t.toString(), Toast.LENGTH_SHORT).show()
}
})
}
}
Interface Api
interface Api {
#FormUrlEncoded
#POST("/api/v1/******/****/register")
fun registerUser(
#FieldMap params: HashMap<String?, Any?>
): Call<DefaultResponse>
}
RetrofitClient.kt object class
object RetrofitClient {
private const val BASE_URL = "http://3.1**.**5.1*1:****"
private val okHttpClient = OkHttpClient.Builder()
.addInterceptor { chain ->
val original = chain.request()
val requestBuilder = original.newBuilder()
.method(original.method(), original.body())
val request = requestBuilder.build()
chain.proceed(request)
}.build()
val instance: Api by lazy{
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build()
retrofit.create(Api::class.java)
}
}
DefaultResponse.kt model data class
data class DefaultResponse(
#SerializedName("code")
val code: Int,
#SerializedName("err")
val error: Boolean,
#SerializedName("msg")
val msg: String
)
Through Postman

How to send json object as post request in CRONET?

I am developing android application in which i send data to server using cronet now i want to send data to server in json object but not know how to send in object?
Following is my snippet code for GET method (WORKING).
Can anyone share how to use POST Method in android cronet ?
Dependencies
implementation 'org.chromium.net:cronet-embedded:71.3578.98'
MainActivity
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import org.chromium.net.CronetEngine
import java.util.concurrent.Executors
class MainActivity : AppCompatActivity() {
companion object {
// Web page url
private const val JSON_PLACEHOLDER_API_URL = "https://jsonplaceholder.typicode.com/todos/1"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Build a Cronet engine
val cronetEngine =
CronetEngine.Builder(this)
.enableBrotli(true)
.build()
// Build the request
val request =
cronetEngine.newUrlRequestBuilder(
JSON_PLACEHOLDER_API_URL,
RequestCallback(),
Executors.newSingleThreadExecutor()
).build()
// Start the request
request.start()
}
}
RequestCallback
import android.util.Log
import org.chromium.net.CronetException
import org.chromium.net.UrlRequest
import org.chromium.net.UrlResponseInfo
import java.nio.ByteBuffer
import java.nio.charset.Charset
/**
* Different methods are invoked for different response status
*/
class RequestCallback : UrlRequest.Callback() {
companion object {
// Log cat tag
private val TAG = RequestCallback::class.java.simpleName
}
override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?) {
Log.i(TAG, "Response Started")
val statusCode = info?.httpStatusCode
Log.i(TAG, "Status Code $statusCode")
if (statusCode == 200) {
// Read the buffer
request?.read(ByteBuffer.allocateDirect(32 * 1024))
}
}
override fun onReadCompleted(request: UrlRequest?, info: UrlResponseInfo?, byteBuffer: ByteBuffer?) {
Log.i(TAG, "Response Completed")
// Flip the buffer
byteBuffer?.flip()
// Convert the byte buffer to a string
byteBuffer?.let {
val byteArray = ByteArray(it.remaining())
it.get(byteArray)
String(byteArray, Charset.forName("UTF-8"))
}.apply {
Log.d(TAG, "Response: $this")
}
// Clear the buffer
byteBuffer?.clear()
// Read the buffer
request?.read(byteBuffer)
}
override fun onFailed(request: UrlRequest?, info: UrlResponseInfo?, error: CronetException?) {
Log.e(TAG, "Response Failed: ${error?.message}")
}
override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
Log.i(TAG, "Response Succeeded")
}
override fun onRedirectReceived(request: UrlRequest?, info: UrlResponseInfo?, newLocationUrl: String?) {
Log.i(TAG, "Response Redirect to $newLocationUrl")
request?.followRedirect()
}
override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
super.onCanceled(request, info)
Log.i(TAG, "Response cancelled")
}
}
Output
Response: {
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
Example:
val myBuilder = CronetEngine.Builder(context)
// Enable caching of HTTP data and
// other information like QUIC server information, HTTP/2 protocol and QUIC protocol.
val cronetEngine: CronetEngine = myBuilder
.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024.toLong())
.enableHttp2(true)
.enableQuic(true)
.build()
val executor: Executor = Executors.newSingleThreadExecutor()
val requestBuilder = cronetEngine.newUrlRequestBuilder(
"FULL-URL",
MyUrlRequestCallback(),
executor
)
// Content-Type is required, removing it will cause Exception
requestBuilder.addHeader("Content-Type","application/json; charset=UTF-8")
requestBuilder.setHttpMethod("POST")
val myUploadDataProvider = MyUploadDataProvider()
requestBuilder.setUploadDataProvider(myUploadDataProvider,executor)
val request: UrlRequest = requestBuilder.build()
request.start()
MyUploadDataProvider Class:
import android.util.Log
import org.chromium.net.UploadDataProvider
import org.chromium.net.UploadDataSink
import java.lang.Exception
import java.nio.ByteBuffer
import java.nio.charset.StandardCharsets
private const val TAG = "MyUploadDataProvider"
//TODO replace username and passowrd "_user & _pass"
var string: String ="{\"username\":\"_user\",\"password\":\"_pass\"}"
val charset = StandardCharsets.UTF_8
class MyUploadDataProvider() : UploadDataProvider() {
override fun getLength(): Long {
val size:Long = string.length.toLong()
Log.e(TAG,"Length = "+size)
return size
}
override fun rewind(uploadDataSink: UploadDataSink?) {
Log.e(TAG,"REWIND IS CALLED")
uploadDataSink!!.onRewindSucceeded()
}
override fun read(uploadDataSink: UploadDataSink?, byteBuffer: ByteBuffer?) {
Log.e(TAG,"READ IS CALLED")
byteBuffer!!.put(string.toByteArray(charset))
//byteBuffer.rewind()
//For chunked uploads, true if this is the final read. It must be false for non-chunked uploads.
uploadDataSink!!.onReadSucceeded(false)
}
}

OkHttp EventListener : byteCount value is always zero in responseBodyEnd callback

I am using EventListener callback for some analysis in my app but I am facing an issue where I am not getting the correct value byteCount in responseBodyEnd callback. It is always 0.
I am attaching the code below.
val client = OkHttpClient.Builder()
.eventListenerFactory(HttpEventListenerFactory.FACTORY)
.build()
val request = Request.Builder()
.url("http://jsonplaceholder.typicode.com/comments?postId=1")
.build()
with(client) {
newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
Log.d("OkHttp##", "Request failed")
}
override fun onResponse(call: Call, response: Response) {
handleResponse(response.body())
response.close()
Log.d("OkHttp##", "Response received")
}
})
}
MyEventListenerImpl.kt
public class HttpEventListenerFactory extends EventListener {
public static final Factory FACTORY = new Factory() {
final AtomicLong nextCallId = new AtomicLong(1L);
#Override
public EventListener create(Call call) {
long callId = nextCallId.getAndIncrement();
Log.d("OkHttp##", "next call id : " + nextCallId);
String message = String.format(Locale.US, "%04d %s%n", callId, call.request().url());
Log.d("OkHttp##", message);
return new HttpEventListenerFactory(callId, System.nanoTime());
}
};
#Override
public void responseBodyEnd(Call call, long byteCount) {
// this method never gets called
// byteCount here is always 0
printEvent("Response body end", callId);
}

How to use Retrofit2

I called my service with AsyncTask and DefaultHttpClient before but now i want to use Retrofit. I read about this and implement that and onResponse method called but my response has Bad Request Message and can't get body of response.
My error is:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.retrofitsample.f.retrofitsample/com.retrofitsample.f.retrofitsample.MainActivity}: java.lang.IllegalArgumentException: Unable to create converter for com.retrofitsample.f.retrofitsample.model.HttpResponse<com.retrofitsample.f.retrofitsample.model.MS>
Caused by: java.lang.IllegalArgumentException: class com.retrofitsample.f.retrofitsample.model.MS declares multiple JSON fields named Id
I have a wcf service like below :
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest,
UriTemplate = "GetMS")]
HttpResponse<MS> GetMS(string token,string Id);
I have a HttpResponse and all of my services return a type of T.. I write belo code in client side:
MyActivity:
retrofit2.Call<HttpResponse<MS>> call=service.getAllMonitoringScheduale("971048F6-7ABA-4060-8CC3-BC57EC259FA3","1292");
call.enqueue(new Callback<HttpResponse<MS>>() {
#Override
public void onResponse(retrofit2.Call<HttpResponse<MS>> call, Response<HttpResponse<MS>> response) {
Log.e("Response=",response.body().getResultMessage());
}
#Override
public void onFailure(retrofit2.Call<HttpResponse<MS>> call, Throwable t) {
Toast.makeText(MainActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
});
My Interface:
public interface GetDataService {
#POST("GetMonitoringSchedule")
Call<HttpResponse<MS>> getAllMS(#Query("token")String token,#Query("Id") String Id);
}
and this is my models Class:
public class HttpResponse<T> {
#SerializedName("ResultMessage")
private String ResultMessage;
#SerializedName("Result")
private T Result;
public HttpResponse(String ResultMessage,T Result){
this.ResultMessage=ResultMessage;
this.Result=Result;
}
public String getResultMessage(){
return ResultMessage;
}
public void setResultMessage(String ResultMessage){
this.ResultMessage=ResultMessage;
}
public T getResult(){
return Result;
}
public void setResult(T Result){
this.Result=Result;
}
}
public class MS {
#SerializedName("Id")
public long Id;
#SerializedName("PId")
public long PId;
#SerializedName("SType")
public int SType;
#SerializedName("SDateF")
public Date SDateF ;
#SerializedName("SDateT")
public Date SDateT;
..Constructor and setter and getter
}
How to fix this errors and what is my problem?
I don't know how to use HttpResponse type in Retrofit2?
I have found a project that uses Retrofit in order to make network requests.
You can use it as a reference in order to understand how to use Retrofit.
https://github.com/AcademyTLV/fundamentals-2018-exercise/tree/ex-7-networking
Also be sure to use a POJO In order to create your classes to handle the request:
http://www.jsonschema2pojo.org/
Here i have fully example for it.
This dependancy add in gradle
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
annotationProcessor 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
Here now create ApiClient.kt file
object ApiClient {
val BASE_URL = "http://yourwebsite/services/"
private var retrofit: Retrofit? = null
val client: Retrofit
get() {
if (retrofit == null) {
retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
return retrofit!!
}
}
Now create APIInterface.kt
#FormUrlEncoded
#POST("users/login")
fun POST_LOGIN(
#Field("imei_number") imei_number: String,
#Field("device_token") device_token: String,
#Field("mobile") mobile: String,
#Field("password") password: String
): Call<LoginResponse>
#GET("general/init-data")
fun GENERAL_MODULE(
#Header("Authorization") auth_key: String
): Call<InitResponse>
#GET("event-gallery/list")
fun GET_Event_GALLERY(
#Header("Authorization") auth_key: String
): Call<EventListResponse>
#GET("event-gallery/photo-list")
fun GET_Event_GALLERY_PHOTO(
#Header("Authorization") auth_key: String,
#Query("id") id: Int
): Call<EventGallerListResponse>
if Any Header for token the use #Header and also When call #GET that time params use #Query and #Post that time #Fields
Now Response file
data class EventListResponse(
#SerializedName("success")
var success: Boolean,
#SerializedName("data")
var data: EventgalleryModel?,
#SerializedName("server_error"),
#SerializedName("eventgallery")
var eventgallery: ArrayList<EventListData>
var server_error: Boolean,
#SerializedName("message")
var message: String
)
Then create Model class of Response
Now time to Activity code
private fun loadData() {
card_progress.visibility = View.VISIBLE
val apiService = ApiClient.client.create(ApiInterface::class.java)
val call =
apiService.GET_FEE_INSTALMENT_LIST(PreferenceManager.getAuthKey(this#FeesInstalmentActivity)!!)
call.enqueue(object : Callback<FeeInstalmentListResponse> {
override fun onResponse(
call: Call<FeeInstalmentListResponse>,
response: Response<FeeInstalmentListResponse>
) {
card_progress.visibility = View.GONE
val data = response.body()!!.data
if (response.code() == 200 && data != null) {
if (response.body()!!.server_error) {
txt_no_data_fee.visibility = View.VISIBLE
txt_no_data_fee.text = response.body()!!.message
} else {
Log.e("data", data.toString())
if (data != null && data.feesinstalment.isEmpty()) {
txt_no_data_fee.visibility = View.VISIBLE
} else {
txt_no_data_fee.visibility = View.GONE
adapter!!.setItem(data.feesinstalment)
}
}
} else if (response.code() == 401) {
PreferenceManager.removePref(this#FeesInstalmentActivity)
startActivity(
Intent(this#FeesInstalmentActivity, LoginActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
)
finish()
} else {
Toast.makeText(
this#FeesInstalmentActivity,
R.string.somethingWrong,
Toast.LENGTH_SHORT
).show()
}
}
override fun onFailure(call: Call<FeeInstalmentListResponse>, t: Throwable) {
card_progress.visibility = View.GONE
Log.e("onFailure", t.message)
txt_no_data_fee.visibility = View.VISIBLE
}
})
}
Sry i forget Adapter here
class FeeInstalmentAdapter(
private val context: Context,
private var items: ArrayList<FeeInstalmentListData>
) : RecyclerView.Adapter() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(context).inflate(R.layout.row_fees_instalment_item, parent, false))
}
#SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.due_date.text = DateHelper.parseData(items[position].due_date!!, "yyyy-MM-dd", "dd MMM yyyy")
holder.instalment_title.text = items[position].instalment_title
if (items[position].paid_date == null) {
holder.paid_text.visibility = View.GONE
holder.paid_date.text = context.resources.getString(R.string.UnPaid)
holder.paid_date.setTextColor(Color.parseColor("#DC143C"))
} else {
holder.paid_date.text = DateHelper.parseData(items[position].due_date!!, "yyyy-MM-dd", "dd MMM yyyy")
holder.paid_date.setTextColor(Color.parseColor("#58A259"))
}
//holder.paid_date.text = items[position].paid_date
holder.amount.text = "Rs. " + items[position].amount
holder.amount.setTextColor(Color.parseColor("#ED7136"))
}
override fun getItemCount(): Int {
return items.size
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItemViewType(position: Int): Int {
return position
}
fun setItem(holidays: ArrayList<FeeInstalmentListData>) {
items = holidays
notifyDataSetChanged()
}
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val due_date = view.due_date
val instalment_title = view.instalment_title
val paid_date = view.paid_date
val amount = view.amount
val paid_text = view.paidText
}
}

Categories

Resources