когда мой GPS активирован, мое приложение работает, но когда GPS деактивирован, он показывает мне ошибку sgt:
Как мне решить проблему?
Ошибка:
E / AndroidRuntime: FATAL EXCEPTION: main Процесс: com.yech.tusuper, PID: 29424 io.reactivex.exceptions.UndeliverableException: исключение не может быть доставлено потребителю, поскольку оно уже отменило / удалило поток или Исключению некуда go для начала. Дополнительная информация: https://github.com/ReactiveX/RxJava/wiki/What 's-different-in-2.0 # обработка ошибок | kotlin .UninitializedPropertyAccessException: свойство lateinit currentLocation не было инициализировано в io.reactivex.plugins.RxJavaPlugins.onError (RxJavaPlugins. java: 367) в io.reactivex. android .schedulecheunler . java: 126) в android .os.Handler.handleCallback (Обработчик. java: 739) в android .os.Handler.dispatchMessage (Обработчик. java: 95) в android. os.Looper.l oop (Looper. java: 148) в android .app.ActivityThread.main (ActivityThread. java: 7325) в java .lang.reflect.Method.invoke (Native Method) в com. android .internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit. java: 1230) в com. android .internal.os.ZygoteInit.main (ZygoteInit. java: 1120) Причина: kotlin .UninitializedPropertyAccessException: свойство lateinit currentLocation не было инициализировано в com.yech.tusuper.ui.cart.CartFragment.access $ getCurrentLocation $ p (CartFragment.kt: 76) в com.yech.tusuper.ui. cart.CartFragment $ paymentCOD $ 1 $ 1.onSuccess (CartFragment.kt: 402) на ком. yech.tusuper.ui.cart.CartFragment $ paymentCOD $ 1 $ 1.onSuccess (CartFragment.kt: 389) в io.reactivex.internal.operators.single.SingleObserveOn $ ObserveOnSingleObserver.run (SingleObserveOn. java: 81) в io. реактивный. android .schedulers.HandlerScheduler $ ScheduledRunnable.run (HandlerScheduler. java: 124) в android .os.Handler.handleCallback (Обработчик. java: 739) в android .os.Handler. dispatchMessage (Handler. java: 95) в android .os.Looper.l oop (Looper. java: 148) в android .app.ActivityThread.main (ActivityThread. java: 7325 ) в java .lang.reflect.Method.invoke (собственный метод) в com. android .internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit. java: 1230) в com. android .internal .os.ZygoteInit.main (ZygoteInit. java: 1120)
Códi go:
CartFragment.kt
класс CartFragment: Fragment (), ILoadTimeFromFirebaseCallback {
override fun onLoadTimeSuccess(order: OrderModel, estimatedTimeMs: Long) {
order.createDate = (estimatedTimeMs)
order.orderStatus = 0
writeOrderToFirebase(order)
}
override fun onLoadTimeFailed(message: String) {
Toast.makeText(context!!,message,Toast.LENGTH_SHORT).show()
}
private var placeSelected: Place?=null
private var places_fragment: AutocompleteSupportFragment?=null
private lateinit var placeClient: PlacesClient
private val placeFields = Arrays.asList(
Place.Field.ID,
Place.Field.NAME,
Place.Field.ADDRESS,
Place.Field.LAT_LNG)
private val REQUEST_BRAINTREE_CODE: Int=8888
private var cartDataSource:CartDataSource?=null
private var compositeDisposable:CompositeDisposable = CompositeDisposable()
private var recyclerViewState:Parcelable?=null
private lateinit var cartViewModel: CartViewModel
private lateinit var btn_place_order:Button
var txt_empty_cart:TextView?=null
var txt_total_price:TextView?=null
var group_place_holder:CardView?=null
var recycler_cart:RecyclerView?=null
var adapter:MyCartAdapter?=null
private lateinit var locationRequest: LocationRequest
private lateinit var locationCallback: LocationCallback
private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
private lateinit var currentLocation: Location
internal var address:String=""
internal var comment:String=""
lateinit var cloudFunctions: ICloudFunctions
lateinit var ifcmService: IFCMService
lateinit var listener: ILoadTimeFromFirebaseCallback
override fun onResume() {
calculateTotalPrice()
if (fusedLocationProviderClient != null)
fusedLocationProviderClient.requestLocationUpdates(locationRequest,locationCallback,
Looper.getMainLooper())
super.onResume()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
setHasOptionsMenu(true)
EventBus.getDefault().postSticky(HideFABCart(true))
cartViewModel =
ViewModelProviders.of(this).get(CartViewModel::class.java)
//After create cartviewMoedl, init data source
cartViewModel.initCartdataSource(context!!)
val root = inflater.inflate(R.layout.fragment_cart, container, false)
initViews(root)
initLocation()
cartViewModel.getMutableLiveDataCartItem().observe(this, Observer {
if (it == null || it.isEmpty())
{
recycler_cart!!.visibility = View.GONE
group_place_holder!!.visibility = View.GONE
txt_empty_cart!!.visibility = View.VISIBLE
}
else
{
recycler_cart!!.visibility = View.VISIBLE
group_place_holder!!.visibility = View.VISIBLE
txt_empty_cart!!.visibility = View.GONE
adapter = MyCartAdapter(context!!,it)
recycler_cart!!.adapter = adapter
}
})
return root
}
private fun initLocation() {
buildLocationRequest()
buildLocationCallback()
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context!!)
fusedLocationProviderClient!!.requestLocationUpdates(locationRequest, locationCallback,
Looper.getMainLooper())
}
private fun buildLocationCallback() {
locationCallback = object : LocationCallback() {
override fun onLocationResult(p0: LocationResult?) {
super.onLocationResult(p0)
currentLocation = p0!!.lastLocation
}
}
}
private fun buildLocationRequest() {
locationRequest = LocationRequest()
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
locationRequest.setInterval(2000)
locationRequest.setFastestInterval(2000)
locationRequest.setSmallestDisplacement(10f)
}
private fun initViews(root:View) {
initPlacesClient()
setHasOptionsMenu(true) //Important, if not add it, menu will never be inflate
cloudFunctions = RetrofitCloudClient.getInstance().create(ICloudFunctions::class.java)
ifcmService = RetrofitFCMClient.getInstance().create(IFCMService::class.java)
listener = this
cartDataSource = LocalCartDataSource(CartDatabase.getInstance(context!!).cartDAO())
recycler_cart = root.findViewById(R.id.recycler_cart) as RecyclerView
recycler_cart!!.setHasFixedSize(true)
val layoutManager = LinearLayoutManager(context)
recycler_cart!!.layoutManager = layoutManager
recycler_cart!!.addItemDecoration(DividerItemDecoration(context,layoutManager.orientation))
val swipe = object:MySwipeHelper(context!!,recycler_cart!!,200) {
override fun instantiateMyButton(
viewHolder: RecyclerView.ViewHolder,
buffer: MutableList<MyButton>
) {
buffer.add(MyButton(context!!,
"Delete",
30,
0,
Color.parseColor("#FF3C30"),
object:IMyButtonCallback{
override fun onClick(pos: Int) {
val deleteItem = adapter!!.getItemAtPosition(pos)
cartDataSource!!.deleteCart(deleteItem)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : SingleObserver<Int>{
override fun onSuccess(t: Int) {
adapter!!.notifyItemRemoved(pos)
sumCart()
EventBus.getDefault().postSticky(CountCartEvent(true))
Toast.makeText(context,"Delete item success",Toast.LENGTH_SHORT).show()
}
override fun onSubscribe(d: Disposable) {
}
override fun onError(e: Throwable) {
Toast.makeText(context,""+e.message,Toast.LENGTH_SHORT).show()
}
})
}
}))
}
}
txt_empty_cart = root.findViewById(R.id.txt_empty_cart) as TextView
txt_total_price = root.findViewById(R.id.txt_total_price) as TextView
group_place_holder = root.findViewById(R.id.group_place_holder) as CardView
btn_place_order = root.findViewById(R.id.btn_place_order) as Button
//Event
btn_place_order.setOnClickListener {
val builder = AlertDialog.Builder(context!!)
builder.setTitle("Importante!!!")
val view = LayoutInflater.from(context).inflate(R.layout.layout_place_order,null)
// val edt_address = view.findViewById<View>(R.id.edt_address) as EditText
val edt_comment = view.findViewById<View>(R.id.edt_comment) as EditText
val txt_address = view.findViewById<View>(R.id.txt_address_detail) as TextView
val rdi_home = view.findViewById<View>(R.id.rdi_home_addres) as RadioButton
// val rdi_other_address = view.findViewById<View>(R.id.rdi_other_addres) as RadioButton
val rdi_ship_to_this_address = view.findViewById<View>(R.id.rdi_ship_this_addres) as RadioButton
val rdi_cod = view.findViewById<View>(R.id.rdi_cod) as RadioButton
val rdi_braintree = view.findViewById<View>(R.id.rdi_braintree) as RadioButton
places_fragment = activity!!.supportFragmentManager.findFragmentById(R.id.places_autocomplete_fragment)
as AutocompleteSupportFragment
places_fragment!!.setPlaceFields(placeFields)
places_fragment!!.setOnPlaceSelectedListener(object : PlaceSelectionListener {
override fun onPlaceSelected(p0: Place) {
placeSelected = p0
txt_address.text = placeSelected!!.address
}
override fun onError(p0: Status) {
Toast.makeText(context,""+p0.statusMessage,Toast.LENGTH_SHORT).show()
}
})
//Data
txt_address.setText(Common.currentUser!!.address!!) //By default we checked rdi_home
//Event
rdi_home.setOnCheckedChangeListener { compoundButton, b ->
if (b)
{
txt_address.setText(Common.currentUser!!.address!!)
}
}
/* rdi_other_address.setOnCheckedChangeListener { compoundButton, b ->
if (b) {
txt_address.setText("")
}
}*/
rdi_ship_to_this_address.setOnCheckedChangeListener { compoundButton, b ->
if (b) {
fusedLocationProviderClient!!.lastLocation
.addOnFailureListener { e->
txt_address.visibility = View.GONE
Toast.makeText(context!!,""+e.message, Toast.LENGTH_SHORT).show()
}
.addOnCompleteListener { task ->
val coordinates = StringBuilder()
.append(task.result!!.latitude)
.append("/")
.append(task.result!!.longitude)
.toString()
val singleAddress = Single.just(getAddressFromLating(task.result!!.latitude,task.result!!.longitude))
val disposables = singleAddress.subscribeWith(object : DisposableSingleObserver<String>(){
override fun onSuccess(t: String) {
txt_address.setText(t)
}
override fun onError(e: Throwable) {
txt_address.setText(e.message!!)
}
})
}
}
}
builder.setView(view)
builder.setNegativeButton("NO", {dialogInterface, _ -> dialogInterface.dismiss()})
.setPositiveButton("YES",
{dialogInterface, _ ->
if(rdi_cod.isChecked)
paymentCOD(txt_address.text.toString(),edt_comment.text.toString())
else if(rdi_braintree.isChecked)
{
address = txt_address.text.toString()
comment = edt_comment.text.toString()
if(!TextUtils.isEmpty(Common.currentToken))
{
val dropInRequest = DropInRequest().clientToken(Common.currentToken)
startActivityForResult(dropInRequest.getIntent(context),REQUEST_BRAINTREE_CODE)
}
}
})
val dialog = builder.create()
dialog.show()
}
}
private fun initPlacesClient() {
Places.initialize(context!!,getString(R.string.google_maps_key))
placeClient = Places.createClient(context!!)
}
private fun paymentCOD(address: String, comment: String) {
compositeDisposable.add(cartDataSource!!.getAllCart(Common.currentUser!!.uid!!)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe ({ cartItemList ->
//When we have all cartItems, we will get total price
cartDataSource!!.sumPrice(Common.currentUser!!.uid!!)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object: SingleObserver<Double>{
override fun onSuccess(totalPrice: Double) {
val finalPrice = totalPrice
val order = OrderModel()
order.userId = Common.currentUser!!.uid!!
order.userName = Common.currentUser!!.name!!
order.userPhone = Common.currentUser!!.phone!!
order.shippingAddress = address
order.comment = comment
if (currentLocation != null)
{
order.lat = currentLocation!!.latitude
order.lng = currentLocation!!.longitude
}
order.cartItemList = cartItemList
order.totalPayment = totalPrice
order.finalPayment = finalPrice
order.discount = 0
order.isCod = true
order.transactionId = "Cash On Delivery"
//Submit to Firebase
syncLocalTimeWithServerTime(order)
}
override fun onSubscribe(e: Disposable) {
}
override fun onError(e: Throwable) {
if (!e.message!!.contains("Query returned empty"))
Toast.makeText(context,"[SUM CART]"+e.message,Toast.LENGTH_SHORT).show()
}
})
},{ throwable -> Toast.makeText(context!!,""+throwable.message,Toast.LENGTH_SHORT).show() }))
}
private fun writeOrderToFirebase(order: OrderModel) {
FirebaseDatabase.getInstance()
.getReference(Common.ORDER_REF)
.child(Common.createOrderNumber())
.setValue(order)
.addOnFailureListener { e -> Toast.makeText(context!!,""+e.message,Toast.LENGTH_SHORT).show() }
.addOnCompleteListener { task ->
//Clean cart
if (task.isSuccessful)
{
cartDataSource!!.cleanCart(Common.currentUser!!.uid!!)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe (object:SingleObserver<Int>{
override fun onSuccess(t: Int) {
val dataSend = HashMap<String,String>()
dataSend.put(Common.NOTI_TITLE,"Nueva Orden")
dataSend.put(Common.NOTI_CONTENT,"Tienes un pedido de: "+Common.currentUser!!.phone)
val sendData = FCMSendData(Common.getNewOrderTopic(),dataSend)
compositeDisposable.add(
ifcmService.sendNotification(sendData)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({t: FCMResponse? ->
// if (t!!.success != 0)
MotionToast.darkColorToast(
context!! as Activity,"Gracias por su compra",
MotionToast.TOAST_SUCCESS,
MotionToast.GRAVITY_BOTTOM,
MotionToast.LONG_DURATION,
ResourcesCompat.getFont(context!!,R.font.helvetica_regular))
//Toast.makeText(context!!,"Gracias por su Compra",Toast.LENGTH_SHORT).show()
},{t: Throwable? ->
Toast.makeText(context!!,"Order was sent but notification failed",Toast.LENGTH_SHORT).show()
}))
}
override fun onSubscribe(d: Disposable) {
}
override fun onError(e: Throwable) {
Toast.makeText(context!!,""+e.message,Toast.LENGTH_SHORT).show()
}
} )
}
}
}
private fun getAddressFromLating(latitude: Double, longitude: Double): String {
val geoCoder =Geocoder(context!!, Locale.getDefault())
var result:String?=null
try {
val addressList = geoCoder.getFromLocation(latitude,longitude,1)
if (addressList != null && addressList.size >0)
{
val address = addressList[0]
val sb = StringBuilder(address.getAddressLine(0))
result = sb.toString()
}
else
result = "Address not found!"
return result
}catch (e:IOException)
{
return e.message!!
}
}
private fun sumCart() {
cartDataSource!!.sumPrice(Common.currentUser!!.uid!!)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object :SingleObserver<Double>{
override fun onSuccess(t: Double) {
txt_total_price!!.text = StringBuilder("Total: S/.")
.append(t)
}
override fun onSubscribe(d: Disposable) {
}
override fun onError(e: Throwable) {
if (!e.message!!.contains("Query returned empty"))
Toast.makeText(context,"[SUM CART]"+e.message,Toast.LENGTH_SHORT).show()
}
})
}
override fun onStart() {
super.onStart()
if (!EventBus.getDefault().isRegistered(this))
EventBus.getDefault().register(this)
}
override fun onStop() {
cartViewModel!!.onStop()
compositeDisposable.clear()
EventBus.getDefault().postSticky(HideFABCart(false))
if (EventBus.getDefault().isRegistered(this))
EventBus.getDefault().unregister(this)
//if (fusedLocationProviderClient != null) //1° Depurar
fusedLocationProviderClient.removeLocationUpdates(locationCallback)
super.onStop()
}
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
fun onUpdateItemInCart(event: UpdateItemInCart){
if (event.cartItem != null)
{
recyclerViewState = recycler_cart!!.layoutManager!!.onSaveInstanceState()
cartDataSource!!.updateCart(event.cartItem)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object: SingleObserver<Int>{
override fun onSuccess(t: Int) {
calculateTotalPrice();
recycler_cart!!.layoutManager!!.onRestoreInstanceState(recyclerViewState)
}
override fun onSubscribe(d: Disposable) {
}
override fun onError(e: Throwable) {
Toast.makeText(context,"[UPDATE CART]"+e.message,Toast.LENGTH_SHORT).show()
}
})
}
}
private fun calculateTotalPrice() {
cartDataSource!!.sumPrice(Common.currentUser!!.uid!!)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object:SingleObserver<Double>{
override fun onSuccess(price: Double) {
txt_total_price!!.text = StringBuilder("Total: S/")
.append(Common.formatPrice(price))
}
override fun onSubscribe(d: Disposable) {
}
override fun onError(e: Throwable) {
if (!e.message!!.contains("Query returned empty"))
Toast.makeText(context,"[SUM CART]"+e.message,Toast.LENGTH_SHORT).show()
}
})
}
override fun onPrepareOptionsMenu(menu: Menu) {
//menu!!.findItem(R.id.action_settings).setVisible(false)//Hide setting menu when in Cart
super.onPrepareOptionsMenu(menu)
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater!!.inflate(R.menu.cart_menu,menu)
super.onCreateOptionsMenu(menu, inflater)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_BRAINTREE_CODE)
{
if (resultCode == Activity.RESULT_OK)
{
val result = data!!.getParcelableExtra<DropInResult>(DropInResult.EXTRA_DROP_IN_RESULT)
val nonce = result!!.paymentMethodNonce
//Calculate sum Cart
cartDataSource!!.sumPrice(Common.currentUser!!.uid!!)
.subscribeOn(Schedulers.io())
.subscribe(object:SingleObserver<Double>{
override fun onSuccess(totalPrice: Double) {
//Get all item to create Cart
compositeDisposable.add(
cartDataSource!!.getAllCart(Common.currentUser!!.uid!!)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({cartItems: List<CartItem>? ->
//After have all cart item, we will submit
val headers = HashMap<String,String>()
headers.put("Authorization",Common.buildToken(Common.authorizeToken!!))
compositeDisposable.add(cloudFunctions.submitPayment(
headers,
totalPrice,
nonce!!.nonce)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({braintreeTransaction ->
if (braintreeTransaction.success)
{
//Create Order
val finalPrice = totalPrice
val order = OrderModel()
order.userId = Common.currentUser!!.uid!!
order.userName = Common.currentUser!!.name!!
order.userPhone = Common.currentUser!!.phone!!
order.shippingAddress = address
order.comment = comment
if (currentLocation != null)
{
order.lat = currentLocation!!.latitude
order.lng = currentLocation!!.longitude
}
order.cartItemList = cartItems
order.totalPayment = totalPrice
order.finalPayment = finalPrice
order.discount = 0
order.isCod = false
order.transactionId = braintreeTransaction.transaction!!.id
//Submit to Firebase
syncLocalTimeWithServerTime(order)
}
},
{t: Throwable? ->
Toast.makeText(context,""+t!!.message,Toast.LENGTH_SHORT).show()
})
)
},
{t: Throwable? ->
Toast.makeText(context,""+t!!.message,Toast.LENGTH_SHORT).show()
})
)
}
override fun onSubscribe(d: Disposable) {
}
override fun onError(e: Throwable) {
if (!e.message!!.contains("Query returned empty"))
Toast.makeText(context,"[SUM CART]"+e.message,Toast.LENGTH_SHORT).show()
}
})
}
}
}
override fun onDestroy() {
EventBus.getDefault().postSticky(MenuItemBack())
super.onDestroy()
}
}