I have a huge problem with the bump API on Android. I setup everything like in the example, the first time I start my activity containing the bump code it works great, now if I go back and start it again it just crash due to a Fatal signal error... It happen right after I call the configure of the bump API.
May I need to not call it again ? But there is nothing to check if it already configured or not.
public class BumpActivity extends Activity {
private IBumpAPI api;
private ProgressDialog mDialog;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bump);
mDialog = ProgressDialog.show(BumpActivity.this, "Preparing bump", "Loading");
bindService(new Intent(IBumpAPI.class.getName()), connection,
Context.BIND_AUTO_CREATE);
IntentFilter filter = new IntentFilter();
filter.addAction(BumpAPIIntents.CHANNEL_CONFIRMED);
filter.addAction(BumpAPIIntents.DATA_RECEIVED);
filter.addAction(BumpAPIIntents.NOT_MATCHED);
filter.addAction(BumpAPIIntents.MATCHED);
filter.addAction(BumpAPIIntents.CONNECTED);
registerReceiver(receiver, filter);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
@Override
public void onBackPressed(){
Intent resultIntent = new Intent();
setResult(Activity.RESULT_CANCELED, resultIntent);
super.onBackPressed();
}
private final ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder binder) {
Log.i("BumpTest", "onServiceConnected");
api = IBumpAPI.Stub.asInterface(binder);
new Thread() {
public void run() {
try {
api.configure("9b17d663752843a1bfa4cc72d309339e",
"Bump User");
} catch (RemoteException e) {
Log.w("BumpTest", e);
}
}
}.start();
Log.d("Bump Test", "Service connected");
}
@Override
public void onServiceDisconnected(ComponentName className) {
Log.d("Bump Test", "Service disconnected");
}
};
private final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
try {
if (action.equals(BumpAPIIntents.DATA_RECEIVED)) {
getUserDetailFromBump(new String(
intent.getByteArrayExtra("data")));
} else if (action.equals(BumpAPIIntents.MATCHED)) {
long channelID = intent
.getLongExtra("proposedChannelID", 0);
Log.i("Bump Test",
"Matched with: "
+ api.userIDForChannelID(channelID));
api.confirm(channelID, true);
Toast toast = Toast.makeText(
getApplicationContext(),
"Matched with: "
+ api.userIDForChannelID(channelID),
Toast.LENGTH_SHORT);
toast.show();
} else if (action.equals(BumpAPIIntents.CHANNEL_CONFIRMED)) {
long channelID = intent.getLongExtra("channelID", 0);
api.send(channelID, CurrentUserManager.getSharedManager()
.getCurrentUser().getUserId().toString().getBytes());
} else if (action.equals(BumpAPIIntents.NOT_MATCHED)) {
Toast toast = Toast.makeText(getApplicationContext(),
"No match", Toast.LENGTH_SHORT);
toast.show();
} else if (action.equals(BumpAPIIntents.CONNECTED)) {
mDialog.dismiss();
api.enableBumping();
}
} catch (RemoteException e) {
}
}
};
public void getUserDetailFromBump(String data) {
Log.i("User Id", data);
LoginRequest login = new LoginRequest(getApplicationContext());
Log.i("Token", login.getArchivedToken());
AsyncHttpClient restRequest = new AsyncHttpClient();
PersistentCookieStore cookie = new PersistentCookieStore(getApplicationContext());
restRequest.setCookieStore(cookie);
RequestParams params = new RequestParams();
params.put("auth_token", login.getArchivedToken());
params.put("user_id", data);
Log.i("Request", "Preparing");
restRequest.get(Constantes.API_URL + "users/show.json", params, new AsyncHttpResponseHandler(){
public void onSuccess(String response) {
Log.i("Reponse", response);
try {
User user = new User(new JSONObject(response));
Log.i("User", user.toString());
//Driver
if (CurrentUserManager.getSharedManager().getCurrentUser().getType() == 1){
CurrentRouteManager.getSharedManager().getCurrentRoute().addPassanger(user);
Intent resultIntent = new Intent(BumpActivity.this, DriverActivity.class);
resultIntent.putExtra("PASSENGER_ADDED", true);
setResult(1, resultIntent);
finish();
}
else{
Intent p = new Intent(BumpActivity.this, RoutePassenger.class);
p.putExtra("driver", user);
startActivity(p);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onFailure(Throwable e) {
Log.i("Error", e.toString());
}
});
}
public void onStart() {
Log.i("BumpTest", "onStart");
super.onStart();
}
public void onRestart() {
Log.i("BumpTest", "onRestart");
super.onRestart();
}
public void onResume() {
Log.i("BumpTest", "onResume");
super.onResume();
}
public void onPause() {
Log.i("BumpTest", "onPause");
try {
api.disableBumping();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.onPause();
}
public void onStop() {
Log.i("BumpTest", "onStop");
try {
api.disableBumping();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.onStop();
}
public void onDestroy() {
Log.i("BumpTest", "onDestroy");
try {
api.disableBumping();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
unbindService(connection);
unregisterReceiver(receiver);
super.onDestroy();
}
}
I finally resolved it few days ago. As I'm not a JAVA expert I think the bug is located within the Bump library. If you do api.configure when it is already configured it simply crash. So I ended up making a singleton, ensuring that it is called only once
Here is the code
public class BumpConnection {
protected Context context;
private IBumpAPI api;
private static BumpConnection sharedManager;
public static synchronized BumpConnection getSharedManager(Context context) {
if (sharedManager == null) {
sharedManager = new BumpConnection(context);
}
return sharedManager;
}
private BumpConnection(Context context){
this.context = context;
context.bindService(new Intent(IBumpAPI.class.getName()), connection,
Context.BIND_AUTO_CREATE);
}
public IBumpAPI getApi() {
return api;
}
public void setApi(IBumpAPI api) {
this.api = api;
}
private final ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder binder) {
Log.i("BumpTest", "onServiceConnected");
api = IBumpAPI.Stub.asInterface(binder);
new Thread() {
public void run() {
try {
api.configure("9b17d663752843a1bfa4cc72d309339e",
"Bump User");
} catch (RemoteException e) {
Log.w("BumpTest", e);
}
}
}.start();
Log.d("Bump Test", "Service connected");
}
@Override
public void onServiceDisconnected(ComponentName className) {
Log.d("Bump Test", "Service disconnected");
}
};
}