I'm working on a simple app, essentially to send data over Bluetooth.
My MainActivity:
package in.justrobotics.jrbluetoothcontrol;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.InputType;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import me.aflak.bluetooth.Bluetooth;
import me.aflak.bluetooth.BluetoothCallback;
import me.aflak.bluetooth.DiscoveryCallback;
public class MainActivity extends AppCompatActivity {
Bluetooth bluetooth;
private ArrayAdapter<String> mBTArrayAdapter;
String address,name;
public void composeEmail(String message) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("*/*");
intent.putExtra(android.content.Intent.EXTRA_EMAIL,new String[] { "shlokj#gmail.com" });
intent.putExtra(Intent.EXTRA_SUBJECT, "Would like to get in touch");
intent.putExtra(Intent.EXTRA_TEXT, message);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
public void sendEmail () {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Send a message: ");
final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_TEXT);
builder.setView(input);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
final String Message = input.getText().toString();
composeEmail(Message);
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bluetoothOn();
mBTArrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
bluetooth = new Bluetooth(getApplicationContext());
if (bluetooth==null){
Toast.makeText(getApplicationContext(),"Bluetooth null",Toast.LENGTH_SHORT).show();
}
if (bluetooth!=null){
Toast.makeText(getApplicationContext(),"Bluetooth not null",Toast.LENGTH_SHORT).show();
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
for (BluetoothDevice device : pairedDevices)
mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
Button openController = (Button) findViewById(R.id.open_controller);
openController.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent startController = new Intent(MainActivity.this,ControllerActivity.class);
//startController.putExtra("BLUETOOTH_CONNECTED_THREAD",mConnectedThread);
startActivity(startController);
}
});
Button openAccelController = (Button) findViewById(R.id.open_accel_controller);
openAccelController.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent startControllerAccel = new Intent(MainActivity.this,AccelerometerControl.class);
startActivity(startControllerAccel);
}
});
bluetooth.setBluetoothCallback(new BluetoothCallback() {
#Override
public void onBluetoothTurningOn() {
}
#Override
public void onBluetoothOn() {
}
#Override
public void onBluetoothTurningOff() {
}
#Override
public void onBluetoothOff() {
}
#Override
public void onUserDeniedActivation() {
}
});
bluetooth.setDiscoveryCallback(new DiscoveryCallback() {
#Override public void onDiscoveryStarted() {}
#Override public void onDiscoveryFinished() {}
#Override public void onDeviceFound(BluetoothDevice device) {}
#Override public void onDevicePaired(BluetoothDevice device) {}
#Override public void onDeviceUnpaired(BluetoothDevice device) {}
#Override public void onError(String message) {}
});
AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
LayoutInflater inflater = getLayoutInflater();
View convertView = (View) inflater.inflate(R.layout.dialog_btdevices, null);
alertDialog.setView(convertView);
alertDialog.setTitle("Select your device");
alertDialog.setMessage("A JR Bluetooth device name is of the form JR_X");
ListView devicesListView = (ListView) convertView.findViewById(R.id.mDevicesListView);
devicesListView.setAdapter(mBTArrayAdapter);
devicesListView.setOnItemClickListener(mDeviceClickListener);
alertDialog.show();
}
private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
String connectStatus="";
if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
Toast.makeText(getBaseContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
return;
}
//mBluetoothStatus.setText("Connecting...");
// Get the device MAC address, which is the last 17 chars in the View
String info = ((TextView) v).getText().toString();
address = info.substring(info.length() - 17);
Toast.makeText(getBaseContext(), address, Toast.LENGTH_SHORT).show();
name = info.substring(0, info.length() - 17);
if (bluetooth.isConnected()){
connectStatus="Connected";
}
if (!bluetooth.isConnected()){
connectStatus="Not connected";
}
Toast.makeText(getBaseContext(), connectStatus, Toast.LENGTH_SHORT).show();
bluetooth.connectToAddress(address);
Toast.makeText(getBaseContext(), "Connected (hopefully)", Toast.LENGTH_SHORT).show();
bluetooth.send("test");
Toast.makeText(getBaseContext(), "Sent data (hopefully)", Toast.LENGTH_SHORT).show();
}};
#Override
protected void onStart() {
super.onStart();
bluetooth.onStart();
bluetooth.enable();
}
#Override
protected void onStop() {
super.onStop();
bluetooth.onStop();
}
private void bluetoothOn(){
if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
//mBluetoothStatus.setText("Bluetooth enabled");
Toast.makeText(getApplicationContext(),"Bluetooth turned on",Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(),"Bluetooth is already on", Toast.LENGTH_SHORT).show();
}
}
}
Stack traces:
2019-04-09 20:16:48.222 23737-23737/in.justrobotics.jrbluetoothcontrol E/AndroidRuntime: FATAL EXCEPTION: main
Process: in.justrobotics.jrbluetoothcontrol, PID: 23737
java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.OutputStream.write(byte[])' on a null object reference
at me.aflak.bluetooth.Bluetooth.send(Bluetooth.java:185)
at me.aflak.bluetooth.Bluetooth.send(Bluetooth.java:201)
at in.justrobotics.jrbluetoothcontrol.MainActivity$7.onItemClick(MainActivity.java:197)
at android.widget.AdapterView.performItemClick(AdapterView.java:310)
at android.widget.AbsListView.performItemClick(AbsListView.java:1164)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3154)
at android.widget.AbsListView$3.run(AbsListView.java:4097)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6238)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
The custom Bluetooth class: https://github.com/OmarAflak/Bluetooth-Library/blob/master/bluetooth/src/main/java/me/aflak/bluetooth/Bluetooth.java
My code is crashing at the line bluetooth.send("test"); with a NullPointerException, and I can't see why. I'm a beginner with Bluetooth on Android; help will be appreciated.
The final outcome I hope I will be able to get is to simply connect to a device and send data, and even that isn't happening.
Edit: I'm facing another problem as well now. I pass the String address to the second activity (https://gist.github.com/shlokj/12c4e2c62ca0f5284c5c3c041775654f) from the first activity (https://gist.github.com/shlokj/f80d0902ad1a366ab03e178164968cfb) through an intent. There, I try to connect at line 163 (bluetoothObject.connectToAddress(address);), and it crashes with a NullPointerException. I have no idea why, because I check that the Bluetooth object and address are not null with an if statement. Stack traces: https://gist.github.com/shlokj/56e3c9e311dea6f77a1acd8953a317c8 Whole repository: https://github.com/shlokj/JR-Bluetooth-Control.
So, in a nutshell, I now need to be also able to connect properly, leave alone sending data.
I just went through the library link you provided and it seems someone else faced the similar issue given here:
https://github.com/OmarAflak/Bluetooth-Library/issues/16
And it turned out be the connection wasn't established yet,so before calling send please check if the device is connected by using isConnected() function.
You shouldn't call send before the connection is established properly.you can set callback for the same using setDiscoveryCallback and do work inside most probable after you get confirmation in void onDevicePaired(BluetoothDevice device).
Edit 1: from the comments.
Are you sure it is in onDevicePaired() that I am supposed to send
data?
Maybe not,I think i misunderstood the example given by library author,now i think you should do it on onDeviceConnected.
Is there any other method that gets called when it is connected?
Yes,you can set a callback for that using following:
bluetooth.setDeviceCallback(new DeviceCallback() {
#Override
public void onDeviceConnected(BluetoothDevice device) {
// do your work here.
}
#Override
public void onDeviceDisconnected(BluetoothDevice device, String message) {
}
#Override
public void onMessage(String message) {
}
#Override
public void onError(String message) {
}
#Override
public void onConnectError(BluetoothDevice device, String message) {
}
});
Edit 2:
There, I try to connect at line
163(bluetoothObject.connectToAddress(address);), and it crashes with a
NullPointerException.
This crash happens because BluetoothAdapter isn't initialized yet,so when you call bluetoothObject.connectToAddress(address) it throws NullPointerException.
You need to initialize that before connecting as following:
bluetoothObject = new Bluetooth(getApplicationContext());
bluetoothObject.onStart();//this is the line that initializes adapter.
bluetoothObject.enable();
Related
My application enters an infinite loop when I press the Connect button to connect to an HC-06 Bluetooth module (Arduino shield). However, there are no loops anywhere in the code when the button is pressed.
package dleedesign.dubcommunicationstestapp;
import android.app.Fragment;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import java.util.Set;
/**
* Created by Chris on 7/24/2016.
*/
public class FirstFragment extends Fragment {
View myView;
public final String TAG = "Main";
private Bluetooth bt;
public Button sendCommand;
public Button send;
public TextView msgReceived;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
myView = inflater.inflate(R.layout.first_layout, container, false);
sendCommand = (Button) myView.findViewById(R.id.sendCommand);
sendCommand.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
connectService();
}
});
send = (Button) myView.findViewById(R.id.send);
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendBtCommand("1");
}
});
msgReceived = (TextView) myView.findViewById(R.id.msgReceived);
msgReceived.setText("Ready to connect");
bt = new Bluetooth(new MainActivity(), mHandler);
return myView;
}
public void sendBtCommand(String msg)
{
bt.sendMessage(msg);
}
public void connectService()
{
try {
msgReceived.setText("Connecting...");
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
if(btAdapter.isEnabled())
{
bt.start();
bt.connectDevice("HC-06");
Log.d(TAG, "Btservice started- listening");
msgReceived.setText("Connected!");
}
else
{
Log.w(TAG, "Btservice started - bluetooth is not enabled, requesting enable...");
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetooth, 0);
msgReceived.setText("Bluetooth not enabled, requested for enable");
}
} catch (Exception e) {
Log.e(TAG, "Unable to start bluetooth", e);
msgReceived.setText("Unable to connect: " + e);
}
}
private final Handler mHandler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
switch (msg.what)
{
case Bluetooth.MESSAGE_STATE_CHANGE:
Log.d(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
break;
case Bluetooth.MESSAGE_WRITE:
Log.d(TAG, "MESSAGE_WRITE");
break;
case Bluetooth.MESSAGE_READ:
Log.d(TAG, "MESSAGE_READ");
break;
case Bluetooth.MESSAGE_DEVICE_NAME:
Log.d(TAG, "MESSAGE_DEVICE_NAME " + msg);
break;
case Bluetooth.MESSAGE_TOAST:
Log.d(TAG, "MESSAGE_TOAST " + msg);
break;
}
}
};
}
For some reason, this problem just suddenly appeared when I tried to employ a loop to keep trying to connect while the connection is not established. I removed that code, but could it still be there somewhere?
Have you overridden the fragment's onActivityResult method?
If not, try overriding it and calling connectService() inside of it, by adding this to your fragment:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
connectService()
}
I am using braintree api to get add card in app for payments. It works fines and sometimes crashes randomly,
This is my 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)
This is my Code for the activity,
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);
}
}
}
This is my gradle version,
compile 'com.braintreepayments.api:braintree:2.+'
Full disclosure: I work for Braintree.
Are you refreshing the client token every time you go through the checkout process as required? I see that you are only downloading the Braintree token from the server if it is null.
Without having any insight into your CreditCard class or its validateCard method, another possibility may be that the CardBuilder object you are passing into Card.tokenize may not be well-formed.
If you are still having trouble, please reach out to Braintree support for help debugging your integration.
Hey I am making an android app based on training samples from developer.android.com Here is my MainActivity Code :
package com.example.hellowifi;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity {
private final IntentFilter mIntentFilter = new IntentFilter();
private WifiP2pManager mManager = null;
private WifiP2pManager.Channel mChannel = null;
private BroadcastReceiver mReciever;
private ListView mListView;
public static final String TAG = "wifidirectdemo";
// TXT RECORD properties
public static final String TXTRECORD_PROP_AVAILABLE = "available";
public static final String SERVICE_INSTANCE = "_wifidemotest";
public static final String SERVICE_REG_TYPE = "_presence._tcp";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (ListView) findViewById(R.id.listView);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(), null);
mReciever = new WiFiBroadCastReciever(mManager, mChannel, this);
startRegistration();
}
#Override
protected void onResume() {
super.onResume();
mReciever = new WiFiBroadCastReciever(mManager, mChannel, this);
registerReceiver(mReciever, mIntentFilter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReciever);
}
public void OnDiscoverButtonClicked(View view) {
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(MainActivity.this, "Discovery Process Succeded", Toast.LENGTH_SHORT).show();
System.out.println("changed");
}
#Override
public void onFailure(int reason) {
Toast.makeText(MainActivity.this, "Discovery Process Failed", Toast.LENGTH_SHORT).show();
}
});
}
private static List peers = new ArrayList();/*
private ArrayAdapter listAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,peers);*/
static WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() {
#Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
peers.clear();
peers.addAll(peerList.getDeviceList());
}
};
private void startRegistration() {
// Create a string map containing information about your service.
Map record = new HashMap();
record.put(TXTRECORD_PROP_AVAILABLE, "visible");
// Service information. Pass it an instance name, service type
// _protocol._transportlayer , and the map containing
// information other devices will want once they connect to this one.
WifiP2pDnsSdServiceInfo serviceInfo =
WifiP2pDnsSdServiceInfo.newInstance("_test", "_presence._tcp", record);
// Add the local service, sending the service info, network channel,
// and listener that will be used to indicate success or failure of
// the request.
mManager.addLocalService(mChannel, serviceInfo, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(MainActivity.this, "Added Local Service", Toast.LENGTH_SHORT);
}
#Override
public void onFailure(int arg0) {
Toast.makeText(MainActivity.this,"Failed to add a service",Toast.LENGTH_SHORT);
}
});
}
}
and my Broadcastreciever class is this :
package com.example.hellowifi;
import java.util.HashMap;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.NetworkInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.util.Log;
import android.widget.Toast;
public class WiFiBroadCastReciever extends BroadcastReceiver {
private MainActivity activity;
private WifiP2pManager mManager=null;
private WifiP2pManager.Channel mChannel=null;
PeerListListener myPeerListListener = null;
public WiFiBroadCastReciever(WifiP2pManager manager, WifiP2pManager.Channel channel,
Activity activity) {
super();
this.mManager = manager;
this.mChannel = channel;
this.activity = (MainActivity) activity;
}
#Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)){
int state=intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE,-1);
if (WifiP2pManager.WIFI_P2P_STATE_ENABLED==state)
Log.d("WiFiBroadCastReciever", "WiFi enabled");
else
Log.d("WiFiBroadCastReciever", "WiFi disabled");
}
else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)){
Toast.makeText(activity, "in intent", Toast.LENGTH_LONG).show();
if (mManager != null) {
mManager.requestPeers(mChannel, myPeerListListener);
}
}
else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)){
if (mManager == null) {
return;
}
NetworkInfo networkInfo = (NetworkInfo) intent
.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected()) {
// We are connected with the other device, request connection
// info to find group owner IP
/*mManager.requestConnectionInfo(mChannel, connectionListener);*/
}
}
else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)){
}
}
final HashMap<String, String> buddies = new HashMap<String, String>();
}
I am getting successful calls to Broadcasting Intents WIFI_P2P_STATE_CHANGED_ACTION,WIFI_P2P_CONNECTION_CHANGED_ACTION,WIFI_P2P_THIS_DEVICE_CHANGED_ACTION but not to WIFI_P2P_PEERS_CHANGED_ACTION
when I am making tethering and portable hotspot to other device and trying to discovering on my device.
Note that: WiFi is enabled and I am also getting Toast of Discovery successful. After that WIFI_P2P_PEERS_CHANGED_ACTION intent is not calling.
I tried searching on each and every thread.
Please try to help me someone. Thanks in advance.
You need to run discoverPeers() on other devices as well.
Now you will receive the WIFI_P2P_PEERS_CHANGED_ACTION intent
I had the same problem before. Please check below scenario how I have fixed the issue.
First I have implemented the same code in server and client android device with minor changes. I have placed a button in server app to invoke the discoverPeers() method. At the same time my client app is running and connected to the same WI-FI network. Then it triggers the WIFI_P2P_PEERS_CHANGED_ACTION event from broadcast in server app. There I have got the list of nearby peers.
I am having some difficulty passing the right information to set up Bluetooth discovery and pairing. I have been following the Android developer example documents pretty closely and have not been able to figure out what I need to pass to this method. This is the site I have been using, for reference.
http://developer.android.com/guide/topics/connectivity/bluetooth.html
TransferFragment:
//some code used from
// http://examples.javacodegeeks.com/android/core/ui/progressdialog/android-progressdialog-example/
// http://developer.android.com/guide/topics/connectivity/bluetooth.html
package com.project.BluetoothTransfer_v1000;
import java.util.Set;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
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.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class TransferFragment extends Fragment{
private TextView filePathTextView;
private Button startTransferButton;
private ImageView bluetoothImage;
ProgressDialog transferDialog;
Handler updateBarHandler;
private static final int REQUEST_BLUETOOTH = 1;
private static final int DISCOVER_DURATION = 300;
Context context;
ArrayAdapter mArrayAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, final Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//set the user interface layout for this activity
setRetainInstance(false);
View v = inflater.inflate(R.layout.activity_bluetooth_transfer, parent, false);
context = this.getActivity();
filePathTextView = (TextView) v.findViewById(R.id.file_path_textView);
startTransferButton = (Button) v.findViewById(R.id.start_transfer_button);
bluetoothImage = (ImageView) v.findViewById(R.id.bluetooth_imageView);
bluetoothImage.setClickable(true);
startTransferButton.setOnClickListener(new View.OnClickListener() {
//start transfer processes
#SuppressWarnings("unchecked")
#Override
public void onClick(View v){
//check to make sure the file path text view != null
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
int REQUEST_ENABLE_BT = -1;
//ensure the device being used has bluetooth capability
if (btAdapter != null){
//check-enable bluetooth
if (!btAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
//ensure the textview isn't empty
//check if filepath is null
if (filePathTextView.getText().toString().length() != 0){
Set<BluetoothDevice> pairedDevices = btAdapter.getBondedDevices();
//check if there are paired devices
if (pairedDevices.size() > 0){
//loop through paired devices
for (BluetoothDevice device: pairedDevices){
//add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}//end found paired devices if
// Create a BroadcastReceiver for ACTION_FOUND
final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
//COMPILER ERROR BELOW ######################################################
//"This method registerReceiver(BroadcastReceiver, IntentFilter)
//is undefined for type new View.OnClickListener
registerReceiver(mReceiver, filter);
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
btAdapter.cancelDiscovery();
}//
else {
//alert user to input file path
new AlertDialog.Builder(context).setTitle("Error")
.setMessage("Please insert a filename to send.")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {}
}).show();
}//ifnull (else)
}//bt equipped check
}//end anon class
});
bluetoothImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//display dialog showing program specs and creators
new AlertDialog.Builder(context).setTitle("About")
.setMessage("Created by:"+"\n"+ "Hal, Chris, and Roger")
.setPositiveButton("Awesome!", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
}
});
return v;
}
}
TransferActivity:
package com.project.BluetoothTransfer_v1000;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
public class TransferActivity extends FragmentActivity{
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_transfer);
TransferFragment fragment = new TransferFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.container, fragment);
fragmentTransaction.commit();
}
}
Try:
TransferFragment.this.getActivity().registerReceiver(mReceiver, filter);
Instead of:
registerReceiver(mReceiver, filter);
Because the method registerReceiver is part of the Activity and not the OnClickListener. This is why the error message complains about not found method in OnClickListener:
This method registerReceiver(BroadcastReceiver, IntentFilter)
is undefined for type new View.OnClickListener
When i call the purchase screen i can buy the in app product and everything works ok but when the user leave the app and returns to view the product it keeps asking them to buy again,
I need to know how i can make this so when the user purchases the app the store screen doesnt come up anymore and they can access the product, the app is designed so that when the user buys the app they gain access to a new activity with features built in
if anyone could help, I would be most grateful
I used this tutorial which was very helpful in getting me started:[TUT] Simple InApp Billing / Payment By blundell
Here is my code
package com.IrishSign.app;
import java.util.Locale;
import com.IrishSign.app.BillingHelper;
import com.IrishSign.app.R;
import com.IrishSign.app.BillingService;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class IrishSignAppActivity extends Activity implements OnClickListener {
private static final String TAG = "BillingService";
private Context mContext;
private ImageView purchaseableItem;
private Button purchaseButton;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.i("BillingService", "Starting");
setContentView(R.layout.main);
mContext = this;
Button A = (Button) findViewById(R.id.alphabet);
Button purchaseableItem = (Button) findViewById(R.id.topics);
Button Intro = (Button) findViewById(R.id.intro);
Button G = (Button) findViewById(R.id.about);
purchaseableItem.setOnClickListener(this);
startService(new Intent(mContext, BillingService.class));
BillingHelper.setCompletedHandler(mTransactionHandler);
A.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent1 = new Intent("com.IrishSign.app.alpha");
startActivity(intent1);
}
});
Intro.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent1 = new Intent("com.IrishSign.app.Intro");
startActivity(intent1);
}
});
G.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
AlertDialog alertDialog = new AlertDialog.Builder(
IrishSignAppActivity.this).setCancelable(false)
.create(); // Reads Update
alertDialog.setTitle("Welcome");
alertDialog.setMessage("-----");//
alertDialog.setButton("Continue",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int arg1) {
Intent intent5 = new Intent(
IrishSignAppActivity.this,
IrishSignAppActivity.class);
}
});
alertDialog.show(); // <-- Shows dialog on screen.
}
});
}
public Handler mTransactionHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
Log.i(TAG, "Transaction complete");
Log.i(TAG, "Transaction status: "
+ BillingHelper.latestPurchase.purchaseState);
Log.i(TAG, "Item purchased is: "
+ BillingHelper.latestPurchase.productId);
if (BillingHelper.latestPurchase.isPurchased()) {
Intent intent = new Intent("com.IrishSign.app.Topics");
startActivity(intent);
}
};
};
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.topics:
if (BillingHelper.isBillingSupported()) {
BillingHelper.requestPurchase(mContext,
"com.blundell.item.passport");
// android.test.purchased or android.test.canceled or
// android.test.refunded or com.blundell.item.passport
} else {
Log.i(TAG, "Can't purchase on this device");
purchaseButton.setEnabled(false); // XXX press button before
// service started will
// disable when it shouldnt
}
break;
default:
// nada
Log.i(TAG, "default. ID: " + v.getId());
break;
}
}
#Override
protected void onPause() {
Log.i(TAG, "onPause())");
super.onPause();
}
#Override
protected void onDestroy() {
BillingHelper.stopService();
super.onDestroy();
}
}
You can check when the application starts by using restoreTransactions. If you have used Managed Products or Subscriptions then only you will get all the details of the user.
For Unmanaged product there is no detail maintained by google.
So call this in your main activity
mBillingService = new BillingService();
mBillingService.setContext(this);
mBillingService.restoreTransactions();
Once you call this in ResponseHandler class there is one method purchaseResponse
purchaseResponse(final Context context,
final PurchaseState purchaseState, final String productId,
final String orderId, final long purchaseTime,
final String developerPayload, final String purchaseToken) {
}
which will return all the details.
You can check purchaseState then after
if (purchaseState == PurchaseState.PURCHASED) {
} else if (purchaseState == PurchaseState.REFUNDED) {
} else if (purchaseState == PurchaseState.CANCELED) {
}