#android #android-recyclerview #android-billing
Вопрос:
первый раз, когда я использую billingclient, но у меня проблема, консоль выдает мне ошибку: RecyclerView BillingClient: адаптер не подключен; пропуск макета, и иногда он загружает RecyclerView, а иногда нет, то есть я ввожу действие, и иногда оно загружает его, и много раз оно не загружается.
Я оставляю код эксперту, который будет направлять меня, и я могу помочь себе понять, где у меня есть ошибка
suscripcion.java
private BillingClient billingClient; private AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener; private RecyclerView recyclerView_sub; private DocumentReference documentReference; private FirebaseFirestore mFirestore; private FirebaseUser user; private FirebaseAuth fAuth; private String userID; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_suscripcion); mFirestore = FirebaseFirestore.getInstance(); fAuth = FirebaseAuth.getInstance(); user = fAuth.getCurrentUser(); if (user !=null) { userID = fAuth.getCurrentUser().getUid(); } documentReference = mFirestore.collection("users").document(userID); setupSubClient(); iniciador(); txtclose = findViewById(R.id.txtclosesub); txtclose.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); startActivity(new Intent(suscripcion.this, MainActivity.class)); } }); } private void iniciador() { statuspremium = findViewById(R.id.statuspremium); rangopremium = findViewById(R.id.rangopremium); recyclerView_sub = findViewById(R.id.recyclerview_sub); recyclerView_sub.setHasFixedSize(true); LinearLayoutManager layoutManager = new LinearLayoutManager(this); recyclerView_sub.setLayoutManager(layoutManager); recyclerView_sub.addItemDecoration(new DividerItemDecoration(this, layoutManager.getOrientation())); } private void loadAllSubPackage() { if (billingClient.isReady()) { SkuDetailsParams params = SkuDetailsParams.newBuilder() .setSkusList(Arrays.asList("vf_sub_unmes", "vf_sub_tresmes")) .setType(BillingClient.SkuType.SUBS) .build(); billingClient.querySkuDetailsAsync(params, new SkuDetailsResponseListener() { @Override public void onSkuDetailsResponse(@NonNull BillingResult billingResult, @Nullable Listlt;SkuDetailsgt; list) { if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { MySubAdapter adapter = new MySubAdapter(suscripcion.this, list, billingClient); recyclerView_sub.setAdapter(adapter); }else { Log.d("ERROR", "onSkuDetailsResponse: " billingResult.getResponseCode()); } } }); }else { Log.d("ERROR", "loadAllSubPackage: Billing cliente not ready" ); } } private void setupSubClient() { acknowledgePurchaseResponseListener = new AcknowledgePurchaseResponseListener() { @Override public void onAcknowledgePurchaseResponse(@NonNull BillingResult billingResult) { if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { Log.d("ERROR", "onAcknowledgePurchaseResponse: " billingResult.getResponseCode()); // rangopremium.setVisibility(View.VISIBLE); // tiemposub.setVisibility(View.VISIBLE); } } }; billingClient = BillingClientSetup.getInstance(this, this); billingClient.startConnection(new BillingClientStateListener() { @Override public void onBillingServiceDisconnected() { Log.d("ERROR", "onBillingServiceDisconnected: " ); } @Override public void onBillingSetupFinished(@NonNull BillingResult billingResult) { if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { Log.d("ERROR", "onBillingSetupFinished: " billingResult.getResponseCode()); // //Query // Listlt;Purchasegt; purchases = billingClient.queryPurchases(BillingClient.SkuType.SUBS) // .getPurchasesList(); billingClient.queryPurchasesAsync(BillingClient.SkuType.SUBS, new PurchasesResponseListener() { @Override public void onQueryPurchasesResponse(@NonNull BillingResult billingResult, @NonNull Listlt;Purchasegt; list) { if (list.size() gt; 0) { for (Purchase purchase:list) handleSubAlreadyPurchase(purchase); Log.d("ERROR", "onBillingSetupFinished: " billingResult.getResponseCode()); }else { loadAllSubPackage(); documentReference.update("premium", "no"); documentReference.update("status", "user"); statuspremium.setVisibility(View.VISIBLE); Log.d("ERROR", "onBillingSetupFinished: " billingResult.getResponseCode()); // rangopremium.setVisibility(View.GONE); // tiemposub.setVisibility(View.GONE); // statuspremium.setVisibility(View.VISIBLE); // recyclerView_sub.setVisibility(View.VISIBLE); } } }); } else { Log.d("ERROR", "onBillingSetupFinished: " billingResult.getResponseCode()); } } }); } private void handleSubAlreadyPurchase(Purchase purchases) { if (purchases.getPurchaseState() == Purchase.PurchaseState.PURCHASED) { rangopremium.setVisibility(View.VISIBLE); Log.d("ERROR", "handleSubAlreadyPurchase: "); if (!purchases.isAcknowledged()) { Log.d("ERROR", "handleSubAlreadyPurchase: "); AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchases.getPurchaseToken()) .build(); billingClient.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener); }else { Log.d("ERROR", "handleSubAlreadyPurchase: "); } } if (purchases.getPurchaseState() == Purchase.PurchaseState.UNSPECIFIED_STATE){ Log.d("ERROR", "handleSubAlreadyPurchase: "); } } @Override public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable Listlt;Purchasegt; list) { if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK amp;amp; list !=null) { rangopremium.setVisibility(View.VISIBLE); statuspremium.setVisibility(View.GONE); recyclerView_sub.setVisibility(View.GONE); documentReference.update("premium", "si"); documentReference.update("status", "Vinorrero"); Log.d("ERROR", "onPurchasesUpdated: " billingResult.getResponseCode()); for (Purchase purchase:list) handleSubAlreadyPurchase(purchase); }else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) { Log.d("ERROR", "onPurchasesUpdated: " billingResult.getResponseCode()); rangopremium.setVisibility(View.GONE); statuspremium.setVisibility(View.VISIBLE); recyclerView_sub.setVisibility(View.VISIBLE); documentReference.update("premium", "no"); documentReference.update("status", "user"); }else { Log.d("ERROR", "onPurchasesUpdated: " billingResult.getResponseCode()); } }
MySubAdapter.java
public class MySubAdapter extends RecyclerView.Adapterlt;MySubAdapter.MyViewHoldergt; { AppCompatActivity appCompatActivity; Listlt;SkuDetailsgt; skuDetailsList; BillingClient billingClient; public MySubAdapter(AppCompatActivity appCompatActivity, Listlt;SkuDetailsgt; skuDetailsList, BillingClient billingClient) { this.appCompatActivity = appCompatActivity; this.skuDetailsList = skuDetailsList; this.billingClient = billingClient; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new MyViewHolder(LayoutInflater.from(appCompatActivity.getBaseContext()) .inflate(R.layout.listado_sub, parent, false)); } @Override public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { holder.txt_sub_name.setText(skuDetailsList.get(position).getTitle()); holder.txt_precio_sub.setText(skuDetailsList.get(position).getPrice()); holder.setListener(new IReciclerClickListener() { @Override public void onClick(View view, int position) { BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setSkuDetails(skuDetailsList.get(position)) .build(); int reponse = billingClient.launchBillingFlow(appCompatActivity, billingFlowParams) .getResponseCode(); switch(reponse) { case BillingClient.BillingResponseCode.BILLING_UNAVAILABLE: Log.d("ERROR11", "BILLING_UNAVAILABLE"); break; case BillingClient.BillingResponseCode.DEVELOPER_ERROR: Log.d("ERROR12", "DEVELOPER_ERROR"); break; case BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED: Log.d("ERROR13", "FEATURE_NOT_SUPPORTED"); break; case BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED: Log.d("ERROR14", "ITEM_ALREADY_OWNED"); break; case BillingClient.BillingResponseCode.SERVICE_DISCONNECTED: Log.d("ERROR15", "SERVICE_DISCONNECTED"); break; case BillingClient.BillingResponseCode.SERVICE_TIMEOUT: Log.d("ERROR16", "SERVICE_TIMEOUT"); break; case BillingClient.BillingResponseCode.ITEM_UNAVAILABLE: Log.d("ERROR17", "ITEM_UNAVAILABLE"); break; default: break; } } }); } @Override public int getItemCount() { return skuDetailsList.size(); } public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { TextView txt_sub_name, txt_precio_sub; IReciclerClickListener listener; public void setListener(IReciclerClickListener listener) { this.listener = listener; } public MyViewHolder(@NonNull View itemView) { super(itemView); txt_sub_name = itemView.findViewById(R.id.txt_sub_name); txt_precio_sub = itemView.findViewById(R.id.txt_precio_sub); itemView.setOnClickListener(this); } @Override public void onClick(View v) { listener.onClick(v, getAdapterPosition()); } }
listado_sub.xml
lt;?xml version="1.0" encoding="utf-8"?gt; lt;com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@ id/card_sub" android:layout_width="match_parent" android:layout_height="wrap_content" card_view:cardBackgroundColor="@android:color/transparent" card_view:cardElevation="0dp" android:theme="@style/Theme.MaterialComponents.Light" android:layout_margin="8dp"gt; lt;LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginEnd="10dp" android:layout_marginStart="10dp" android:orientation="vertical"gt; lt;LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:background="@drawable/btn_desing" android:padding="16dp"gt; lt;TextView android:id="@ id/txt_sub_name" android:text="Titulo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:textColor="@color/colorPrimary" android:textSize="16sp"/gt; lt;TextView android:id="@ id/txt_precio_sub" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_gravity="center" android:text="Precio" android:textAppearance="?attr/textAppearanceBody2" android:textColor="?android:attr/textColorSecondary"/gt; lt;/LinearLayoutgt; lt;/LinearLayoutgt; lt;/com.google.android.material.card.MaterialCardViewgt;
Activity_suscripcion.xlm
lt;?xml version="1.0" encoding="utf-8"?gt; lt;LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@ id/Snackbar_apoyo" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/fondocurva" android:orientation="vertical" android:layout_gravity="center" android:gravity="center"gt; lt;TextView android:id="@ id/txtclosesub" android:layout_width="30dp" android:layout_height="30dp" android:layout_gravity="end" android:layout_marginBottom="20dp" android:layout_marginEnd="20dp" android:layout_marginTop="20dp" android:background="@drawable/circulo" android:gravity="center" android:text="@string/equis" android:textColor="@android:color/background_light" android:textStyle="bold" /gt; lt;androidx.core.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent"gt; lt;LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"gt; lt;androidx.appcompat.widget.AppCompatTextView android:id="@ id/statuspremium" style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="start" android:gravity="center" android:shadowColor="@color/negro" android:shadowDx="2" android:shadowDy="5" android:visibility="gone" android:shadowRadius="10" android:text="@string/no_premium" android:textColor="@color/colorAccent" android:textSize="25sp" android:textStyle="bold|italic" /gt; lt;com.hanks.htextview.rainbow.RainbowTextView android:id="@ id/rangopremium" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:visibility="gone" android:textSize="25sp" android:textStyle="bold" android:text="PREMIUM" app:colorSpace="150dp" app:colorSpeed="10dp"/gt; lt;ImageView android:contentDescription="@string/app_name" android:layout_width="200dp" android:layout_height="200dp" android:src="@drawable/vinoayuda"/gt; lt;TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/haste_premium" android:textSize="18sp" android:textColor="@color/colorAccent" android:layout_gravity="center" android:gravity="center" android:paddingLeft="20dp" android:paddingRight="20dp" android:layout_marginBottom="20dp" android:textStyle="bold" android:fontFamily="sans-serif-smallcaps" android:shadowColor="@color/negro" android:shadowRadius="10" android:shadowDx="2" android:shadowDy="5"/gt; lt;TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/usuario_premium_garantizamos" android:textSize="14sp" android:textColor="@color/blanco" android:layout_gravity="center" android:gravity="center" android:paddingLeft="20dp" android:paddingRight="20dp" android:layout_marginBottom="20dp" android:textStyle="bold" android:fontFamily="sans-serif-smallcaps" app:drawableLeftCompat="@drawable/ic_baseline_error_24" /gt; lt;androidx.recyclerview.widget.RecyclerView android:id="@ id/recyclerview_sub" android:layout_width="match_parent" android:layout_height="0dp" android:visibility="visible" android:layout_weight="1" android:layout_marginBottom="20dp"gt; lt;/androidx.recyclerview.widget.RecyclerViewgt; lt;/LinearLayoutgt; lt;/androidx.core.widget.NestedScrollViewgt; lt;/LinearLayoutgt;
Комментарии:
1. попробуйте один раз инициализировать экземпляр адаптера и задать данные при получении обратного вызова.
2. Здравствуйте, спасибо за ответ, не могли бы вы рассказать мне немного больше, я новичок в этом, Спасибо за помощь