2016-04-08 10 views
-1

Ich benutze braintree api, um Karte in App für Zahlungen zu bekommen. Es funktioniert Bußgelder und manchmal stürzt zufällig,BraintreeHttpClient.setBaseUrl (java.lang.String) auf eine Null-Objekt Referenz

Das ist mein stacktrace,

E/AndroidRuntime: FATAL EXCEPTION: Thread-833 
                  Process: cl.tempclick, PID: 29509 
                  java.lang.NullPointerException: Attempt to invoke virtual method 'com.braintreepayments.api.internal.HttpClient com.braintreepayments.api.internal.BraintreeHttpClient.setBaseUrl(java.lang.String)' on a null object reference 
                   at com.braintreepayments.api.BraintreeFragment.setConfiguration(BraintreeFragment.java:488) 
                   at com.braintreepayments.api.BraintreeFragment$5.onConfigurationFetched(BraintreeFragment.java:415) 
                   at com.braintreepayments.api.ConfigurationManager.getConfiguration(ConfigurationManager.java:46) 
                   at com.braintreepayments.api.BraintreeFragment.fetchConfiguration(BraintreeFragment.java:412) 
                   at com.braintreepayments.api.BraintreeFragment.waitForConfiguration(BraintreeFragment.java:458) 
                   at com.braintreepayments.api.TokenizationClient.tokenize(TokenizationClient.java:72) 
                   at com.braintreepayments.api.Card.tokenize(Card.java:29) 
                   at cl.tk.ui.activities.sub_activity.AddPayment$UIThreadHandler$1.run(AddPayment.java:364) 
                   at java.lang.Thread.run(Thread.java:818) 

Dies ist mein Code für die Aktivität,

package cl.tk.ui.activities.sub_activity; 

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.support.v4.content.ContextCompat; 
import android.support.v4.content.LocalBroadcastManager; 
import android.support.v7.app.AppCompatActivity; 
import android.view.MotionEvent; 
import android.view.View; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.TextView; 

import com.braintreepayments.api.BraintreeFragment; 
import com.braintreepayments.api.exceptions.InvalidArgumentException; 
import com.braintreepayments.api.interfaces.PaymentMethodNonceCreatedListener; 
import com.braintreepayments.api.models.CardBuilder; 
import com.braintreepayments.api.models.PaymentMethodNonce; 

import cl.tk.R; 
import cl.tk.controllers.constants.Constants; 
import cl.tk.controllers.constants.Enums_String; 
import cl.tk.controllers.listeners.ProcessedResult; 
import cl.tk.controllers.rest_api.RetrofitAdapters; 
import cl.tk.ui.activities.Register; 
import cl.tk.ui.fragments.dialog.DTDialog; 
import cl.tk.ui.iBAPViews.editext.pattern.PatternedEditText; 
import cl.tk.utility.CreditCard; 
import cl.tk.utility.CustomException; 
import cl.tek.utility.GeneralFunctions; 
import cl.tk.utility.MonthYearPicker; 
import cl.tk.utility.Validation; 
import cl.tk.utility.fonts.FontsManager; 
import retrofit.Callback; 
import retrofit.RetrofitError; 
import retrofit.client.Response; 


public class AddPayment extends AppCompatActivity implements  View.OnClickListener,View.OnTouchListener, ProcessedResult,PaymentMethodNonceCreatedListener 
{ 
private Handler uiThreadHandler; 
private TextView tvExpiryDate; 
//private EditText edCvv,ed_cardHOlderName,edZip; 
private PatternedEditText edCardNumber; 
private MonthYearPicker myp; 
private String mClientToken=null; 
private CreditCard creditCard =null; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_add_payment); 

    uiThreadHandler = new UIThreadHandler(); 
    initialze(); 

    downloadBraintreeTOken(); 
} 

private void downloadBraintreeTOken() 
{ 
    RetrofitAdapters.get().getBraintreeToken(new Callback<Response>() { 
     @Override 
     public void success(Response response, Response response2) { 
      parseResult(response); 
     } 

     @Override 
     public void failure(RetrofitError error) { 
      uiThreadHandler.sendEmptyMessage(Constants.ActivityBasicsCode.HIDEDIALOG); 
      Message message = uiThreadHandler.obtainMessage(Constants.ActivityBasicsCode.SHOWTOAST); 
      message.obj = error.getLocalizedMessage(); 
      uiThreadHandler.sendMessage(message); 
     } 
    }); 
} 

private void initialze() 
{ 
    GeneralFunctions.setToolbarMsgIconHide(this, Constants.ToolbarConstants.PAYMENTS, true); 

    Button buttonAdd=GeneralFunctions.findViewByIdAndCast(this,R.id.payment_bt_addCard); 
    buttonAdd.setOnClickListener(this); 
    GeneralFunctions.setColorSelector(ContextCompat.getColor(this, R.color.color175), ContextCompat.getColor(this, R.color.color1A9), buttonAdd); 

    TextView tv_defult=GeneralFunctions.findViewByIdAndCast(this,R.id.payment_ct_default); 
    tv_defult.setOnClickListener(this); 

    FontsManager.initFormAssets(this, Enums_String.FontsNameLato.SEMIBOLD.toString()); 
    FontsManager.changeFonts(tv_defult); 

    edCardNumber=GeneralFunctions.findViewByIdAndCast(this,R.id.payment_ed_cardNumber); 
    tvExpiryDate=GeneralFunctions.findViewByIdAndCast(this,R.id.payment_tv_expiryDate); 
    tvExpiryDate.setOnTouchListener(this); 

    myp = new MonthYearPicker(this); 
    myp.build(new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      tvExpiryDate.setText(myp.getSelectedMonth() + 1 + "/" + myp.getSelectedYear()); 
     } 
    }, null); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    IntentFilter filter = new IntentFilter(Enums_String.LocalReceiver.INTERENT.toString()); 
    LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, filter); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver); 
} 

@Override 
public void onClick(View v) { 
    switch (v.getId()) 
    { 
     case R.id.payment_bt_addCard: 
      uiThreadHandler.sendEmptyMessage(Constants.ActivityBasicsCode.VALIDATION); 
      break; 
    } 
} 

@Override 
public boolean onTouch(View v, MotionEvent event) { 
    if(event.getAction() == MotionEvent.ACTION_UP) 
    { 
     if(v.getId()==R.id.payment_tv_expiryDate) 
     { 
      if(myp.pickerDialog != null && !myp.pickerDialog.isShowing()) 
       myp.pickerDialog.dismiss(); 
      myp.show(); 
     } 
     return true; 
    } 
    return false; 
} 

@Override 
public <IResponse, IMethod, IExtra> void processedResult(IResponse iResponse, IMethod iMethod, IExtra iExtra) { 

} 


@Override 
public <IResponse, IMethod> void processedResult(IResponse iResponse, IMethod iMethod) { 
    switch (iMethod.toString()) 
    { 
     case Constants.CallbackConstants.VIEW_ERROR: { 
      Message message = uiThreadHandler.obtainMessage(Constants.ActivityBasicsCode.SETERROR); 
      message.obj=iResponse; 
      uiThreadHandler.sendMessage(message); 
     } 
     break; 
     case Constants.CallbackConstants.BACK: 
      finish(); 
      break; 
    } 
} 

@Override 
public void onPaymentMethodNonceCreated(final PaymentMethodNonce paymentMethodNonce) { 

} 


private void setError(String errorMsg) { 
    if (errorMsg.equalsIgnoreCase("cardNumber")) 
     GeneralFunctions.setError(null,String.format(getString(R.string.ed_error_invalid),edCardNumber.getTag().toString()),edCardNumber); 
    else if (errorMsg.equalsIgnoreCase("cardDate")) 
     GeneralFunctions.setError(null,String.format(getString(R.string.ed_error_invalid),tvExpiryDate.getTag().toString()),tvExpiryDate); 
} 



private class UIThreadHandler extends Handler { 
    @Override 
    public void handleMessage(Message msg) 
    { 
     switch (msg.what) { 
      case Constants.ActivityBasicsCode.CARDERROR: 
       GeneralFunctions.setError((CustomException)msg.obj,null,null); 
       break; 
      case Constants.ActivityBasicsCode.SETERROR: 
       setError(msg.obj.toString()); 
       break; 
      case Constants.ActivityBasicsCode.SHOWTOAST: 
      { 
       String text=(String)msg.obj; 
       GeneralFunctions.showToast(text,AddPayment.this); 
      } 
      break; 
      case Constants.ActivityBasicsCode.HIDEDIALOG: 
       GeneralFunctions.hideProgressDialog(Constants.DialogConstants.Transparent, AddPayment.this); 
       break; 
      case Constants.ActivityBasicsCode.SHOWDIALOG: 
      { 
       DTDialog dtDialog=DTDialog.newInstance(); 
       GeneralFunctions.showProgressDialog(dtDialog, Constants.DialogConstants.Transparent, AddPayment.this); 
      }break; 
      case Constants.ActivityBasicsCode.VALIDATION: { 
       new Thread(new Runnable() { 
        @Override 
        public void run() 
        { 
         try { 
          if(Validation.validate(AddPayment.this)) { 
           creditCard = new CreditCard(GeneralFunctions.getText(edCardNumber),GeneralFunctions.getText(tvExpiryDate),AddPayment.this); 

           boolean validation = creditCard.validateCard(); 
           if (validation) { 
            if(mClientToken==null) { 
             downloadBraintreeTOken(); 
             Message message = uiThreadHandler.obtainMessage(Constants.ActivityBasicsCode.SHOWTOAST); 
             message.obj = getString(R.string.toast_payment_token); 
             uiThreadHandler.sendMessage(message); 
             return; 
            } 
            BraintreeFragment braintreeFragment= BraintreeFragment.newInstance(AddPayment.this, mClientToken); 

            if(null==braintreeFragment) 
            { 
             Message message = uiThreadHandler.obtainMessage(Constants.ActivityBasicsCode.SHOWTOAST); 
             message.obj = getString(R.string.toast_payment_fragment); 
             uiThreadHandler.sendMessage(message); 
             uiThreadHandler.sendEmptyMessage(Constants.ActivityBasicsCode.SHOWDIALOG); 
            } 
            else { 
             CardBuilder cardBuilder = new CardBuilder() 
               .cardNumber(creditCard.getNumber().replaceAll("-", "").trim()) 
               .expirationDate(creditCard.getExpriyDate()); 
             com.braintreepayments.api.Card.tokenize(braintreeFragment, cardBuilder); //On this line my app crashes randomly 
            } 
           } 
          } 
         }catch (CustomException e) 
         { 
          Message message = uiThreadHandler.obtainMessage(Constants.ActivityBasicsCode.CARDERROR); 
          message.obj=e; 
          uiThreadHandler.sendMessage(message); 
         } catch (InvalidArgumentException e) { 
          e.printStackTrace(); 
         } 
        } 
       }).start(); 
       break; 
      } 
     } 
     super.handleMessage(msg); 
    } 
} 

}

Dies ist meine gradle Version, kompilieren 'com.braintreepayments.api: braintree: 2. +'

Antwort

0

Volle Enthüllung: Ich arbeite für Braintree.

Sind Sie refreshing the client token every time you go through the checkout process as required? Ich sehe, dass Sie nur das Braintree-Token vom Server herunterladen, wenn es null ist.

Ohne einen Einblick in Ihre CreditCard-Klasse oder ihre validateCard-Methode zu haben, kann eine andere Möglichkeit darin bestehen, dass das CardBuilder-Objekt, das Sie in Card.tokenize übergeben, nicht wohlgeformt ist.

Wenn Sie immer noch Probleme haben, wenden Sie sich bitte an Braintree support für Hilfe bei der Fehlersuche bei der Integration.

+0

ja, zuerst lade ich das Braintree-Token vom Server in onCreate() und überprüfe dann noch einmal, ob es null ist, dann versuch nochmal Token zu downloaden .... und die Karte ist wohlgeformt .... wie diese nur stürzt weniger oft ab. – TheReprator

+0

Wir haben das Problem erkannt und einen Fix veröffentlicht. Bitte aktualisiere deine Version des Android v.zero SDK auf 2.2.4. Weitere Informationen finden Sie hier: https://github.com/braintree/braintree_android/issues/89 –

Verwandte Themen