Abhishek Patel Abhishek Patel - 3 months ago 10
Android Question

Method Called Twice in DatePicker

I use The

datepickerdialog
in simple
Activity
..and when
DialogBox
is closed, below method will be called 2 times.

private void FetchData(String day, String month, int year)


I don't know why this method call 2 times when DatepickerDialog show only 1 time?

public class MainActivity extends Activity {
ListView listview;
Cursor smscursor;
SMS_SQL sql;
ListAdapter adapter;
final ArrayList<List> list = new ArrayList<List>();
private int year;
private int month;
String monthstr;
private int day;
String dayday, monthmonth;
ArrayList<String> smslist = new ArrayList<String>();
String PhoneNo = "1234567890";
static final int DATE_DIALOG_ID = 999;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewsms);
ActionBar action = getActionBar();
action.setDisplayHomeAsUpEnabled(true);
action.setDisplayShowTitleEnabled(true);
listview = (ListView) findViewById(R.id.listview);
sql = new SMS_SQL(this);
sql.Open();
final Calendar c = Calendar.getInstance();
year = c.get(Calendar.YEAR);
month = c.get(Calendar.MONTH);
day = c.get(Calendar.DAY_OF_MONTH);
smscursor = sql.FetchSMS();
while (smscursor.moveToNext()) {
list.add(new List(smscursor.getString(smscursor
.getColumnIndexOrThrow(SMS_SQL.SMS_TITLE)), smscursor
.getString(smscursor
.getColumnIndexOrThrow(SMS_SQL.SMS_DATE)),
smscursor.getInt(smscursor
.getColumnIndexOrThrow(SMS_SQL.SMS_ID)),
smscursor.getString(smscursor
.getColumnIndexOrThrow(SMS_SQL.SMS_MESSAGE))));

}
adapter = new ListAdapter(this, R.layout.smsitem, list);
adapter.setNotifyOnChange(true);
listview.setAdapter(adapter);
}

@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DATE_DIALOG_ID:
// set date picker as current date
return new DatePickerDialog(this, datePickerListener, year, month,
day);
}
return null;
}

private DatePickerDialog.OnDateSetListener datePickerListener = new DatePickerDialog.OnDateSetListener() {

// when dialog box is closed, below method will be called.
public void onDateSet(DatePicker view, int selectedYear,
int selectedMonth, int selectedDay) {
year = selectedYear;
month = selectedMonth;
day = selectedDay;
month++;
if (day <= 9) {
dayday = 0 + "" + day;
} else {
dayday = "" + day;
}

if (month <= 9) {
monthmonth = 0 + "" + month;
} else {
monthmonth = "" + month;
}
FetchData(dayday, monthmonth, year);
}

};

private void FetchData(String day, String month, int year) {
// TODO Auto-generated method stub
String date1 = day + "-" + month + "-" + year;
Cursor sms = sql.fetchSmsByDate(date1);
while (sms.moveToNext()) {
smslist.add(sms.getString(sms
.getColumnIndexOrThrow(SMS_SQL.SMS_MESSAGE)));

}
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);

alertDialogBuilder
.setTitle("Are you Sure To Send All This SMS To 1234567890..??");

alertDialogBuilder
.setMessage(
"If You Press Yes Then All Location Saved On this Date is Send..!!")
.setCancelable(true);
alertDialogBuilder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
sendit();
dialog.dismiss();
}
}).setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});

AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();

}

private void sendit() {

for (int i = 0; i < smslist.size(); i++) {
sendSMS(PhoneNo, smslist.get(i));
}
}

private void sendSMS(String phoneNumber, String message) {
String SENT = "SMS_SENT";
String DELIVERED = "SMS_DELIVERED";

PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(
SENT), 0);

PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0,
new Intent(DELIVERED), 0);

// ---when the SMS has been sent---
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "SMS sent",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Toast.makeText(getBaseContext(), "Generic failure",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(getBaseContext(), "No service",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(getBaseContext(), "Null PDU",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Toast.makeText(getBaseContext(), "Radio off",
Toast.LENGTH_SHORT).show();
break;
}
}
}, new IntentFilter(SENT));

// ---when the SMS has been delivered---
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "SMS delivered",
Toast.LENGTH_SHORT).show();
break;
case Activity.RESULT_CANCELED:
Toast.makeText(getBaseContext(), "SMS not delivered",
Toast.LENGTH_SHORT).show();
break;
}
}
}, new IntentFilter(DELIVERED));

SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub

MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}

@SuppressWarnings("deprecation")
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(MainActivity.this, AddToDB.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
case R.id.Sync:
showDialog(DATE_DIALOG_ID);
return true;
}
return super.onOptionsItemSelected(item);
}
}

Answer

Since JellyBean, the onDateSet() method of the DatePicker class is called twice i.e. once when Ok button is pressed and then when the DatePickerDialog is dismissed. It is a known "bug". You can have a workaround like this:-

int noOfTimesCalled = 0; in class level and then replace onDateSet() method with below code:-

public void onDateSet(DatePicker view, int selectedYear,
            int selectedMonth, int selectedDay) {
    if(noOfTimesCalled%2==0) {
        year = selectedYear;
        month = selectedMonth;
        day = selectedDay;
        month++;
        if (day <= 9) {
            dayday = 0 + "" + day;
        } else {
            dayday = "" + day;
        }

        if (month <= 9) {
            monthmonth = 0 + "" + month;
        } else {
            monthmonth = "" + month;
        }
        FetchData(dayday, monthmonth, year);
    }
    noOfTimesCalled++;
}

Edit:- JUST AN FYI. Same is the case with TimePickerDialog where onTimeSet() is called twice.