I have an aplication that gets the count of the user_id on the database to check if the user exists or not.
the code I am having problem:
registerBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
usernameR = usernameRgt.getText().toString();
emailR = emailRgt.getText().toString();
passwordR = passwordRgt.getText().toString();
repeatR = repeatPassRgt.getText().toString();
new userExistsTask().execute(new ApiConnector());
if ((usernameR == null || usernameR.isEmpty() == true) || (emailR == null || emailR.isEmpty() == true) || (passwordR == null || passwordR.isEmpty() == true) || (repeatR == null || repeatR.isEmpty() == true)) {
Toast.makeText(RegisterActivity.this, "One or more fields are empty!", Toast.LENGTH_SHORT).show();
} else {
if (userExistN == 0) {
Toast.makeText(RegisterActivity.this, "Não existe", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(RegisterActivity.this, "existe", Toast.LENGTH_SHORT).show();
}
}
}
});
It works the way I want to the problem is that the call to the new userExistsTask().execute(new ApiConnector());(method that set the variable userExistsN value) takes some time to execute and the if gets the wrong value to the variable userExistsN so there is a way to put a delay between the if and the method call?
Update:
userExistYask() code:
private class userExistsTask extends AsyncTask<ApiConnector,Long,JSONArray>
{
#Override
protected JSONArray doInBackground(ApiConnector... params) {
// it is executed on Background thread
return params[0].userExists(usernameR);
}
#Override
protected void onPostExecute(JSONArray jsonArray) {
if (jsonArray != null) {
JSONObject json = null;
try {
json = jsonArray.getJSONObject(0);
userExistN = json.getInt("userCount");
System.out.println(userExistN);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast.makeText(RegisterActivity.this, "Null", Toast.LENGTH_SHORT).show();
}
}
}
Why don't you put the IF code in separate method and call this method from postExecute? This guarantees the method won't be called till the background method is done
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
}
}, 5000);
There's a couple issues here. You're calling your AsyncTask even if the text fields are empty, which is not needed.
To solve your main issue, just move the functionality that requires the result of the AsyncTask to onPostExecute().
Something like this:
registerBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
usernameR = usernameRgt.getText().toString();
emailR = emailRgt.getText().toString();
passwordR = passwordRgt.getText().toString();
repeatR = repeatPassRgt.getText().toString();
if ((usernameR == null || usernameR.isEmpty() == true) || (emailR == null || emailR.isEmpty() == true) || (passwordR == null || passwordR.isEmpty() == true) || (repeatR == null || repeatR.isEmpty() == true)) {
Toast.makeText(RegisterActivity.this, "One or more fields are empty!", Toast.LENGTH_SHORT).show();
} else {
new userExistsTask().execute(new ApiConnector());
}
}
});
Then your AsyncTask:
private class userExistsTask extends AsyncTask<ApiConnector,Long,JSONArray>
{
#Override
protected JSONArray doInBackground(ApiConnector... params) {
// it is executed on Background thread
return params[0].userExists(usernameR);
}
#Override
protected void onPostExecute(JSONArray jsonArray) {
if (jsonArray != null) {
JSONObject json = null;
try {
json = jsonArray.getJSONObject(0);
userExistN = json.getInt("userCount");
//change this to Lod.d(Tag, userExistN);
System.out.println(userExistN);
if (userExistN == 0) {
Toast.makeText(getApplicationContext(), "Não existe", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "existe", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast.makeText(RegisterActivity.this, "Null", Toast.LENGTH_SHORT).show();
}
}
}
Create an Interface
public interface AsyncResponse {
void processFinish(int userExistN);
}
In userExistsTask class:
private class userExistsTask extends AsyncTask<ApiConnector,Long,JSONArray>
{
public AsyncResponse delegate=null;
#Override
protected JSONArray doInBackground(ApiConnector... params) {
return params[0].userExists(usernameR);
}
:
:
:
}
#Override
protected void onPostExecute(JSONArray jsonArray) {
delegate.processFinish(userExistN);
}
In Activity onCreate()
userExistsTask existsTask = new userExistsTask();
existsTask.execute(new ApiConnector());
existsTask.delegate = this;
void processFinish(int userExistN){
if ((usernameR == null || usernameR.isEmpty() == true) || (emailR == null || emailR.isEmpty() == true) || (passwordR == null || passwordR.isEmpty() == true) || (repeatR == null || repeatR.isEmpty() == true)) {
Toast.makeText(RegisterActivity.this, "One or more fields are empty!", Toast.LENGTH_SHORT).show();
} else {
if (userExistN == 0) {
Toast.makeText(RegisterActivity.this, "Não existe", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(RegisterActivity.this, "existe", Toast.LENGTH_SHORT).show();
}
}
}
Related
I want to send an SMS with location to the contact that the user has been saved. But I don't know how to do it. I am totally new to Android Studio, so I don´t know how to write my code that it will work the way I want it.
Please, can you help me to do that?
This is the code of sending SMS:
Button sendBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendBtn = (Button) findViewById(R.id.btnSendSMS);
sendBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
sendSMSMessage();
}
});
}
protected void sendSMSMessage() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.SEND_SMS)) {
// fixme: show explanation
// before requesting the permission again
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.SEND_SMS},
MY_PERMISSIONS_REQUEST_SEND_SMS);
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.SEND_SMS},
MY_PERMISSIONS_REQUEST_SEND_SMS);
}
} else {
sendSmsImpl();
}
}
#Override
public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_SEND_SMS: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
sendSmsImpl();
} else {
// fixme: explain that it can't send SMS without the permission
Toast.makeText(getApplicationContext(),
"SMS faild, please try again.", Toast.LENGTH_LONG).show();
return;
}
// !!! NOTE: you still need break inside switch/case
// even with curly braces
break;
}
}
}
private void sendSmsImpl() {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage("+212xxx", null, "Je suis en danger, voici ma localisation : https://www.google.com/maps/search/?api=1&query=<lat>,<lng>", null, null);
//todo: use sentIntent argument of sendTextMessage to detect success/error
Toast.makeText(getApplicationContext(),
"SMS sent.", Toast.LENGTH_LONG).show();
}
And this the code of saving contact:
private int id;
private String phoneNo;
private String name;
// constructor
public ContactModel(int id, String name, String phoneNo) {
this.id = id;
this.phoneNo = validate(phoneNo);
this.name = name;
}
// validate the phone number, and reformat is necessary
private String validate(String phone) {
// creating StringBuilder for both the cases
StringBuilder case1 = new StringBuilder("+212");
StringBuilder case2 = new StringBuilder("");
// check if the string already has a "+"
if (phone.charAt(0) != '+') {
for (int i = 0; i < phone.length(); i++) {
// remove any spaces or "-"
if (phone.charAt(i) != '-' && phone.charAt(i) != ' ') {
case1.append(phone.charAt(i));
}
}
return case1.toString();
} else {
for (int i = 0; i < phone.length(); i++) {
// remove any spaces or "-"
if (phone.charAt(i) != '-' || phone.charAt(i) != ' ') {
case2.append(phone.charAt(i));
}
}
return case2.toString();
}
}
public String getPhoneNo() {
return phoneNo;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I'm trying to disable setOnGroupClickListener in ExpandableListView in android through a value set by asynctask.
expandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) {
try {
new checkProgressValue().execute(i).get(3000,TimeUnit.MILLISECONDS);
} catch (Exception e) {
e.printStackTrace();
}
Log.i("ResultPermission", String.valueOf(permission));
if (permission.equals(false)) {
return false;
}
else {
return true;
}
}
});
AsyncTask Code:
public class checkProgressValue extends AsyncTask<Integer, Void, Void> {
#Override
protected Void doInBackground(Integer... voids) {
Call<DefaultResponse> call = RetrofitClient.getInstance().getApi()
.checkQuizTopicForAttempt(user.getId(), topicList.get(voids[0]).getCourse_id());
final int temp = voids[0];
call.enqueue(new Callback<DefaultResponse>() {
#Override
public void onResponse(Call<DefaultResponse> call, Response<DefaultResponse> response) {
try {
if (response.body().getMessage() == null) {
progressValue = 0;
} else {
progressValue = Integer.parseInt(response.body().getMessage());
}
if (progressValue == 0 ) {
permission = false;
} else {
Toast.makeText(getActivity().getApplicationContext(),
"Lock", Toast.LENGTH_SHORT).show();
permission = true;
}
} catch (Exception e) {
e.printStackTrace();
}
Log.i("Permission", String.valueOf(permission));
}
#Override
public void onFailure(Call<DefaultResponse> call, Throwable t) {
Toast.makeText(getActivity().getApplicationContext(), t.getMessage(), Toast.LENGTH_LONG).show();
permission = true;
Log.i("Permission", String.valueOf(permission));
}
});
return null;
}
}
Program doesn't wait at execute(i).get() method and always return true. The Log.i in this method print permission true while in AsyncTask print false.
I didn't get where I'm wrong. Or is there any way i handle onClick in PostExecute method?
just Call this function in onResponse :
expandableListView.expandGroup(positionOfGroup);
I have a problem with SpeechRecognizer on android. Here's my code:
public class MyRecognizerListener implements RecognitionListener {
String id;
MyRecognizerListener(String id){
this.id = id;
}
#Override
public void onEndOfSpeech() {
}
#Override
public void onBeginningOfSpeech() {
Log.d("Speech", "Inizia ad Ascoltare");
}
#Override
public void onReadyForSpeech(Bundle params) {
Log.d("Speech", "E' pronto ad Ascoltare");
}
#Override
public void onPartialResults(Bundle results) {
matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
if(matches.size() > 1) {
Log.d("Speech", "Risultati Parziali = " + Integer.toString(matches.size()));
for (int i = 0; i < matches.size(); i++) {
Log.d("Speech", matches.get(i));
}
if (matches.contains("si") || matches.contains("sì") || matches.contains("Sì")
|| matches.contains("yes") || matches.contains("ES")) {
Opera opera = createOpera(id);
startAudio(opera);
}
matches = null;
turnSpeechOff = false;
speechRecognizer.cancel();
speechRecognizer.destroy();
speechRecognizer = null;
}
}
#Override
public void onEvent(int eventType, Bundle params) {
}
#Override
public void onError(int error) {
if(turnSpeechOff) {
Log.d("Speech", Integer.toString(error));
turnSpeechOff = false;
speechRecognizer.cancel();
speechRecognizer.destroy();
speechRecognizer = null;
}
}
#Override
public void onRmsChanged(float rmsdB) {
}
#Override
public void onBufferReceived(byte[] buffer) {
}
#Override
public void onResults(Bundle results) {
matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
for (int i = 0; i < matches.size(); i++){
Log.d("Parole", matches.get(i));
}
if(matches.contains("si") || matches.contains("sì") || matches.contains("Sì")
|| matches.contains("yes") || matches.contains("ES")){
Opera opera = createOpera(id);
startAudio(opera);
}
matches = null;
turnSpeechOff = false;
speechRecognizer.cancel();
speechRecognizer.destroy();
speechRecognizer = null;
}
}
public void startAudioAsk(final String art_id){
if(speechRecognizer != null) {
return;
}
if(audioPlayer == null || !audioPlayer.isPlaying() ) {
if(operaAudioAsk != null && operaAudioAsk.equals(art_id)){
return;
}
operaAudioAsk = art_id;
if(language.equals("IT")) {
audioPlayer = MediaPlayer.create(this, R.raw.chiedi);
} else {
audioPlayer = MediaPlayer.create(this, R.raw.ask);
}
audioPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
audioPlayer.reset();
audioPlayer.release();
int audioTitle;
if(language.equals("IT")){
audioTitle = getResources().getIdentifier(art_id + "_title" + "_it", "raw", getPackageName());
audioPlayer = MediaPlayer.create(MainActivity.this, audioTitle);
} else {
audioTitle = getResources().getIdentifier(art_id + "_title" + "_en", "raw", getPackageName());
audioPlayer = MediaPlayer.create(MainActivity.this, audioTitle);
}
audioPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
askVoice(art_id);
audioPlayer.reset();
audioPlayer.release();
audioPlayer = null;
}
});
audioPlayer.start();
}
});
audioPlayer.start();
}
}
public void askVoice(String art_id){
if(speechRecognizer == null) {
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
speechRecognizer.setRecognitionListener(new MyRecognizerListener(art_id));
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getPackageName());
intent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);
intent.putExtra(RecognizerIntent.EXTRA_WEB_SEARCH_ONLY, true);
if(language.equals("IT")){
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "it");
} else {
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "en_US");
}
speechRecognizer.startListening(intent);
voiceTimer = new Timer();
voiceTimer.schedule(new StopVoiceManager(), 2000);
Log.d("Speech", "Starta");
}
}
public void stopVoice(){
if(speechRecognizer != null){
Log.d("Speech", "Cancello");
turnSpeechOff = true;
speechRecognizer.stopListening();
}
}
public class StopVoiceManager extends TimerTask{
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
stopVoice();
Log.d("Speech", "Prova a Cancellare");
}
});
}
}
As you can see, there's also a task that, after 2 seconds, calls speechRecognizer.stoplistening().
The first listening is ok, I say "yes" and it recognizes it, but the second listening raises the ERROR_CLIENT and it doesn't recognize anything, then the third listening returns to be ok, the fourth doesn't recognize anything and so.
How can i fix this bug?
This is the demo code and when I add onClickListener in fill function it is not working and if i set any other property like background color it works fine.
private void fillHolder(FriendsHolder holder, final Friend friend) {
if (friend == null)
return;
Iterator<Button> iViews = holder.interests.iterator();
Iterator<String> iInterests = friend.getInterests().iterator();
while (iViews.hasNext() && iInterests.hasNext()) {
iViews.next().setText(iInterests.next());
}
Iterator<Button> iViewss = holder.interests.iterator();
while (iViewss.hasNext()) {
iViewss.next().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), friend.getNickname(), Toast.LENGTH_SHORT).show();
}
});
}
holder.infoPage.setBackgroundColor(getResources().getColor(friend.getBackground()));
holder.nickName.setText(friend.getNickname());
}
}
You're iterating through iViewss (with double S in the end) and you're setting the listener to iViews(with single S in the end).
It's not the same object.
iViews.next().setOnClickListener() will throw a NoSuchElementException because there is not a next element.
Change your code like that:
private void fillHolder(FriendsHolder holder, final Friend friend) {
if (friend == null)
return;
Iterator<Button> iViews = holder.interests.iterator();
Iterator<String> iInterests = friend.getInterests().iterator();
while (iViews.hasNext() && iInterests.hasNext()) {
iViews.next().setText(iInterests.next());
}
while (iViews.hasNext()) {
iViews.next().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), friend.getNickname(), Toast.LENGTH_SHORT).show();
}
});
}
holder.infoPage.setBackgroundColor(getResources().getColor(friend.getBackground()));
holder.nickName.setText(friend.getNickname());
}
EDIT:
You can also combine the two while-loops (as cricket_007 suggestion):
private void fillHolder(FriendsHolder holder, final Friend friend) {
if (friend == null)
return;
Iterator<Button> iViews = holder.interests.iterator();
Iterator<String> iInterests = friend.getInterests().iterator();
while (iViews.hasNext()) {
Button button = iViews.next();
if (iInterests.hasNext()) {
button.setText(iInterests.next());
}
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), friend.getNickname(), Toast.LENGTH_SHORT).show();
}
});
}
holder.infoPage.setBackgroundColor(getResources().getColor(friend.getBackground()));
holder.nickName.setText(friend.getNickname());
}
Along with the comments from the other answer, I think this code is more appropriate - it looks like you can combine the while-loops.
private void fillHolder(FriendsHolder holder, final Friend friend) {
if (friend == null)
return;
Iterator<Button> iViews = holder.interests.iterator();
Iterator<String> iInterests = friend.getInterests().iterator();
while (iViews.hasNext()) {
Button nextButton = iViews.next();
if (iInterests.hasNext()) {
nextButton.setText(iInterests.next());
}
nextButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), friend.getNickname(), Toast.LENGTH_SHORT).show();
}
});
}
holder.infoPage.setBackgroundColor(getResources().getColor(friend.getBackground()));
holder.nickName.setText(friend.getNickname());
}
For some reason I can't call a method that contains PhoneCallListener from onutteranceCompleted. There are no error messages, it just seems to stop executing the script. I've added some Logs and it gets to the "here" log in setUpPhone with PhoneCallListener. Without PhoneCallListener it will get to the final log "phone set up". Here is example code of how I have it implemented.
#Override
public void onInit(int status)
{
if(status == TextToSpeech.SUCCESS)
{
tts.setOnUtteranceCompletedListener(this);
int result = tts.setLanguage(Locale.US);
if(result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED)
{
//Language not supported
}
else
{
speakOut();
}
}
}
private void speakOut()
{
HashMap<String, String> myHashAlarm = new HashMap<String, String>();
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_ALARM));
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "Text to Speech");
tts.speak("blah blah", TextToSpeech.QUEUE_FLUSH, myHashAlarm);
}
#Override
public void onDestroy()
{
if(tts != null)
{
tts.stop();
tts.shutdown();
}
super.onDestroy();
}
public void onUtteranceCompleted(String utteranceId)
{
Log.i("TEST", utteranceId);
setUpPhone();
Log.i("TEST", "phone set up"); //this is never reached
}
private void setUpPhone()
{
Log.i("TEST", "here");
PhoneCallListener phoneListener = new PhoneCallListener(); //If I remove this line, the log "phone set up" displays.
}
I don't know why PhoneCallListener stops execution, however I solved this by putting "phoneListener = new PhoneCallListener();" in the onCreate method.