My project requires to save user cards and I used Stripe for that,
as per stripe's official documentation I have to use their prebuilt CardInputWidget .
Now I have some design requirements that are not matching with this Widget even after changing its theme or style.
So I am looking for any other way to save stripe card using simple edittext or create custom Card object of Stripe?
Here's the code
implementation 'com.stripe:stripe-android:14.5.0'
Fragment code
stripe = new Stripe(getActivity(), myApp.getStripePublishKey());
PaymentMethodCreateParams params = card_multiline_widget.getPaymentMethodCreateParams();
if (params == null) {
ToastUtils.makeToast(getActivity(), "Invalid Details");
return;
}
stripe.createPaymentMethod(params, new ApiResultCallback<PaymentMethod>() {
#Override
public void onSuccess(#NonNull PaymentMethod result) {
if (getActivity() != null) {
getActivity().runOnUiThread(() -> progressDialog.dismiss());
}
paymentMethodId = result.id;
LogUtils.e(paymentMethodId);
saveCard();
// Send paymentMethodId to your server for the next steps
}
#Override
public void onError(#NonNull Exception e) {
// Display the error to the user
e.printStackTrace();
LogUtils.e(e.getMessage());
if (getActivity() != null) {
getActivity().runOnUiThread(() -> progressDialog.dismiss());
}
}
});
Short
I think it's not good practice to use your own input. Prefer Stripe's one.
Explanations
Google could reject the app because of security failure.
If you use a text field for card input, you can see the card number before sending it to stripe. So you can save the full card info, in log file or else where, before getting the Stripe token.
You can do this without bad intention, but be careful if someone found it...
Related
Our android app is a chat app. Users can paste a branch link in a chat message. When another user taps on it, we want to retrieve the link parameters to take the user to another screen.
Unfortunately, we are unable to retrieve the link parameters when we tap on such link inside the app (note that we are not using a webview), we are getting the error "Warning. Session initialisation already happened.
To force a new session, set intent extra, branch_force_new_session, to true in the onInitFinished(#Nullable JSONObject referringParams, #Nullable BranchError error) method.
How can we solve this? It's not obvious to me how I could pass a new intent param in that use case.
Notes:
Our launcher activity is singleTask
We are on branch.io sdk 4.3.2
onNewIntent() does not seem to be called (in the code below), maybe that is the root cause for our issue.
sample code:
private Branch.BranchReferralInitListener branchReferralInitListener =
new Branch.BranchReferralInitListener() {
#Override
public void onInitFinished(#Nullable JSONObject referringParams, #Nullable BranchError error) {
...
}
#Override
protected void onStart() {
super.onStart();
Branch.getInstance().initSession(branchReferralInitListener, getIntent() != null ?
getIntent().getData() : null, this);
}
#Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
this.setIntent(intent);
// activity will skip onStart, handle this case with reInitSession
Branch.getInstance().reInitSession(this, branchReferralInitListener);
}
This is a known issue with the Android SDK v4.3.2 and we are working on a resolution.
Would suggest you to try the following in the meanwhile:
When the user tries to open an app that is running in the background, we get an error for set branch_force_new_session to true.
Branch SDK gets initialised on onStart for the Launcher Activity and when the app comes foreground from the background, its on onResume.
In this scenario, we could need to re-initialise the SDK here.
Would request you to implement the below snippet as per Branch docs (https://docs.branch.io/apps/android/#initialize-branch)
// activity will skip onStart, handle this case with reInitSession
Branch.getInstance().reInitSession(this, branchReferralInitListener);
Alternatively, would suggest you to install Branch SDK v4.3.1.
Initialized, you branch IO in application class so that it will initialize once and will not be require again
// Branch logging for debugging
Branch.enableLogging();
//Disable Device ID #2966
Branch.disableDeviceIDFetch(true);
// Initialize the Branch object
BranchIOManager.setupBranchInstance(this);
// It tells the Branch initialization to wait for the Google Play Referrer before proceeding.
Branch.enablePlayStoreReferrer(1000L);
Then inside initSession() branch method use. Pass them as JSON Object to method where you can retrieve the value based on key names.
if (branch != null && uri != null) {
branch.initSession(new Branch.BranchUniversalReferralInitListener() {
#Override
public void onInitFinished(BranchUniversalObject branchUniversalObject, LinkProperties linkProperties, BranchError error) {
// Log.d("onInitFinished", error + "");
if (error == null && branchUniversalObject != null) {
JSONObject jBranch = branchUniversalObject.getContentMetadata().convertToJson();
if (!branchJSONString.equals(jBranch.toString())) {
//This check is applied as if we launch another mLandingScreenPhoneActivity from Branch link then app will become in loop
branchJSONString = jBranch.toString();
loadScreenFromBranchIODynamicLink(jBranch, 0);
}
}
if (error != null) {
// //Toast.makeText(LandingScreenPhoneActivity.this, error + "", Toast.LENGTH_SHORT).show();
}
}
}, uri, this);
}
Here you can get screen values
String screenName = referringParams.optString("screen_key");
//Screen in app where needs to navigate
int screenIndex = referringParams.optInt("screen_index");
Last week I started learning Android as I needed to create an application for one of the projects at Uni.
The application is a simple barcode/QRcode scanner and it should scan the code, compare its result with the database (I'm using Firebase) and either return other data from database if the barcode is found or ask the user if he wants to add the barcode to the database if it's not found.
I thought the easiest way to do it would be to use AlertDialog, but the app crashes every single time I scan the code.
I debugged the app and checked the Logcat, what I get is:
You need to use a Theme.AppCompat theme (or descendant) with this activity.
This is exactly where I get the error and where I wanted to use AlertDialog - based on the value in the variable details.
private BarcodeCallback callback = new BarcodeCallback() {
#Override
public void barcodeResult(final BarcodeResult result) {
barcodeView.decodeSingle(callback);
dbRef.child("Items").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Iterator<DataSnapshot> item = dataSnapshot.getChildren().iterator();
Boolean isFound = false;
while (!isFound || item == null) {
DataSnapshot i = item.next();
String check = i.child("ID").getValue().toString();
if (result.getText().equals(check)) {
isFound = true;
details = "Consumption: " + i.child("Consumption").getValue().toString()
+ "\nCost: " + i.child("Cost").getValue().toString()
+ "\nName: " + i.child("Name").getValue().toString();
} else {
details = "Not found";
}
}
new AlertDialog.Builder(getApplicationContext())
.setMessage("This is just an example for the purpose of the question.")
.create()
.show();
}
I get the error exactly on the line with .show();.
In the previous posts I found that you can't display AlertDialog in this place, and you need to use runOnUiThread function or Handler, none of those options worked for me, and I was getting the error in the same place.
Do you guys have any advice or suggestions?
Also, I'm sorry for the way this post looks like or for any missing but required information. I know it's not an excuse, but this is my first post here.
Thanks in advance for any replies.
The problem is here:
new AlertDialog.Builder(getApplicationContext())
You can't build a Dialog using the application context. To reach this you need an Activity Context.
Read this question or this article for further understanding
I am attempting to create a real-time communication capability for a Phonegap/Cordova app. I am using SignalR 2 to handle the communication.
The thing I am struggling with is getting a message to a particular user. Every single example out there shows saving Context.User.Identity.Name, which is useless to me because the remote site's User.Identity context is not shared by my phonegap app.
In essence, I am not authenticating a user in the traditional sense, so I need another way of linking the SignalR connectionID with the username I pass along.
Taken from the official ASP.NET signalr Examples, I have the following code which overrides the OnConnected event. Unfortunately it takes no parameters and expects User.Identity to be not null:
public override Task OnConnected()
{
using (var db = new UserContext())
{
// Retrieve user.
var user = db.Users
.Include(u => u.Rooms)
.SingleOrDefault(u => u.UserName == Context.User.Identity.Name);
// If user does not exist in database, must add.
if (user == null)
{
user = new User()
{
UserName = Context.User.Identity.Name
};
db.Users.Add(user);
db.SaveChanges();
}
else
{
// Add to each assigned group.
foreach (var item in user.Rooms)
{
Groups.Add(Context.ConnectionId, item.RoomName);
}
}
}
return base.OnConnected();
}
Now, maybe what I'd need is to have a version of this method that takes a string as a parameter and then I'd use that as my user identifier.
But how to go about that?
You need to create a new IUserIdProvider for the user and use dependency injection to register your provider and use it.
public interface IUserIdProvider
{
string GetUserId(IRequest request);
}
Register your provider with Global Host
GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => new MyIdProvider());
Usage:
public class MyHub : Hub
{
public void Send(string userId, string message)
{
Clients.User(userId).send(message);
}
}
Taken from: http://www.asp.net/signalr/overview/guide-to-the-api/mapping-users-to-connections#IUserIdProvider
I would like to integrate Braintree API into my android application.I referred to Braintree page and I got an idea for how we can integrate it into application. But I have an issue when I want to display Drop-In UI below of my currently showing activity's layout. But in demo it will start new activity BraintreePaymentActivity.java.
I don't want to open new activity I just want to show the same operation in my activity. For that I refer Card-form demo and added my custom button for Purchase.And on Purchase button click I call below code. But here I don't understand from where I can get Nonce value?
Braintree.setup ( this, CLIENT_TOKEN_FROM_SERVER, new Braintree.BraintreeSetupFinishedListener () {
#Override
public void onBraintreeSetupFinished ( boolean setupSuccessful, Braintree braintree, String errorMessage, Exception exception ) {
if ( setupSuccessful ) {
// braintree is now setup and available for use
} else {
// Braintree could not be initialized, check errors and try again
// This is usually a result of a network connectivity error
}
}} );
If anyone has any idea about that then please suggest here.
I am stuck with Braintree API.
Thanks in advance.
You are correct that your use case does not fit for the Drop-in UI.
In order to add a PaymentMethodNonce listener, once Braintree is setup, simply call Braintree.addListener and supply a Braintree.PaymentMethodNonceListener implementation. I've included an example below. You can also refer to the client side integration section in the Credit Cards guide in Braintree's documentation.
Braintree.setup (this, CLIENT_TOKEN_FROM_SERVER, new Braintree.BraintreeSetupFinishedListener () {
#Override
public void onBraintreeSetupFinished ( boolean setupSuccessful, Braintree braintree, String errorMessage, Exception exception) {
if (setupSuccessful) {
// braintree is now setup and available for use
braintree.addListener(new Braintree.PaymentMethodNonceListener() {
public void onPaymentMethodNonce(String paymentMethodNonce) {
// Communicate the nonce to your server
}
});
} else {
// Braintree could not be initialized, check errors and try again
// This is usually a result of a network connectivity error
}
}
});
I'm using Parse.com in my Android app. I'm making a collaborative shopping list which allows the user to mark items for deletion (they turn grey), but they only get actually deleted when I press the Sync button (and there's a network available). Currently, the objects are erased from parse database but not from the local datastore. I'm trying this:
ParseQuery<ShoppingItem> queryDeletes = ShoppingItem.getQuery();
queryDeletes.fromPin(MyApplication.ALL_ITEMS);
queryDeletes.whereEqualTo("isDeleted", true);
queryDeletes.findInBackground(new FindCallback<ShoppingItem>() {
#Override
public void done(final List<ShoppingItem> items, ParseException e) {
if (e == null) {
ShoppingItem.deleteAllInBackground(items, new DeleteCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
ShoppingItem.unpinAllInBackground(items, new DeleteCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
if (!isFinishing()) {
shoppingListAdapter.loadObjects(); // update the list view
}
}
}
});
}
}
});
}
}
});
}
Already tried clearing app data and overriding equals() in ShoppingItem with no success. Any ideas?
Thanks!
Ok, so I solved it. From what I understood, what I was trying to do is not possible using the parse library.
First of all, deleteAllInBackground() also unpins objects, so the unpinAllInBackground() is not needed.
The problem is that I was pinning the objects using item.pin(MyApplication.ALL_ITEMS), thus the only way to unpin them is by passing the pin name using item.unpinInBackground(MyApplication.ALL_ITEMS). However, the batch version does not allow to pass as argument both a collection of items AND the pin name. Thus, it isn't possible to batch unpin items with a named pin.
I ended up unpinning the objects individually passing the pin name. The big complain I have is that doing item.unpinInBackground() without the pin name does not throw an exception and thus I was not aware what the problem was.