i'm trying to implement a SIP Client on Android application using native Session Initiation protocol.
Everything is woking fine if i create an Activity and put the following code :
public class WalkieTalkieActivity extends AppCompatActivity implements View.OnTouchListener {
public String sipAddress = null;
public SipManager manager = null;
public SipProfile me = null;
public SipAudioCall call = null;
public IncomingCallReceiver callReceiver;
private static final int CALL_ADDRESS = 1;
private static final int SET_AUTH_INFO = 2;
private static final int UPDATE_SETTINGS_DIALOG = 3;
private static final int HANG_UP = 4;
private final int PERMISSIONS_REQUEST_RECORD_AUDIO = 1;
private final int PERMISSIONS_REQUEST_USE_SIP = 2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_walkietalkie);
//initRecorderParameters(new int[]{8000, 11025, 16000, 22050, 44100});
//Richiedo i vari permessi
if (!hasUseSipPermission()) { requestUseSipPermission(); }
//Rchiedo i vari permessi
if (!hasRecordAudioPermission()) { requestRecordAudioPermission(); }
if (!SipManager.isVoipSupported(this)) {
//Visualizzo il messaggio voip non supportato e torno alla dahboard
Toast.makeText(WalkieTalkieActivity.this, "Voip non supportato su questo telefono", Toast.LENGTH_LONG).show();
Intent dashboard = new Intent(WalkieTalkieActivity.this,MainActivity.class);
// passo all'attivazione dell'activity page1.java
startActivity(dashboard);
finish();
}
if (!SipManager.isApiSupported(this)) {
//Visualizzo il messaggio voip non supportato e torno alla dahboard
Toast.makeText(WalkieTalkieActivity.this, "API non supportate su questo telefono", Toast.LENGTH_LONG).show();
Intent dashboard = new Intent(WalkieTalkieActivity.this,MainActivity.class);
// passo all'attivazione dell'activity page1.java
startActivity(dashboard);
finish();
}
// "Push to talk" can be a serious pain when the screen keeps turning off.
// Let's prevent that.
//getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// use this to start and trigger a service
Intent i = new Intent(this, SipEngine.class);
// potentially add data to the intent
i.putExtra("KEY1", "Value to be used by the service");
this.startService(i);
initializeManager();
}
#Override
public void onStart() {
super.onStart();
// When we get back from the preference setting Activity, assume
// settings have changed, and re-login with new auth info.
initializeManager();
}
#Override
public void onDestroy() {
super.onDestroy();
if (call != null) {
call.close();
}
closeLocalProfile();
if (callReceiver != null) {
this.unregisterReceiver(callReceiver);
}
}
public void initializeManager() {
if(manager == null) {
manager = SipManager.newInstance(this);
}
initializeLocalProfile();
}
/**
* Logs you into your SIP provider, registering this device as the location to
* send SIP calls to for your SIP address.
*/
public void initializeLocalProfile() {
if (manager == null) {
return;
}
if (me != null) {
closeLocalProfile();
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
//String username = prefs.getString("namePref", "");
//String domain = prefs.getString("domainPref", "");
//String password = prefs.getString("passPref", "");
String username = "username";
String domain = "domain";
String password = "password";
// Set up the intent filter. This will be used to fire an
// IncomingCallReceiver when someone calls the SIP address used by this
// application.
IntentFilter filter = new IntentFilter();
filter.addAction("android.vohippo.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver, filter);
try {
Log.d("VOHIPPOSERVICE", "PROVO A REGISTRARE");
SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
//Costruisco il builder
me = builder.build();
//Intent
Intent i = new Intent();
i.setAction("android.vohippo.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);
manager.open(me, pi, null);
// This listener must be added AFTER manager.open is called,
// Otherwise the methods aren't guaranteed to fire.
manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {
public void onRegistering(String localProfileUri) {
updateStatus("Registering with SIP Server...");
//updateNotification(ContextCompat.getColor(getBaseContext(), R.color.colorPrimary), "Attivazione in corso...");
}
public void onRegistrationDone(String localProfileUri, long expiryTime) {
updateStatus("Ready");
//updateNotification(ContextCompat.getColor(getBaseContext(), R.color.colorPrimary), "Servizio disponibile");
}
public void onRegistrationFailed(String localProfileUri, int errorCode,
String errorMessage) {
updateStatus("Registration failed. Please check settings.");
//updateNotification(ContextCompat.getColor(getBaseContext(), R.color.colorPrimary), "Servizio non disponibile");
}
});
} catch (ParseException pe) {
updateStatus("Connection Error.");
//updateNotification(ContextCompat.getColor(getBaseContext(), R.color.colorPrimary), "Errore di connessione");
} catch (SipException se) {
updateStatus("Connection error.");
//updateNotification(ContextCompat.getColor(getBaseContext(), R.color.colorPrimary), "Errore connessione");
}
}
/**
* Closes out your local profile, freeing associated objects into memory
* and unregistering your device from the server.
*/
public void closeLocalProfile() {
if (manager == null) {
return;
}
try {
if (me != null) {
manager.close(me.getUriString());
}
} catch (Exception ee) {
Log.d("WalkieTalkieActivity", "Failed to close local profile.", ee);
}
}
/**
* Make an outgoing call.
*/
public void initiateCall() {
Toast.makeText(WalkieTalkieActivity.this, "Chiamata lanciata", Toast.LENGTH_SHORT).show();
updateStatus(sipAddress);
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
// Much of the client's interaction with the SIP Stack will
// happen via listeners. Even making an outgoing call, don't
// forget to set up a listener to set things up once the call is established.
#Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
if (call.isMuted()) {
call.toggleMute();
}
updateStatus(call);
Toast.makeText(WalkieTalkieActivity.this, "Chiamata stabilita", Toast.LENGTH_SHORT).show();
}
#Override
public void onCallEnded(SipAudioCall call) {
Toast.makeText(WalkieTalkieActivity.this, "Chiamata terminata", Toast.LENGTH_SHORT).show();
updateStatus("Ready.");
}
};
call = manager.makeAudioCall(me.getUriString(), sipAddress, listener, 30);
}
catch (Exception e) {
Log.i("WalkieTalkieActivity", "Error when trying to close manager.", e);
if (me != null) {
try {
manager.close(me.getUriString());
} catch (Exception ee) {
Log.i("WalkieTalkieActivity",
"Error when trying to close manager.", ee);
ee.printStackTrace();
}
}
if (call != null) {
call.close();
}
}
}
/**
* Updates the status box at the top of the UI with a messege of your choice.
* #param status The String to display in the status box.
*/
public void updateStatus(final String status) {
// Be a good citizen. Make sure UI changes fire on the UI thread.
this.runOnUiThread(new Runnable() {
public void run() {
TextView labelView = (TextView) findViewById(R.id.sipLabel);
labelView.setText(status);
}
});
}
/**
* Updates the status box with the SIP address of the current call.
* #param call The current, active call.
*/
public void updateStatus(SipAudioCall call) {
String useName = call.getPeerProfile().getDisplayName();
if(useName == null) {
useName = call.getPeerProfile().getUserName();
}
updateStatus(useName + "#" + call.getPeerProfile().getSipDomain());
}
/**
* Updates whether or not the user's voice is muted, depending on whether the button is pressed.
* #param v The View where the touch event is being fired.
* #param event The motion to act on.
* #return boolean Returns false to indicate that the parent view should handle the touch event
* as it normally would.
*/
public boolean onTouch(View v, MotionEvent event) {
if (call == null) {
return false;
} else if (event.getAction() == MotionEvent.ACTION_DOWN && call != null && call.isMuted()) {
call.toggleMute();
} else if (event.getAction() == MotionEvent.ACTION_UP && !call.isMuted()) {
call.toggleMute();
}
return false;
}
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, CALL_ADDRESS, 0, "Call someone");
menu.add(0, SET_AUTH_INFO, 0, "Edit your SIP Info.");
menu.add(0, HANG_UP, 0, "End Current Call.");
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case CALL_ADDRESS:
showDialog(CALL_ADDRESS);
break;
case SET_AUTH_INFO:
updatePreferences();
break;
case HANG_UP:
if(call != null) {
try {
call.endCall();
} catch (SipException se) {
Log.d("WalkieTalkieActivity",
"Error ending call.", se);
}
call.close();
}
break;
}
return true;
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case CALL_ADDRESS:
LayoutInflater factory = LayoutInflater.from(this);
final View textBoxView = factory.inflate(R.layout.call_address_dialog, null);
return new AlertDialog.Builder(this)
.setTitle("Call Someone.")
.setView(textBoxView)
.setPositiveButton(
android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
EditText textField = (EditText)
(textBoxView.findViewById(R.id.calladdress_edit));
sipAddress = textField.getText().toString();
initiateCall();
}
})
.setNegativeButton(
android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Noop.
}
})
.create();
case UPDATE_SETTINGS_DIALOG:
return new AlertDialog.Builder(this)
.setMessage("Please update your SIP Account Settings.")
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
updatePreferences();
}
})
.setNegativeButton(
android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Noop.
}
})
.create();
}
return null;
}
public void updatePreferences() {
//Intent settingsActivity = new Intent(getBaseContext(),
// SipSettings.class);
//startActivity(settingsActivity);
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSIONS_REQUEST_USE_SIP:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(WalkieTalkieActivity.this, "Permission Granted!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(WalkieTalkieActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
}
case PERMISSIONS_REQUEST_RECORD_AUDIO:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(WalkieTalkieActivity.this, "Permission Granted!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(WalkieTalkieActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
}
}
}
//Controllo che il sistema abbia il permesso di registrare audio
private boolean hasRecordAudioPermission(){
boolean hasPermission = (ContextCompat.checkSelfPermission(this,
Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED);
Log.d("VOHIPPO", "Permesso di registrare audio? " + hasPermission);
return hasPermission;
}
private void requestRecordAudioPermission(){
String requiredPermission = Manifest.permission.RECORD_AUDIO;
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
requiredPermission)) {
Toast.makeText(WalkieTalkieActivity.this, "Quest applicazione richiede il permesso di registrare audio", Toast.LENGTH_SHORT).show();
}
// request the permission.
ActivityCompat.requestPermissions(this,
new String[]{requiredPermission},
PERMISSIONS_REQUEST_RECORD_AUDIO);
}
//Controllo che il sistema abbia il permesso di registrare audio
private boolean hasUseSipPermission(){
boolean hasPermission = (ContextCompat.checkSelfPermission(this,
Manifest.permission.USE_SIP) == PackageManager.PERMISSION_GRANTED);
Log.d("VOHIPPO", "Permesso di usare sip? " + hasPermission);
return hasPermission;
}
private void requestUseSipPermission(){
String requiredPermission = Manifest.permission.USE_SIP;
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
requiredPermission)) {
Toast.makeText(WalkieTalkieActivity.this, "Quest applicazione richiede il permesso di usare SIP", Toast.LENGTH_SHORT).show();
}
// request the permission.
ActivityCompat.requestPermissions(this,
new String[]{requiredPermission},
PERMISSIONS_REQUEST_USE_SIP);
}
but if i create a service and try to do the same into this service i have no errors, but my client doesn't register with the server.
This is the code i put into the service :
public class SipEngine extends IntentService {
public String sipAddress = null;
public SipManager manager = null;
public SipProfile me = null;
public SipAudioCall call = null;
public IncomingCallReceiver callReceiver;
private static final int CALL_ADDRESS = 1;
private static final int SET_AUTH_INFO = 2;
private static final int UPDATE_SETTINGS_DIALOG = 3;
private static final int HANG_UP = 4;
private int NOTIFICATION = 10002; //Any unique number for this notification
public SipEngine() {
super("SipEngine");
}
#Override
protected void onHandleIntent(Intent workIntent) {
// Gets data from the incoming Intent
String dataString = workIntent.getDataString();
initializeManager();
sendNotification();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//#Override
//public void onStart() {
// super.onStart();
// When we get back from the preference setting Activity, assume
// settings have changed, and re-login with new auth info.
//initializeManager();
//}
#Override
public void onDestroy() {
super.onDestroy();
if (call != null) {
call.close();
}
closeLocalProfile();
if (callReceiver != null) {
this.unregisterReceiver(callReceiver);
}
}
public void initializeManager() {
if(manager == null) {
manager = SipManager.newInstance(this);
}
initializeLocalProfile();
}
/**
* Logs you into your SIP provider, registering this device as the location to
* send SIP calls to for your SIP address.
*/
public void initializeLocalProfile() {
if (manager == null) {
return;
}
if (me != null) {
closeLocalProfile();
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
//String username = prefs.getString("namePref", "");
//String domain = prefs.getString("domainPref", "");
//String password = prefs.getString("passPref", "");
String username = "username";
String domain = "server";
String password = "password";
// Set up the intent filter. This will be used to fire an
// IncomingCallReceiver when someone calls the SIP address used by this
// application.
IntentFilter filter = new IntentFilter();
filter.addAction("android.vohippo.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver, filter);
try {
Log.d("VOHIPPOSERVICE", "PROVO A REGISTRARE");
SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
//Costruisco il builder
me = builder.build();
//Intent
Intent i = new Intent();
i.setAction("android.vohippo.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);
manager.open(me, pi, null);
// This listener must be added AFTER manager.open is called,
// Otherwise the methods aren't guaranteed to fire.
manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {
public void onRegistering(String localProfileUri) {
//updateStatus("Registering with SIP Server...");
updateNotification(ContextCompat.getColor(getBaseContext(), R.color.colorPrimary), "Attivazione in corso...");
}
public void onRegistrationDone(String localProfileUri, long expiryTime) {
//updateStatus("Ready");
updateNotification(ContextCompat.getColor(getBaseContext(), R.color.colorPrimary), "Servizio disponibile");
}
public void onRegistrationFailed(String localProfileUri, int errorCode,
String errorMessage) {
//updateStatus("Registration failed. Please check settings.");
updateNotification(ContextCompat.getColor(getBaseContext(), R.color.colorPrimary), "Servizio non disponibile");
}
});
} catch (ParseException pe) {
//updateStatus("Connection Error.");
//updateNotification(ContextCompat.getColor(getBaseContext(), R.color.colorPrimary), "Errore di connessione");
} catch (SipException se) {
//updateStatus("Connection error.");
//updateNotification(ContextCompat.getColor(getBaseContext(), R.color.colorPrimary), "Errore connessione");
}
}
/**
* Closes out your local profile, freeing associated objects into memory
* and unregistering your device from the server.
*/
public void closeLocalProfile() {
if (manager == null) {
return;
}
try {
if (me != null) {
manager.close(me.getUriString());
}
} catch (Exception ee) {
Log.d("WalkieTalkieActivity", "Failed to close local profile.", ee);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Send simple notification using the NotificationCompat API.
*/
public void sendNotification() {
// Use NotificationCompat.Builder to set up our notification.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
//icon appears in device notification bar and right hand corner of notification
builder.setSmallIcon(R.drawable.ic_service_sip);
// This intent is fired when notification is clicked
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://stacktips.com/"));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
// Set the intent that will fire when the user taps the notification.
builder.setContentIntent(pendingIntent);
// Large icon appears on the left of the notification
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_service_sip));
// Content title, which appears in large type at the top of the notification
builder.setContentTitle("Vohippo");
int color = ContextCompat.getColor(this, R.color.colorPrimary);
builder.setColor(color);
// Content text, which appears in smaller text below the title
builder.setContentText("491023456");
// The subtext, whichppears under the text on newer devices.
// This will show-up in the devices with Android 4.2 and above only
builder.setSubText("Attendere...");
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Will display the notification in the notification bar
notificationManager.notify(NOTIFICATION, builder.build());
}
/**
* Send simple notification using the NotificationCompat API.
*/
public void updateNotification(int color, String status) {
// Use NotificationCompat.Builder to set up our notification.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setColor(color);
// The subtext, which appears under the text on newer devices.
// This will show-up in the devices with Android 4.2 and above only
builder.setSubText(status);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Will display the notification in the notification bar
notificationManager.notify(NOTIFICATION, builder.build());
}
Should i do something different into a service instead of a normal Activity?
Than k you.
Related
Currently i'm implementing the in app update feature from android. I'm using the immediate update method, the problem that I'm facing is that when the UI prompting the user to update shows and the user does not click the update button instead they click the cross button. The UI for the app update just closes and user can continue using the app.
What I want is that when user click the cross button the app immediately closes, until user updates the app then they can use the app as usual. I also uses the java code for the android development.
public class LoginActivity extends AppCompatActivity {
private LoginViewModel loginViewModel;
public static final String MyPREFERENCES = "LoginPrefs" ;
public static final String Name = "nameKey";
public static final String User = "userKey";
public static final String con = "closed";
public static String error = "";
public static int userFlag = 0;
SharedPreferences sharedpreferences;
SharedPreferences.Editor editor;
public TextInputEditText usernameEditText;
public TextInputEditText passwordEditText;
private AppUpdateManager mAppUpdateManager;
private int RC_APP_UPDATE = 999;
private int inAppUpdateType;
private com.google.android.play.core.tasks.Task<AppUpdateInfo> appUpdateInfoTask;
private InstallStateUpdatedListener installStateUpdatedListener;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
loginViewModel = ViewModelProviders.of(this, new LoginViewModelFactory())
.get(LoginViewModel.class);
usernameEditText = findViewById(R.id.user);
passwordEditText = findViewById(R.id.pass);
final Button loginButton = findViewById(R.id.submitBTN);
final TextInputLayout userL = findViewById(R.id.userL);
final TextInputLayout passL = findViewById(R.id.passL);
final JellyToggleButton jtb = findViewById(R.id.jtb);
// Creates instance of the manager.
mAppUpdateManager = AppUpdateManagerFactory.create(this);
// Returns an intent object that you use to check for an update.
appUpdateInfoTask = mAppUpdateManager.getAppUpdateInfo();
//lambda operation used for below listener
//For flexible update
installStateUpdatedListener = installState -> {
if (installState.installStatus() == InstallStatus.DOWNLOADED) {
popupSnackbarForCompleteUpdate();
}
};
mAppUpdateManager.registerListener(installStateUpdatedListener);
inAppUpdateType = AppUpdateType.IMMEDIATE; //1
inAppUpdate();
if(userFlag==1){
jtb.setChecked(true);
}
userL.setHint("Enter username");
sharedpreferences = getSharedPreferences(MyPREFERENCES, MODE_PRIVATE);
loginViewModel.getLoginFormState().observe(this, new Observer<LoginFormState>() {
#Override
public void onChanged(#Nullable LoginFormState loginFormState) {
if (loginFormState == null) {
return;
}
loginButton.setEnabled(loginFormState.isDataValid());
if (loginFormState.getUsernameError() != null) {
usernameEditText.setError(getString(loginFormState.getUsernameError()));
loginButton.startAnimation(AnimationUtils.loadAnimation(LoginActivity.this,R.anim.shake));
}
if (loginFormState.getPasswordError() != null) {
passwordEditText.setError(getString(loginFormState.getPasswordError()));
loginButton.startAnimation(AnimationUtils.loadAnimation(LoginActivity.this,R.anim.shake));
}
}
});
loginViewModel.getLoginResult().observe(this, new Observer<LoginResult>() {
#Override
public void onChanged(#Nullable LoginResult loginResult) {
if (loginResult == null) {
return;
}
if (loginResult.getError() != null) {
showLoginFailed(loginResult.getError());
}
if (loginResult.getSuccess() != null) {
updateUiWithUser(loginResult.getSuccess());
Intent i = new Intent(LoginActivity.this, user_dashboard.class);
startActivity(i);
}
setResult(Activity.RESULT_OK);
//Complete and destroy login activity once successful
}
});
TextWatcher afterTextChangedListener = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// ignore
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// ignore
}
#Override
public void afterTextChanged(Editable s) {
loginViewModel.loginDataChanged(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
}
};
usernameEditText.addTextChangedListener(afterTextChangedListener);
passwordEditText.addTextChangedListener(afterTextChangedListener);
passwordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
loginViewModel.login(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
}
return false;
}
});
loginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(userFlag==0) {
loginViewModel.login(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
getStaffData();
}
else if(userFlag==1){
loginWorker();
}
}
});
jtb.setOnStateChangeListener(new JellyToggleButton.OnStateChangeListener() {
#Override
public void onStateChange(float process, State state, JellyToggleButton jtb) {
if (state.equals(State.LEFT)) {
userL.setHint("Enter username");
error = "Username cannot be empty";
userFlag = 0;
}
if (state.equals(State.RIGHT)) {
userL.setHint("Enter badge ID");
error = "Badge ID cannot be empty";
userFlag = 1;
}
}
});
}
#Override
protected void onDestroy() {
mAppUpdateManager.unregisterListener(installStateUpdatedListener);
finishAndRemoveTask();
super.onDestroy();
}
#Override
protected void onResume() {
try {
mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.updateAvailability() ==
UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
// If an in-app update is already running, resume the update.
try {
mAppUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
inAppUpdateType,
this,
RC_APP_UPDATE);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
});
mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener(appUpdateInfo -> {
//For flexible update
if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
popupSnackbarForCompleteUpdate();
}
});
} catch (Exception e) {
e.printStackTrace();
}
super.onResume();
}
#Override //For flexible update
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_APP_UPDATE) {
//when user clicks update button
if (resultCode == RESULT_OK) {
Toast.makeText(LoginActivity.this, "App download starts...", Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
//if you want to request the update again just call checkUpdate()
Toast.makeText(LoginActivity.this, "App download canceled.", Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_IN_APP_UPDATE_FAILED) {
Toast.makeText(LoginActivity.this, "App download failed.", Toast.LENGTH_LONG).show();
}
}
}
private void updateUiWithUser(LoggedInUserView model) {
String welcome = getString(R.string.welcome);
// TODO : initiate successful logged in experience
Toast.makeText(getApplicationContext(), welcome, Toast.LENGTH_LONG).show();
}
private void showLoginFailed(#StringRes Integer errorString) {
Toast.makeText(getApplicationContext(), errorString, Toast.LENGTH_SHORT).show();
}
private void getStaffData() {
String username = usernameEditText.getText().toString();
APIInterface apiInterface3 = APIClient.getClient().create(APIInterface.class);
Call<loginList> call3 = apiInterface3.staffData(username);
call3.enqueue(new Callback<loginList>() {
#Override
public void onResponse(Call<loginList> call, Response<loginList> response) {
loginList list = response.body();
if (list!=null && list.getStatusCode()==1) { //response received.
if(list.getStaffList().size()>0){
Log.d("check-in", list.getStatusCode() + " " + list.getStaffList().get(0).getName());
Toast.makeText(LoginActivity.this,"Logged in",Toast.LENGTH_SHORT).show();
final String name = list.getStaffList().get(0).getName();
final String badge = list.getStaffList().get(0).getBadge();
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Name,name);
editor.putString(User,badge);
editor.putInt(con,1);
editor.apply();
}
else if(list.getStaffList().size()==0){
}
}
}
#Override
public void onFailure(Call<loginList> call, Throwable t) {
Log.d("fail",t.toString());
}
});
}
private void loginWorker(){
String username = usernameEditText.getText().toString();
String password = passwordEditText.getText().toString();
APIInterface apiInterface3 = APIClient.getClient().create(APIInterface.class);
Call<loginList> call3 = apiInterface3.loginWorker(username,password);
call3.enqueue(new Callback<loginList>() {
#Override
public void onResponse(Call<loginList> call, Response<loginList> response) {
loginList list = response.body();
Log.d("response", response.body().toString());
if (list!=null && list.getStatusCode()==1) { //response received.
if(list.getLoginList().size()>0){
Log.d("check-in", list.getStatusCode() + " " + list.getLoginList().get(0).getName());
Toast.makeText(LoginActivity.this,"Logged in",Toast.LENGTH_SHORT).show();
List<login> item = response.body().getLoginList();
final String name = list.getLoginList().get(0).getName();
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Name,name);
editor.putInt(con,1);
editor.apply();
}
String welcome = getString(R.string.welcome);
Toast.makeText(getApplicationContext(), welcome, Toast.LENGTH_SHORT).show();
Intent i = new Intent(LoginActivity.this, user_dashboard.class);
startActivity(i);
}
else
Toast.makeText(LoginActivity.this, "wrong ID or password",Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<loginList> call, Throwable t) {
Log.d("fail",t.toString());
}
});
editor = sharedpreferences.edit();
editor.putString(User, username);
editor.commit();
}
#Override
public void onBackPressed() {
new MaterialAlertDialogBuilder(LoginActivity.this,R.style.MyDialogTheme)
.setTitle("Exit")
.setMessage("Confirm to exit?")
.setBackground(getDrawable(R.drawable.alert_dialog))
// Specifying a listener allows you to take an action before dismissing the dialog.
// The dialog is automatically dismissed when a dialog button is clicked.
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Continue with delete
finishAffinity();
}
})
.setNegativeButton(android.R.string.no, null)
.show();
}
private void inAppUpdate() {
try {
// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener(new OnSuccessListener<AppUpdateInfo>() {
#Override
public void onSuccess(AppUpdateInfo appUpdateInfo) {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
// For a flexible update, use AppUpdateType.FLEXIBLE
&& appUpdateInfo.isUpdateTypeAllowed(inAppUpdateType)) {
// Request the update.
try {
mAppUpdateManager.startUpdateFlowForResult(
// Pass the intent that is returned by 'getAppUpdateInfo()'.
appUpdateInfo,
// Or 'AppUpdateType.FLEXIBLE' for flexible updates.
inAppUpdateType,
// The current activity making the update request.
LoginActivity.this,
// Include a request code to later monitor this update request.
RC_APP_UPDATE);
} catch (IntentSender.SendIntentException ignored) {
}
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private void popupSnackbarForCompleteUpdate() {
try {
Snackbar snackbar =
Snackbar.make(
findViewById(R.id.coordinatorL),
"An update has just been downloaded.\nRestart to update",
Snackbar.LENGTH_INDEFINITE);
snackbar.setAction("INSTALL", view -> {
if (mAppUpdateManager != null){
mAppUpdateManager.completeUpdate();
}
});
snackbar.setActionTextColor(getResources().getColor(R.color.orange));
snackbar.show();
} catch (Resources.NotFoundException e) {
e.printStackTrace();
}
}
}
The image I borrowed from google, on the left image as can be seen there is a cross button on top right user can click to close the update process
The most important point I will emphasize is that you should not force users to update the app until it is absolutely necessary (like some security issues etc). Forcing updates to users is considered a very bad user experience.
To the question you asked, you have the answer in your question itself. If you check the code you have something like this in your onActivityResult method-
if (requestCode == RC_APP_UPDATE) {
//when user clicks update button
if (resultCode == RESULT_OK) {
Toast.makeText(LoginActivity.this, "App download starts...", Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
//if you want to request the update again just call checkUpdate()
Toast.makeText(LoginActivity.this, "App download canceled.", Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_IN_APP_UPDATE_FAILED) {
Toast.makeText(LoginActivity.this, "App download failed.", Toast.LENGTH_LONG).show();
}
}
In case when the user cancels resultCode == RESULT_CANCELED or the update fails resultCode == RESULT_IN_APP_UPDATE_FAILED, you can take whatever action you want. You can finish the activity or whatever is suitable in your situation.
I'm stuck and can't find a way to restart or reconnect the Bluetooth service in my app. The app has 3 fragments, tabs managed by FragmentPagerAdapter.
In the first fragment you can discover, associate and communicate with the BT device. In the second and third card it is necessary to interact with the device, it is not possible to get the connection or keep the service connected.
Here it goes the first fragment:
public class Conexiones extends Fragment implements ServiceConnection, SerialListener {
public BluetoothAdapter BTAdapter;
private ListView listView; // detectados
private ArrayList<String> mDeviceList;
public Button conectar, actualizar;
private ArrayAdapter m_DiscoveredPeersAdapter;
BluetoothDevice bdDevice;
BluetoothClass dbClass;
ArrayList<BluetoothDevice> listaBTDevices = null;
View view;
public SerialSocket socket;
public SerialService service;
public Conexiones(){
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
view = inflater.inflate(R.layout.fragment_conexiones, container, false );
BTAdapter = BluetoothAdapter.getDefaultAdapter();
listView = (ListView) this.view.findViewById(R.id.listView);
mDeviceList = new ArrayList<>();
m_DiscoveredPeersAdapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, mDeviceList);
listView.setAdapter(m_DiscoveredPeersAdapter);
listItemClicked = new ListItemClicked();
clicked = new ButtonClicked();
checkBTPermissions();
listaBTDevices = new ArrayList<BluetoothDevice>();
m_DiscoveredPeersAdapter.notifyDataSetChanged();
if (BTAdapter == null || !BTAdapter.isEnabled()) {
Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnOn, 1);
}
int MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 1;
ActivityCompat.requestPermissions(activity,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
if (BTAdapter.isEnabled()){
BTAdapter.startDiscovery();
Log.e("mio", "dp de star discovery");
}
else{
Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnOn, 1);
Log.e("mio", "no weisa");
}
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
activity.registerReceiver(mReceiver, filter);
return view;
}
#Override
public void onStart() {
Log.e("mio", "dentro de on start ");
dataInicialRecibida=false;
super.onStart();
//getPairedDevices();
this.conectar.setOnClickListener(clicked);
this.actualizar.setOnClickListener(clicked);
listView.setOnItemClickListener(listItemClicked);
MainActivity activity = (MainActivity) getActivity();
texto.setText("sistema listo");
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.i("BT", "recibe");
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
//discovery starts, we can show progress dialog or perform other tasks
Log.i("BT", "empezamos BT");
}
if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
//discovery starts, we can show progress dialog or perform other tasks
Log.i("BT", "terminiamos BT");
try {
Method getUuidsMethod = BluetoothAdapter.class.getDeclaredMethod("getUuids", null);
ParcelUuid[] uuids = (ParcelUuid[]) getUuidsMethod.invoke(BTAdapter, null);
if(uuids != null) {
for (ParcelUuid uuid : uuids) {
Log.d(TAG, "UUID: " + uuid.getUuid().toString());
miu=uuid.getUuid().toString();
}
}else{
Log.d(TAG, "Uuids not found, be sure to enable Bluetooth!");
}
}catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
//discovery starts, we can show progress dialog or perform other tasks
Log.i("BT", "state changed BT");
}
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// mDeviceList.add(device.getName() + "\n" + device.getAddress());
// DeviceItem newDevice = new DeviceItem(device.getName(), device.getAddress(), "false");
Log.i("BTN", device.getName() + "\n" + device.getAddress());
// mDeviceList.notifyDataSetChanged();
if(listaBTDevices.size()<1) // this checks if the size of bluetooth device is 0,then add the
{
Log.i("mio", "lista devices menor a 1");// device to the arraylist.
m_DiscoveredPeersAdapter.add(device.getName()+"\n"+device.getAddress());
listaBTDevices.add(device);
m_DiscoveredPeersAdapter.notifyDataSetChanged();
}
else
{
Log.i("mio", "lista devices maor o igual a 1");
boolean flag = true; // flag to indicate that particular device is already in the arlist or not
for(int i = 0; i<listaBTDevices.size();i++)
{
if(device.getAddress().equals(listaBTDevices.get(i).getAddress()))
{
flag = false;
}
}
if(flag == true)
{
m_DiscoveredPeersAdapter.add(device.getName()+"\n"+device.getAddress());
listaBTDevices.add(device);
m_DiscoveredPeersAdapter.notifyDataSetChanged();
}
}
}
listView.setAdapter(new ArrayAdapter<String>(context,
android.R.layout.simple_list_item_1, mDeviceList));
}
};
#RequiresApi(api = Build.VERSION_CODES.M)
private void checkBTPermissions() {
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP){
int permissionCheck =getActivity().checkSelfPermission("Manifest.permission.ACCESS_FINE_LOCATION");
permissionCheck += getActivity().checkSelfPermission("Manifest.permission.ACCESS_COARSE_LOCATION");
if (permissionCheck != 0) {
this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1001); //Any number
}
}else{
Log.d(TAG, "checkBTPermissions: No need to check permissions. SDK version < LOLLIPOP.");
}
}
#Override
public void onDestroy() {
MainActivity activity = (MainActivity) getActivity();
activity.unregisterReceiver(mReceiver);
super.onDestroy();
Log.e("mio", "on destroy ");
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK){
Log.d(TAG, "caso okookok.");
BTAdapter.startDiscovery();
}else{
Log.d(TAG, "cas no ok.");
}
}
#Override
public void onStop() {
super.onStop();
Log.e("mio", "on stop");
MainActivity activity = (MainActivity) getActivity();
activity.unregisterReceiver(mReceiver);
}
#Override
public void onServiceConnected(ComponentName name, IBinder binder) {
service = ((SerialService.SerialBinder) binder).getService();
Log.e("mio", "on service conectado conexiones ");
if(initialStart && isResumed()) {
initialStart = false;
getActivity().runOnUiThread(this::connect);
}
}
#Override
public void onServiceDisconnected(ComponentName name) {
service = null;
texto.setText("desconectado BT");
Log.e("mio", "desconectado BT conexiones");
}
#Override
public void onSerialConnect() {
texto.setText("conexion BT");
Log.e("mio", "conectado BT conexiones");
}
#Override
public void onSerialConnectError(Exception e) {
texto.setText("error conexion BT");
Log.e("mio", "onSerialConnectError");
}
#Override
public void onSerialRead(byte[] data) {
receive(data);
texto.setText("leyendo BT");
Log.e("mio", "leyendo BT ");
}
private void receive(byte[] data) {
receiveText+=new String(data);
receiveText="";
}
#Override
public void onSerialIoError(Exception e) {
texto.setText("error conexion BT");
}
class ButtonClicked implements View.OnClickListener
{
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.button:
listaBTDevices.clear();
m_DiscoveredPeersAdapter.clear();
startSearching();
texto.setText("buscando dispositivos BT");
break;
case R.id.button3:
break;
}
}
}
class ListItemClicked implements AdapterView.OnItemClickListener
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
bdDevice = listaBTDevices.get(position);
//bdClass = arrayListBluetoothDevices.get(position);
Log.i("Log", "The dvice : "+bdDevice.toString());
connect();
}
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager) service.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
private void getPairedDevices() {
// Set<BluetoothDevice> pairedDevice = BTAdapter.getBondedDevices();
// if(pairedDevice.size()>0)
{
// for(BluetoothDevice device : pairedDevice)
{
// arrayListpaired.add(device.getName()+"\n"+device.getAddress());
// arrayListPairedBluetoothDevices.add(device);
}
}
// adapter.notifyDataSetChanged();
}
public void send(String str) {
try {
SpannableStringBuilder spn = new SpannableStringBuilder(str+'\n');
byte[] data = (str).getBytes();
socket.write(data);
} catch (Exception e) {
onSerialIoError(e);
}
}
#SuppressWarnings("deprecation")
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// getActivity().bindService(new Intent(getActivity(), SerialService.class), this, Context.BIND_AUTO_CREATE);
}
private void connect() {
try {
BTAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = BTAdapter .getRemoteDevice(bdDevice.getAddress());
String deviceName = device.getName() != null ? device.getName() : device.getAddress();
socket = new SerialSocket();
service.connect(this, "Connected to " + deviceName);
socket.connect(getContext(), service, device);
MainActivity activity = (MainActivity) getActivity();
activity.setidEquipo(bdDevice.getAddress());
// conexión ok, cambiar color letras boton
} catch (Exception e) {
//onSerialConnectError(e);
Log.i("mio", "error del connect "+e);
// sino hay conexión mantener boton con letras naranjas
}
}
private void startSearching() {
Log.i("Log", "in the start searching method");
MainActivity activity = (MainActivity) getActivity();
IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
activity.registerReceiver(mReceiver, intentFilter);
BTAdapter.startDiscovery();
}
private void onBluetooth() {
if(!BTAdapter.isEnabled())
{
BTAdapter.enable();
Log.i("Log", "Bluetooth is Enabled");
}
}
private void offBluetooth() {
if(BTAdapter.isEnabled())
{
BTAdapter.disable();
}
}
}
The serial service:
public class SerialService extends Service implements SerialListener {
class SerialBinder extends Binder {
SerialService getService() { return SerialService.this; }
}
private enum QueueType {Connect, ConnectError, Read, IoError}
private class QueueItem {
QueueType type;
byte[] data;
Exception e;
QueueItem(QueueType type, byte[] data, Exception e) { this.type=type; this.data=data; this.e=e; }
}
private final Handler mainLooper;
private final IBinder binder;
private final Queue<QueueItem> queue1, queue2;
private SerialListener listener;
private boolean connected;
private String notificationMsg;
public SerialService() {
mainLooper = new Handler(Looper.getMainLooper());
binder = new SerialBinder();
queue1 = new LinkedList<>();
queue2 = new LinkedList<>();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return binder;
}
public void connect(SerialListener listener, String notificationMsg) {
this.listener = listener;
connected = true;
this.notificationMsg = notificationMsg;
}
public void disconnect() {
listener = null;
connected = false;
notificationMsg = null;
}
public void attach(SerialListener listener) {
if(Looper.getMainLooper().getThread() != Thread.currentThread())
throw new IllegalArgumentException("not in main thread");
cancelNotification();
// use synchronized() to prevent new items in queue2
// new items will not be added to queue1 because mainLooper.post and attach() run in main thread
if(connected) {
synchronized (this) {
this.listener = listener;
}
}
for(QueueItem item : queue1) {
switch(item.type) {
case Connect: listener.onSerialConnect (); break;
case ConnectError: listener.onSerialConnectError (item.e); break;
case Read: listener.onSerialRead (item.data); break;
case IoError: listener.onSerialIoError (item.e); break;
}
}
for(QueueItem item : queue2) {
switch(item.type) {
case Connect: listener.onSerialConnect (); break;
case ConnectError: listener.onSerialConnectError (item.e); break;
case Read: listener.onSerialRead (item.data); break;
case IoError: listener.onSerialIoError (item.e); break;
}
}
queue1.clear();
queue2.clear();
}
public void detach() {
if(connected)
createNotification();
// items already in event queue (posted before detach() to mainLooper) will end up in queue1
// items occurring later, will be moved directly to queue2
// detach() and mainLooper.post run in the main thread, so all items are caught
listener = null;
}
public void onSerialConnect() {
Log.i("mio", "dentro on serial connect ");
if(connected) {
Log.i("mio", "dentro de connected ");
synchronized (this) {
if (listener != null) {
mainLooper.post(() -> {
if (listener != null) {
listener.onSerialConnect();
} else {
queue1.add(new QueueItem(QueueType.Connect, null, null));
}
});
} else {
queue2.add(new QueueItem(QueueType.Connect, null, null));
}
}
}
}
public void onSerialConnectError(Exception e) {
if(connected) {
synchronized (this) {
if (listener != null) {
mainLooper.post(() -> {
if (listener != null) {
listener.onSerialConnectError(e);
} else {
queue1.add(new QueueItem(QueueType.ConnectError, null, e));
cancelNotification();
disconnect();
}
});
} else {
queue2.add(new QueueItem(QueueType.ConnectError, null, e));
cancelNotification();
disconnect();
}
}
}
}
public void onSerialRead(byte[] data) {
if(connected) {
synchronized (this) {
if (listener != null) {
mainLooper.post(() -> {
if (listener != null) {
listener.onSerialRead(data);
} else {
queue1.add(new QueueItem(QueueType.Read, data, null));
}
});
} else {
queue2.add(new QueueItem(QueueType.Read, data, null));
}
}
}
}
public void onSerialIoError(Exception e) {
if(connected) {
synchronized (this) {
if (listener != null) {
mainLooper.post(() -> {
if (listener != null) {
listener.onSerialIoError(e);
} else {
queue1.add(new QueueItem(QueueType.IoError, null, e));
cancelNotification();
disconnect();
}
});
} else {
queue2.add(new QueueItem(QueueType.IoError, null, e));
cancelNotification();
disconnect();
}
}
}
}
}
The serial socket class:
class SerialSocket implements Runnable {
private static final UUID BLUETOOTH_SPP = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private final BroadcastReceiver disconnectBroadcastReceiver;
private Context context;
private SerialListener listener;
private BluetoothDevice device;
private BluetoothSocket socket;
private boolean connected;
SerialSocket() {
disconnectBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(listener != null)
listener.onSerialIoError(new IOException("background disconnect"));
disconnect(); // disconnect now, else would be queued until UI re-attached
}
};
}
/**
* connect-success and most connect-errors are returned asynchronously to listener
*/
void connect(Context context, SerialListener listener, BluetoothDevice device) throws IOException {
if(connected || socket != null)
throw new IOException("already connected");
this.context = context;
this.listener = listener;
this.device = device;
context.registerReceiver(disconnectBroadcastReceiver, new IntentFilter(Constants.INTENT_ACTION_DISCONNECT));
Executors.newSingleThreadExecutor().submit(this);
}
void disconnect() {
listener = null; // ignore remaining data and errors
// connected = false; // run loop will reset connected
if(socket != null) {
try {
socket.close();
} catch (Exception ignored) {
}
socket = null;
}
try {
context.unregisterReceiver(disconnectBroadcastReceiver);
} catch (Exception ignored) {
}
}
void write(byte[] data) throws IOException {
if (!connected)
throw new IOException("not connected");
socket.getOutputStream().write(data);
}
#Override
public void run() { // connect & read
try {
socket = device.createRfcommSocketToServiceRecord(BLUETOOTH_SPP);
socket.connect();
if(listener != null)
listener.onSerialConnect();
} catch (Exception e) {
if(listener != null)
listener.onSerialConnectError(e);
try {
socket.close();
} catch (Exception ignored) {
}
socket = null;
return;
}
connected = true;
try {
byte[] buffer = new byte[1024];
int len;
//noinspection InfiniteLoopStatement
while (true) {
len = socket.getInputStream().read(buffer);
byte[] data = Arrays.copyOf(buffer, len);
if(listener != null)
listener.onSerialRead(data);
}
} catch (Exception e) {
connected = false;
if (listener != null)
listener.onSerialIoError(e);
try {
socket.close();
} catch (Exception ignored) {
}
socket = null;
}
}
}
And the second fragment whereas I need to keep connection or connect to the same device already connected in fragment ("conexiones"):
public class Identificacion extends Fragment implements ServiceConnection, SerialListener {
private String deviceAddress;
private String newline = "\r\n";
private String receiveText;
private enum Connected { False, Pending, True }
private String sendText;
private SerialSocket socket;
private SerialService service;
private boolean initialStart = true;
private Connected connected = Connected.False;
// constructor requerido vacio
public Identificacion(){
}
#Override
public void onCreate(Bundle savedInstanceState) {
Log.e("mio", "dentro on creata identificacion");
super.onCreate(savedInstanceState);
setRetainInstance(true);
// deviceAddress = getArguments().getString("device");
}
#SuppressWarnings("deprecation") // onAttach(context) was added with API 23. onAttach(activity) works for all API versions
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
getActivity().bindService(new Intent(getActivity(), SerialService.class), this, Context.BIND_AUTO_CREATE);
}
#Override
public void onDetach() {
try { getActivity().unbindService(this); } catch(Exception ignored) {}
super.onDetach();
}
#Override
public void onResume() {
super.onResume();
/* if(initialStart && service !=null) {
initialStart = false;
getActivity().runOnUiThread(this::connect);
} */
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
view = inflater.inflate(R.layout.fragment_identificacion, container, false );
return view;
}
private void addListenerOnButton() {
bt12.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
EditText txtView = (EditText) aux1;
EditText txtView2 = (EditText) aux2;
TextView txtView3 = (TextView) aux3;
if (pin2 != null && pin2.length() == largo && pin4 != null && pin4.length() == largo){
//consultar BD si exta bien la pass, caso si:
Log.e("mio", "dentro de pin y pass con formato " + pin2);
pin=pin2;
String aenvio=(String)pin2+";"+pin4;
// enviar pin por BT
connect();
send(aenvio);
}
}
});
}// fin add listener button
private void connect() {
try {
MainActivity activity = (MainActivity) getActivity();
String par3= activity.getidEquipo();
deviceAddress=par3;
Log.e("mio", "connect identif valor deviceAddress "+deviceAddress);
//deviceAddress = getArguments().getString("device");
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceAddress);
String deviceName = device.getName() != null ? device.getName() : device.getAddress();
// status("connecting...");
Log.e("mio", "connect identif deviceName "+deviceName);
connected = Connected.Pending;
onAttach(activity);
// socket =
//socket = new SerialSocket();
getActivity().bindService(new Intent(getActivity(), SerialService.class ), this, Context.BIND_ADJUST_WITH_ACTIVITY );
service.connect(this, "Connected to " + deviceName);
socket.connect(getContext(), service, device);
connected = Connected.True;
Log.e("mio", "connect identif salida "+deviceName);
} catch (Exception e) {
onSerialConnectError(e);
}
}
private void send(String str) {
if(connected != Connected.True) {
Toast.makeText(getActivity(), "not connected", Toast.LENGTH_SHORT).show();
Log.e("mio", "dentro send no conectado "+str);
// return;
}
try {
connect();
// SpannableStringBuilder spn = new SpannableStringBuilder(str+'\n');
Log.e("mio", "send conectado "+str);
// spn.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.colorSendText)), 0, spn.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Toast.makeText(getActivity(), "enviando login a esp", Toast.LENGTH_SHORT).show();
sendText=str; // poner aca el string de user;pass a enviar al esp32 app
byte[] data = (str + newline).getBytes();
socket.write(data);
} catch (Exception e) {
onSerialIoError(e);
}
}
private void receive(byte[] data) {
receiveText+=(new String(data));
}
#Override
public void onServiceConnected(ComponentName name, IBinder binder) {
service = ((SerialService.SerialBinder) binder).getService();
if(initialStart && isResumed()) {
initialStart = false;
getActivity().runOnUiThread(this::connect);
}
}
#Override
public void onServiceDisconnected(ComponentName name) {
service = null;
}
#Override
public void onSerialRead(byte[] data) {
Log.e("mio", "serial leer data ");
receive(data);
}
#Override
public void onSerialIoError(Exception e) {
Log.e("mio", "serial io error, desconectar ");
disconnect();
}
}
Managing code when you are using Bluetooth or system-related task is too hard because it creates a tightly coupled code eventually turn into the buggy code. So you can use this and this libraries to do your task neat and cleanly. Please check the example app for my suggested first and second libraries. If you face any struck in implementation let me know.
Run service from an activity or from the App class.
upd:
Or use singleton as a main point to communicate with the BluetoothHelper
I solved this of my way, by keeping the bluetooth socket static.
I've setted the 'boolean' object {TRUE, PENDING, FALSE}, in service and handled this object with service listener in others activities.
in the activities i unbind the service but do not disconnect socket, but as i don't disconnect from socket when change activities, there's a memory leak, but for me isn't a problem.
result:
the socket keeps connected and i can access the device from all activities, and the error handling (discconect, bluetooth off) happens thanks to listener
Create a service running in a different process not the main app process. Communicate with main app and service using broadcast receivers. This makes sure you can be anywhere in main app but you can still interact with Ble service
solved moving all the bluetooth code: broadcast receiver, service instance and socket instance, to the main activity, then in the fragments the service is attached (bind service) or (if null) started again.
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
Log.e("mio", "dentro de is visible to user identif ");
// connect();
if(service != null){
service.attach(this);
Log.e("mio", "caso attach ");
}
else{
Log.e("mio", "caso start service 1 ");
getActivity().startService(new Intent(getActivity(), SerialService.class)); // prevents service destroy on unbind from recreated activity caused by orientation change
// service.attach(this);
}
This solves the problem nice and easy, so the service is available when user see data in the fragment, and communication is well received and sent.
I wanted my Android to communicate with an Arduino using an USB host. I've tried many references but can't seem to send any char to my Arduino. I can detect my Arduino but sending char or string to it is frustrating. Here are my codes:
MainActivity.java
public class MainActivity extends AppCompatActivity {
UsbDevice device=null;
UsbManager manager=null;
PendingIntent mPermissionIntent;
UsbInterface intf;
UsbEndpoint endpoint;
UsbDeviceConnection connection;
Button find;
Button send;
TextView hello;
UsbManager mUsbManager;
private static final String ACTION_USB_PERMISSION =
"com.android.example.USB_PERMISSION";
private byte[] bytes;
private static int TIMEOUT = 0;
private boolean forceClaim = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
find = (Button) findViewById(R.id.Find);
send = (Button) findViewById(R.id.Send);
hello = (TextView) findViewById(R.id.hello);
find.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
hello.setText("");
checkInfo();
}
});
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(device!=null) {
intf = device.getInterface(0);
endpoint = intf.getEndpoint(0);
connection = mUsbManager.openDevice(device);
hello.setText("Kirim");
String kirim = "a";
bytes = kirim.getBytes();
connection.claimInterface(intf, forceClaim);
connection.bulkTransfer(endpoint, bytes, bytes.length, 0);
}
else{
Toast.makeText(MainActivity.this,"Device ==
null",Toast.LENGTH_SHORT);
}
}
});
private void checkInfo(){
manager=(UsbManager) getSystemService(Context.USB_SERVICE);
mPermissionIntent = PendingIntent.getBroadcast(this,0,new
Intent(ACTION_USB_PERMISSION),0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver,filter);
HashMap<String,UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
String i="";
int j=0;
while(deviceIterator.hasNext()){
device = deviceIterator.next();
manager.requestPermission(device,mPermissionIntent);
i += "\n" + "DeviceID: " + device.getDeviceId() + "\n"
+ "DeviceName: " + device.getDeviceName() + "\n"
+ "DeviceClass: " + device.getDeviceClass() + " - "
+ "DeviceSubClass: " + device.getDeviceSubclass() + "\n"
+ "VendorID: " + device.getVendorId() + "\n"
+ "ProductID: " + device.getProductId() + "\n";
j++;
}
hello.setText(i);
}
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice) intent
.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(
UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (device != null) {
// call method to set up device communication
}
} else {
Log.d("ERROR", "permission denied for device " +
device);
}
}
}
}
};
}
I iterate using a find button and send using a send button. The iteration went just fine, but the sending didn't work. I needed to send just a character to the Arduino. My phone supports OTG and had been tested using other serial communication application to send char to Arduino and it works just fine.
Thanks in advance
using the usb serial lib in releases section at: https://github.com/felHR85/UsbSerial then import the lib and install dependencies as shown in the url. For solving the problem you can create a service class that handles usb related stuff (look at usb host android documentation for details: https://developer.android.com/guide/topics/connectivity/usb/host.html
as follows:
public class UsbService extends Service {
public static final String TAG = "UsbService";
public static final String ACTION_USB_READY = "com.felhr.connectivityservices.USB_READY";
public static final String ACTION_USB_ATTACHED = "android.hardware.usb.action.USB_DEVICE_ATTACHED";
public static final String ACTION_USB_DETACHED = "android.hardware.usb.action.USB_DEVICE_DETACHED";
public static final String ACTION_USB_NOT_SUPPORTED = "com.felhr.usbservice.USB_NOT_SUPPORTED";
public static final String ACTION_NO_USB = "com.felhr.usbservice.NO_USB";
public static final String ACTION_USB_PERMISSION_GRANTED = "com.felhr.usbservice.USB_PERMISSION_GRANTED";
public static final String ACTION_USB_PERMISSION_NOT_GRANTED = "com.felhr.usbservice.USB_PERMISSION_NOT_GRANTED";
public static final String ACTION_USB_DISCONNECTED = "com.felhr.usbservice.USB_DISCONNECTED";
public static final String ACTION_CDC_DRIVER_NOT_WORKING = "com.felhr.connectivityservices.ACTION_CDC_DRIVER_NOT_WORKING";
public static final String ACTION_USB_DEVICE_NOT_WORKING = "com.felhr.connectivityservices.ACTION_USB_DEVICE_NOT_WORKING";
public static final int MESSAGE_FROM_SERIAL_PORT = 0;
public static final int CTS_CHANGE = 1;
public static final int DSR_CHANGE = 2;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private static final int BAUD_RATE = 9600; // BaudRate. Change this value if you need
public static boolean SERVICE_CONNECTED = false;
private IBinder binder = new UsbBinder();
private UsbService context;
private Handler mHandler;
private UsbManager usbManager;
private UsbDevice device;
private UsbDeviceConnection connection;
private UsbSerialDevice serialPort;
private boolean serialPortConnected;
/*
* Data received from serial port will be received here. Just populate onReceivedData with your code
* In this particular example. byte stream is converted to String and send to UI thread to
* be treated there.
*/
private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
#Override
public void onReceivedData(byte[] arg0) {
try {
String data = new String(arg0, "UTF-8");
if (mHandler != null)
mHandler.obtainMessage(MESSAGE_FROM_SERIAL_PORT, data).sendToTarget();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
};
/*
* State changes in the CTS line will be received here
*/
private UsbSerialInterface.UsbCTSCallback ctsCallback = new UsbSerialInterface.UsbCTSCallback() {
#Override
public void onCTSChanged(boolean state) {
if(mHandler != null)
mHandler.obtainMessage(CTS_CHANGE).sendToTarget();
}
};
/*
* State changes in the DSR line will be received here
*/
private UsbSerialInterface.UsbDSRCallback dsrCallback = new UsbSerialInterface.UsbDSRCallback() {
#Override
public void onDSRChanged(boolean state) {
if(mHandler != null)
mHandler.obtainMessage(DSR_CHANGE).sendToTarget();
}
};
/*
* Different notifications from OS will be received here (USB attached, detached, permission responses...)
* About BroadcastReceiver: http://developer.android.com/reference/android/content/BroadcastReceiver.html
*/
private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context arg0, Intent arg1) {
if (arg1.getAction().equals(ACTION_USB_PERMISSION)) {
boolean granted = arg1.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED);
if (granted) // User accepted our USB connection. Try to open the device as a serial port
{
Intent intent = new Intent(ACTION_USB_PERMISSION_GRANTED);
arg0.sendBroadcast(intent);
connection = usbManager.openDevice(device);
new ConnectionThread().start();
} else // User not accepted our USB connection. Send an Intent to the Main Activity
{
Intent intent = new Intent(ACTION_USB_PERMISSION_NOT_GRANTED);
arg0.sendBroadcast(intent);
}
} else if (arg1.getAction().equals(ACTION_USB_ATTACHED)) {
if (!serialPortConnected)
findSerialPortDevice(); // A USB device has been attached. Try to open it as a Serial port
} else if (arg1.getAction().equals(ACTION_USB_DETACHED)) {
// Usb device was disconnected. send an intent to the Main Activity
Intent intent = new Intent(ACTION_USB_DISCONNECTED);
arg0.sendBroadcast(intent);
if (serialPortConnected) {
serialPort.close();
}
serialPortConnected = false;
}
}
};
/*
* onCreate will be executed when service is started. It configures an IntentFilter to listen for
* incoming Intents (USB ATTACHED, USB DETACHED...) and it tries to open a serial port.
*/
#Override
public void onCreate() {
this.context=this;
serialPortConnected = false;
UsbService.SERVICE_CONNECTED = true;
setFilter();
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
findSerialPortDevice();
}
/* MUST READ about services
* http://developer.android.com/guide/components/services.html
* http://developer.android.com/guide/components/bound-services.html
*/
#Override
public IBinder onBind(Intent intent) {
return binder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
serialPort.close();
unregisterReceiver(usbReceiver);
UsbService.SERVICE_CONNECTED = false;
}
/*
* This function will be called from MainActivity to write data through Serial Port
*/
public void write(byte[] data) {
if (serialPort != null)
serialPort.write(data);
}
public void setHandler(Handler mHandler) {
this.mHandler = mHandler;
}
private void findSerialPortDevice() {
// This snippet will try to open the first encountered usb device connected, excluding usb root hubs
HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList();
if (!usbDevices.isEmpty()) {
// first, dump the hashmap for diagnostic purposes
for (Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) {
device = entry.getValue();
Log.d(TAG, String.format("USBDevice.HashMap (vid:pid) (%X:%X)-%b class:%X:%X name:%s",
device.getVendorId(), device.getProductId(),
UsbSerialDevice.isSupported(device),
device.getDeviceClass(), device.getDeviceSubclass(),
device.getDeviceName()));
}
for (Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) {
device = entry.getValue();
int deviceVID = device.getVendorId();
int devicePID = device.getProductId();
// if (deviceVID != 0x1d6b && (devicePID != 0x0001 && devicePID != 0x0002 && devicePID != 0x0003) && deviceVID != 0x5c6 && devicePID != 0x904c) {
if (UsbSerialDevice.isSupported(device)) {
// There is a supported device connected - request permission to access it.
requestUserPermission();
break;
} else {
connection = null;
device = null;
}
}
if (device==null) {
// There are no USB devices connected (but usb host were listed). Send an intent to MainActivity.
Intent intent = new Intent(ACTION_NO_USB);
sendBroadcast(intent);
}
} else {
Log.d(TAG, "findSerialPortDevice() usbManager returned empty device list." );
// There is no USB devices connected. Send an intent to MainActivity
Intent intent = new Intent(ACTION_NO_USB);
sendBroadcast(intent);
}
}
private void setFilter() {
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_USB_PERMISSION);
filter.addAction(ACTION_USB_DETACHED);
filter.addAction(ACTION_USB_ATTACHED);
registerReceiver(usbReceiver, filter);
}
/*
* Request user permission. The response will be received in the BroadcastReceiver
*/
private void requestUserPermission() {
Log.d(TAG, String.format("requestUserPermission(%X:%X)", device.getVendorId(), device.getProductId() ) );
PendingIntent mPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
usbManager.requestPermission(device, mPendingIntent);
}
public class UsbBinder extends Binder {
public UsbService getService() {
return UsbService.this;
}
}
/*
* A simple thread to open a serial port.
* Although it should be a fast operation. moving usb operations away from UI thread is a good thing.
*/
private class ConnectionThread extends Thread {
#Override
public void run() {
serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection);
if (serialPort != null) {
if (serialPort.open()) {
serialPortConnected = true;
serialPort.setBaudRate(BAUD_RATE);
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
/**
* Current flow control Options:
* UsbSerialInterface.FLOW_CONTROL_OFF
* UsbSerialInterface.FLOW_CONTROL_RTS_CTS only for CP2102 and FT232
* UsbSerialInterface.FLOW_CONTROL_DSR_DTR only for CP2102 and FT232
*/
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
serialPort.read(mCallback);
serialPort.getCTS(ctsCallback);
serialPort.getDSR(dsrCallback);
//
// Some Arduinos would need some sleep because firmware wait some time to know whether a new sketch is going
// to be uploaded or not
//Thread.sleep(2000); // sleep some. YMMV with different chips.
// Everything went as expected. Send an intent to MainActivity
Intent intent = new Intent(ACTION_USB_READY);
context.sendBroadcast(intent);
} else {
// Serial port could not be opened, maybe an I/O error or if CDC driver was chosen, it does not really fit
// Send an Intent to Main Activity
if (serialPort instanceof CDCSerialDevice) {
Intent intent = new Intent(ACTION_CDC_DRIVER_NOT_WORKING);
context.sendBroadcast(intent);
} else {
Intent intent = new Intent(ACTION_USB_DEVICE_NOT_WORKING);
context.sendBroadcast(intent);
}
}
} else {
// No driver for given device, even generic CDC driver could not be loaded
Intent intent = new Intent(ACTION_USB_NOT_SUPPORTED);
context.sendBroadcast(intent);
}
}
}
}
then in your main activity put this snippets:
java
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case UsbService.ACTION_USB_PERMISSION_GRANTED: // USB PERMISSION GRANTED
Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_PERMISSION_NOT_GRANTED: // USB PERMISSION NOT GRANTED
Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_NO_USB: // NO USB CONNECTED
Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_DISCONNECTED: // USB DISCONNECTED
Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_NOT_SUPPORTED: // USB NOT SUPPORTED
Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show();
break;
}
}
};
private UsbService usbService;
public TextView display;
private EditText editText;
private MyHandler mHandler;
private final ServiceConnection usbConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
usbService = ((UsbService.UsbBinder) arg1).getService();
usbService.setHandler(mHandler);
// Toast.makeText(getApplicationContext(),"dentro on service connected " + usbService, Toast.LENGTH_SHORT).show();
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
usbService = null;
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.operacion);
mHandler = new MyHandler(this);
// your stuff here
#Override
public void onResume() {
super.onResume();
// Toast.makeText(getApplicationContext(),"on resume ", Toast.LENGTH_SHORT).show();
setFilters(); // Start listening notifications from UsbService
startService(UsbService.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it
// Toast.makeText(getApplicationContext(),"despues de start y weas ", Toast.LENGTH_SHORT).show();
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(mUsbReceiver);
unbindService(usbConnection);
}
private void startService(Class<?> service, ServiceConnection serviceConnection, Bundle extras) {
// Toast.makeText(getApplicationContext(),"start1", Toast.LENGTH_SHORT).show();
if (!UsbService.SERVICE_CONNECTED) {
Intent startService = new Intent(this, service);
if (extras != null && !extras.isEmpty()) {
Set<String> keys = extras.keySet();
for (String key : keys) {
String extra = extras.getString(key);
startService.putExtra(key, extra);
}
}
startService(startService);
// Toast.makeText(getApplicationContext(),"dp metodo start", Toast.LENGTH_SHORT).show();
}
Intent bindingIntent = new Intent(this, service);
bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
private void setFilters() {
IntentFilter filter = new IntentFilter();
filter.addAction(UsbService.ACTION_USB_PERMISSION_GRANTED);
filter.addAction(UsbService.ACTION_NO_USB);
filter.addAction(UsbService.ACTION_USB_DISCONNECTED);
filter.addAction(UsbService.ACTION_USB_NOT_SUPPORTED);
filter.addAction(UsbService.ACTION_USB_PERMISSION_NOT_GRANTED);
registerReceiver(mUsbReceiver, filter);
}
public void getCurrentTimeUsingDate(){
String currentDateTimeString2 = DateFormat.getDateInstance().format(new Date());
TextView txtView3 = (TextView) findViewById(R.id.textView4);
txtView3.setText(""+currentDateTimeString2);
}
private static class MyHandler extends Handler {
private final WeakReference<Pag4> mActivity;
public MyHandler(Pag4 activity) {
mActivity = new WeakReference<>(activity);
}
Integer conta = 0;
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UsbService.MESSAGE_FROM_SERIAL_PORT:
String data = (String) msg.obj;
conta++;
break;
case UsbService.CTS_CHANGE:
Toast.makeText(mActivity.get(), "CTS_CHANGE",Toast.LENGTH_LONG).show();
break;
case UsbService.DSR_CHANGE:
Toast.makeText(mActivity.get(), "DSR_CHANGE",Toast.LENGTH_LONG).show();
break;
}
}
}
}
you make a button (btn3 in the example) and then add the listener as follows:
java
bt3.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
String auxi2="1"; // put whatever you need to send here
if (!auxi2.equals("")) {
String data = auxi2;
if (usbService != null) { // if UsbService was correctly binded, Send data
usbService.write(data.getBytes());
// Toast.makeText(getApplicationContext(),"auxi2 escrito"+ auxi2, Toast.LENGTH_SHORT).show();
}
}
}
});
Hope is clear, I assume you know how to import libs, and make a button, put the permission in manifiest, dependencies. Details about this in android doc link already posted upper in my answer.
I'm trying to create a service that will play music in the background, but when a song completes the nextone should be played but seems oncomplete listener is not called. Can anyone tell me where is the problem?
P.S. I don't get anything in logcat, and I dont get the log that should be shown when entering oncomplete listener.
Here is my code:
public class myPlayService extends Service implements OnCompletionListener,
OnPreparedListener, OnErrorListener, OnSeekCompleteListener,
OnInfoListener, OnBufferingUpdateListener {
private static final String TAG = "--";
public static MediaPlayer mediaPlayer = new MediaPlayer();
// songs
private static ArrayList<Songs> songs;
private static int position;
// Set up the notification ID
private static final int NOTIFICATION_ID = 1;
private boolean isPausedInCall = false;
private PhoneStateListener phoneStateListener;
private TelephonyManager telephonyManager;
// ---Variables for seekbar processing---
String sntSeekPos;
static int intSeekPos;
int mediaPosition;
int mediaMax;
// Intent intent;
private final Handler handler = new Handler();
private static int songEnded;
public static boolean serviceStarted=false;
public static final String BROADCAST_ACTION = "com.darkovski.quran.seekprogress";
// Set up broadcast identifier and intent
public static final String BROADCAST_BUFFER = "com.darkovski.quran.broadcastbuffer";
Intent bufferIntent;
Intent seekIntent;
// Declare headsetSwitch variable
private int headsetSwitch = 1;
// OnCreate
#Override
public void onCreate() {
Log.v(TAG, "Creating Service");
// android.os.Debug.waitForDebugger();
// Instantiate bufferIntent to communicate with Activity for progress
// dialogue
serviceStarted=true;
songs = new ArrayList<Songs>();
bufferIntent = new Intent(BROADCAST_BUFFER);
// ---Set up intent for seekbar broadcast ---
seekIntent = new Intent(BROADCAST_ACTION);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnSeekCompleteListener(this);
mediaPlayer.setOnInfoListener(this);
mediaPlayer.reset();
// Register headset receiver
registerReceiver(headsetReceiver, new IntentFilter(
Intent.ACTION_HEADSET_PLUG));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// get songs and position
songs = new ArrayList<Songs>();
songs = (ArrayList<Songs>) intent.getSerializableExtra("songs");
Log.v("--", songs.size() + " size!#$");
position = intent.getIntExtra("position", -1);
// ---Set up receiver for seekbar change ---
registerReceiver(broadcastReceiver, new IntentFilter(
Player.BROADCAST_SEEKBAR));
// Manage incoming phone calls during playback. Pause mp on incoming,
// resume on hangup.
// -----------------------------------------------------------------------------------
// Get the telephony manager
Log.v(TAG, "Starting telephony");
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
Log.v(TAG, "Starting listener");
phoneStateListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
// String stateString = "N/A";
Log.v(TAG, "Starting CallStateChange");
switch (state) {
case TelephonyManager.CALL_STATE_OFFHOOK:
case TelephonyManager.CALL_STATE_RINGING:
if (mediaPlayer != null) {
pauseMedia();
isPausedInCall = true;
}
break;
case TelephonyManager.CALL_STATE_IDLE:
// Phone idle. Start playing.
if (mediaPlayer != null) {
if (isPausedInCall) {
isPausedInCall = false;
playMedia();
}
}
break;
}
}
};
// Register the listener with the telephony manager
telephonyManager.listen(phoneStateListener,
PhoneStateListener.LISTEN_CALL_STATE);
// Insert notification start
initNotification();
mediaPlayer.reset();
// Set up the MediaPlayer data source using the strAudioLink value
if (!mediaPlayer.isPlaying()) {
try {
// Send message to Activity to display progress dialogue
sendBufferingBroadcast();
mediaPlayer.setDataSource(songs.get(position).getLink());
;
// Prepare mediaplayer
mediaPlayer.prepare();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
}
}
// --- Set up seekbar handler ---
setupHandler();
return START_STICKY;
}
// ---Send seekbar info to activity----
private void setupHandler() {
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 300); // 1 second
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
// // Log.d(TAG, "entered sendUpdatesToUI");
LogMediaPosition();
handler.postDelayed(this, 1000); // 2 seconds
}
};
private void LogMediaPosition() {
// // Log.d(TAG, "entered LogMediaPosition");
if (mediaPlayer.isPlaying()) {
mediaPosition = mediaPlayer.getCurrentPosition();
// if (mediaPosition < 1) {
// Toast.makeText(this, "Buffering...", Toast.LENGTH_SHORT).show();
// }
mediaMax = mediaPlayer.getDuration();
// seekIntent.putExtra("time", new Date().toLocaleString());
seekIntent.putExtra("counter", String.valueOf(mediaPosition));
seekIntent.putExtra("mediamax", String.valueOf(mediaMax));
seekIntent.putExtra("song_ended", String.valueOf(songEnded));
sendBroadcast(seekIntent);
}
}
// --Receive seekbar position if it has been changed by the user in the
// activity
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateSeekPos(intent);
}
};
// Update seek position from Activity
public void updateSeekPos(Intent intent) {
int seekPos = intent.getIntExtra("seekpos", 0);
if (mediaPlayer.isPlaying()) {
handler.removeCallbacks(sendUpdatesToUI);
mediaPlayer.seekTo(seekPos);
setupHandler();
}
}
// ---End of seekbar code
// If headset gets unplugged, stop music and service.
private BroadcastReceiver headsetReceiver = new BroadcastReceiver() {
private boolean headsetConnected = false;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// Log.v(TAG, "ACTION_HEADSET_PLUG Intent received");
if (intent.hasExtra("state")) {
if (headsetConnected && intent.getIntExtra("state", 0) == 0) {
headsetConnected = false;
headsetSwitch = 0;
// Log.v(TAG, "State = Headset disconnected");
// headsetDisconnected();
} else if (!headsetConnected
&& intent.getIntExtra("state", 0) == 1) {
headsetConnected = true;
headsetSwitch = 1;
// Log.v(TAG, "State = Headset connected");
}
}
switch (headsetSwitch) {
case (0):
headsetDisconnected();
break;
case (1):
break;
}
}
};
private void headsetDisconnected() {
stopMedia();
stopSelf();
}
// --- onDestroy, stop media player and release. Also stop
// phoneStateListener, notification, receivers...---
#Override
public void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
mediaPlayer.release();
}
if (phoneStateListener != null) {
telephonyManager.listen(phoneStateListener,
PhoneStateListener.LISTEN_NONE);
}
// Cancel the notification
cancelNotification();
// Unregister headsetReceiver
unregisterReceiver(headsetReceiver);
// Unregister seekbar receiver
unregisterReceiver(broadcastReceiver);
// Stop the seekbar handler from sending updates to UI
handler.removeCallbacks(sendUpdatesToUI);
// Service ends, need to tell activity to display "Play" button
resetButtonPlayStopBroadcast();
}
// Send a message to Activity that audio is being prepared and buffering
// started.
private void sendBufferingBroadcast() {
// Log.v(TAG, "BufferStartedSent");
bufferIntent.putExtra("buffering", "1");
sendBroadcast(bufferIntent);
}
// Send a message to Activity that audio is prepared and ready to start
// playing.
private void sendBufferCompleteBroadcast() {
// Log.v(TAG, "BufferCompleteSent");
bufferIntent.putExtra("buffering", "0");
sendBroadcast(bufferIntent);
}
// Send a message to Activity to reset the play button.
private void resetButtonPlayStopBroadcast() {
// Log.v(TAG, "BufferCompleteSent");
bufferIntent.putExtra("buffering", "2");
sendBroadcast(bufferIntent);
}
#Override
public void onBufferingUpdate(MediaPlayer arg0, int arg1) {
// TODO Auto-generated method stub
}
#Override
public boolean onInfo(MediaPlayer arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
return false;
}
#Override
public void onSeekComplete(MediaPlayer mp) {
if (!mediaPlayer.isPlaying()) {
playMedia();
Toast.makeText(this, "SeekComplete", Toast.LENGTH_SHORT).show();
}
}
// ---Error processing ---
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
switch (what) {
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
Toast.makeText(this,
"MEDIA ERROR NOT VALID FOR PROGRESSIVE PLAYBACK " + extra,
Toast.LENGTH_SHORT).show();
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Toast.makeText(this, "MEDIA ERROR SERVER DIED " + extra,
Toast.LENGTH_SHORT).show();
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Toast.makeText(this, "MEDIA ERROR UNKNOWN " + extra,
Toast.LENGTH_SHORT).show();
break;
}
return false;
}
#Override
public void onPrepared(MediaPlayer arg0) {
// Send a message to activity to end progress dialogue
sendBufferCompleteBroadcast();
playMedia();
}
#Override
public void onCompletion(MediaPlayer mp) {
// When song ends, need to tell activity to display "Play" button
position += 1;
mp.stop();
mp.release();
Log.v("--", "complete");
// stopMedia();
playMedia();
// stopSelf();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public static void pause() {
mediaPlayer.pause();
}
public static void resume(){
mediaPlayer.start();
}
public static void playMedia() {
if (!mediaPlayer.isPlaying()) {
try {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(songs.get(position).getLink());
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
try {
mediaPlayer.setDataSource(songs.get(position).getLink());
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void nextSong() {
if (position + 1 == songs.size())
position = 0;
else
position += 1;
playMedia();
}
public static void prevSong() {
if (position - 1 >= 0)
position -= 1;
else
position = songs.size() - 1;
playMedia();
}
// Add for Telephony Manager
public void pauseMedia() {
// Log.v(TAG, "Pause Media");
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
}
public void stopMedia() {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
mediaPlayer.release();
}
// Create Notification
private void initNotification() {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
int icon = R.drawable.ic_launcher;
CharSequence tickerText = "Tutorial: Music In Service";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
notification.flags = Notification.FLAG_ONGOING_EVENT;
Context context = getApplicationContext();
CharSequence contentTitle = "Music In Service App Tutorial";
CharSequence contentText = "Listen To Music While Performing Other Tasks";
Intent notificationIntent = new Intent(this, Player.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText,
contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, notification);
}
// Cancel Notification
private void cancelNotification() {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
mNotificationManager.cancel(NOTIFICATION_ID);
}
}
Actually i am doing call using sip through wifi. bt in this program the problem is that I when i select sip account of the person whom i want to call but when i select the number and press ok then on then second phone there is no notification display that their is an inncoming call. Please help me I am stuck here ???
public class WalkieTalkieActivity extends Activity implements View.OnTouchListener {
public String sipAddress = null;
String DummyNum;
SipManager manager=null;
public SipProfile me = null;
public SipAudioCall call = null;
public IncomingCallReceiver callReceiver;
Button contact;
TextView tv;
private static final int CALL_ADDRESS = 1;
private static final int SET_AUTH_INFO = 2;
private static final int UPDATE_SETTINGS_DIALOG = 3;
private static final int HANG_UP = 4;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.walkietalkie);
// PickContact();
contact = (Button) findViewById(R.id.button1);
contact.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
// BoD con't: CONTENT_TYPE instead of CONTENT_ITEM_TYPE
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
startActivityForResult(intent, 1);
}
});
tv = (TextView) findViewById(R.id.textView1);
ToggleButton pushToTalkButton = (ToggleButton) findViewById(R.id.pushToTalk);
pushToTalkButton.setOnTouchListener(this);
// Set up the intent filter. This will be used to fire an
// IncomingCallReceiver when someone calls the SIP address used by this
// application.
IntentFilter filter = new IntentFilter();
filter.addAction("android.SipDemo.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver, filter);
// "Push to talk" can be a serious pain when the screen keeps turning off.
// Let's prevent that.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
initializeManager();
}
#Override
public void onStart() {
super.onStart();
// When we get back from the preference setting Activity, assume
// settings have changed, and re-login with new auth info.
initializeManager();
}
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
#Override
public void onDestroy() {
super.onDestroy();
if (call != null) {
call.close();
}
closeLocalProfile();
if (callReceiver != null) {
this.unregisterReceiver(callReceiver);
}
}
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
public void initializeManager() {
if (manager == null) {
manager = SipManager.newInstance(this);
}
initializeLocalProfile();
}
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
public void initializeLocalProfile() {
if (manager == null) {
return;
}
if (me != null) {
closeLocalProfile();
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
String username = prefs.getString("namePref", "");
String domain = prefs.getString("domainPref", "");
String password = prefs.getString("passPref", "");
if (username.length() == 0 || domain.length() == 0 || password.length() == 0) {
showDialog(UPDATE_SETTINGS_DIALOG);
return;
}
try {
SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
me = builder.build();
Intent i = new Intent();
i.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);
manager.open(me, pi, null);
// This listener must be added AFTER manager.open is called,
// Otherwise the methods aren't guaranteed to fire.
manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {
public void onRegistering(String localProfileUri) {
updateStatus("Registering with SIP Server...");
}
public void onRegistrationDone(String localProfileUri, long expiryTime) {
updateStatus("Ready");
}
public void onRegistrationFailed(String localProfileUri, int errorCode,
String errorMessage) {
updateStatus("Registration failed. Please check settings.");
}
});
} catch (ParseException pe) {
updateStatus("Connection Error.");
} catch (SipException se) {
updateStatus("Connection error.");
}
}
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
public void closeLocalProfile() {
if (manager == null) {
return;
}
try {
if (me != null) {
manager.close(me.getUriString());
}
} catch (Exception ee) {
Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee);
}
}
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
public void initiateCall() {
updateStatus(sipAddress);
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
// Much of the client's interaction with the SIP Stack will
// happen via listeners. Even making an outgoing call, don't
// forget to set up a listener to set things up once the call is established.
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
#Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
call.toggleMute();
updateStatus(call);
}
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
#Override
public void onCallEnded(SipAudioCall call) {
updateStatus("Ready.");
}
};
call = manager.makeAudioCall(me.getUriString(), sipAddress, listener, 30);
} catch (Exception e) {
Log.i("WalkieTalkieActivity/InitiateCall", "Error when trying to close manager.", e);
if (me != null) {
try {
manager.close(me.getUriString());
} catch (Exception ee) {
Log.i("WalkieTalkieActivity/InitiateCall",
"Error when trying to close manager.", ee);
ee.printStackTrace();
}
}
if (call != null) {
call.close();
}
}
}
public void updateStatus(final String status) {
// Be a good citizen. Make sure UI changes fire on the UI thread.
this.runOnUiThread(new Runnable() {
public void run() {
TextView labelView = (TextView) findViewById(R.id.sipLabel);
labelView.setText(status);
}
});
}
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
public void updateStatus(SipAudioCall call) {
String useName = call.getPeerProfile().getDisplayName();
if (useName == null) {
useName = call.getPeerProfile().getUserName();
}
updateStatus(useName + "#" + call.getPeerProfile().getSipDomain());
}
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
public boolean onTouch(View v, MotionEvent event) {
if (call == null) {
return false;
} else if (event.getAction() == MotionEvent.ACTION_DOWN && call != null && call.isMuted()) {
call.toggleMute();
} else if (event.getAction() == MotionEvent.ACTION_UP && !call.isMuted()) {
call.toggleMute();
}
return false;
}
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, CALL_ADDRESS, 0, "Call someone");
menu.add(0, SET_AUTH_INFO, 0, "Edit your SIP Info.");
menu.add(0, HANG_UP, 0, "End Current Call.");
return true;
}
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case CALL_ADDRESS:
showDialog(CALL_ADDRESS);
break;
case SET_AUTH_INFO:
updatePreferences();
break;
case HANG_UP:
if (call != null) {
try {
call.endCall();
} catch (SipException se) {
Log.d("WalkieTalkieActivity/onOptionsItemSelected",
"Error ending call.", se);
}
call.close();
}
break;
}
return true;
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case CALL_ADDRESS:
LayoutInflater factory = LayoutInflater.from(this);
final View textBoxView = factory.inflate(R.layout.call_address_dialog, null);
return new AlertDialog.Builder(this)
.setTitle("Call Someone.")
.setView(textBoxView)
.setPositiveButton(
android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
EditText textField = (EditText)
(textBoxView.findViewById(R.id.calladdress_edit));
DummyNum = textField.getText().toString();
tv.setText(DummyNum);
SendMessageWebTask webTask1 = new SendMessageWebTask(WalkieTalkieActivity.this);
webTask1.execute();
initiateCall();
}
}
)
.setNegativeButton(
android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Noop.
}
}
)
.create();
case UPDATE_SETTINGS_DIALOG:
return new AlertDialog.Builder(this)
.setMessage("Please update your SIP Account Settings.")
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
updatePreferences();
}
})
.setNegativeButton(
android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Noop.
}
}
)
.create();
}
return null;
}
public void updatePreferences() {
Intent settingsActivity = new Intent(getBaseContext(),
SipSettings.class);
startActivity(settingsActivity);
}
public void PickContact() {
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data != null) {
Uri uri = data.getData();
if (uri != null) {
Cursor c = null;
try {
c = getContentResolver().query(uri, new String[]{
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.TYPE},
null, null, null
);
if (c != null && c.moveToFirst()) {
String number = c.getString(0);
int type = c.getInt(1);
// showSelectedNumber(type, number);
tv.setText(number);
}
} finally {
if (c != null) {
c.close();
}
}
}
}
}
public void showSelectedNumber(int type, String number) {
}
public class SendMessageWebTask extends AsyncTask<String, Void, String> {
private static final String TAG = "WebTask";
private ProgressDialog progressDialog;
private Context context;
private String status;
public SendMessageWebTask(Context context) {
super();
this.context = context;
this.progressDialog = new ProgressDialog(context);
this.progressDialog.setCancelable(true);
this.progressDialog.setMessage("Checking User using Connecto...");
}
#Override
protected String doInBackground(String... params) {
status = invokeWebService();
return status;
}
#Override
protected void onPreExecute() {
Log.i(TAG, "Showing dialog...");
progressDialog.show();
}
#Override
protected void onPostExecute(String params) {
super.onPostExecute(params);
progressDialog.dismiss();
//params = USER_NOT_EXIST_CODE;
if (params.equals("008")) {
Toast toast = Toast.makeText(WalkieTalkieActivity.this, "Requested user is not using Connecto", 7000);
toast.show();
MediaPlayer mp1 = MediaPlayer.create(WalkieTalkieActivity.this, R.raw.button_test);
mp1.start();
sipAddress = DummyNum;
performDial(DummyNum);
} else if (params.equals("001")) {
Toast toast = Toast.makeText(WalkieTalkieActivity.this, "Requested user is not using Connecto... Now Call is through GSM Network", 7000);
toast.show();
// sipAddress = DummyNum;
performDial(DummyNum);
// initiateCall();
} else if (params.equals("100")) {
Toast toast = Toast.makeText(WalkieTalkieActivity.this, "Server Error... Now Call is through GSM Network", 7000);
toast.show();
// sipAddress = DummyNum;
performDial(DummyNum);
// initiateCall();
} else {
Toast toast = Toast.makeText(WalkieTalkieActivity.this, "Your Call is Staring...", 7000);
toast.show();
sipAddress = DummyNum;
// performDial(DummyNum);
initiateCall();
}
// tv.setText(params);
}
private String invokeWebService() {
final String NAMESPACE = "http://tempuri.org/";
final String METHOD_NAME = Utility.verify_sip;
final String URL = Utility.webServiceUrl;
final String SOAP_ACTION = "http://tempuri.org/" + Utility.verify_sip;
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("phone", DummyNum);
Log.v("XXX", tv.getText().toString());
//request.addProperty("password", inputParam2);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapPrimitive result = (SoapPrimitive) envelope.getResponse();
String status = result.toString();
Log.v("RESULT: ", status);
return status;
} catch (Exception e) {
Log.e("exception", e.toString());
StackTraceElement elements[] = e.getStackTrace();
for (int i = 0, n = elements.length; i < n; i++) {
Log.i("File", elements[i].getFileName());
Log.i("Line", String.valueOf(elements[i].getLineNumber()));
Log.i("Method", elements[i].getMethodName());
Log.i("------", "------");
}
return "EXCEPTION";
}
}
}
private void performDial(String numberString) {
if (!numberString.equals("")) {
Uri number = Uri.parse("tel:" + numberString);
Intent dial = new Intent(Intent.ACTION_CALL, number);
startActivity(dial);
}
}
}