TimePicker reset bug. Any workaround? - android

I found some problem for TimePicker widget. After user change time in widget setHour and setMinute methods not works.
public class MainActivity extends AppCompatActivity {
private Button mButton;
private TimePicker mTimePicker;
private static final String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.reset);
mTimePicker = (TimePicker) findViewById(R.id.timePicker);
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Calendar cal = Calendar.getInstance();
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
mTimePicker.setHour(hour);
mTimePicker.setMinute(minute);
Log.v(TAG, "onClick: " + hour + "=>" + mTimePicker.getHour());
Log.v(TAG, "onClick: " + minute + "=>" + mTimePicker.getMinute());
}
});
}
}
Step for reproduce:
Run app (my time: 13:21)
Change time on the Widget (21:21)
Tap on the Reset button
Result:time not reset to 13:21
Log:
03-30 13:18:05.765 30923-30923/ru.neverdark.timepickerproblem
V/MainActivity: onClick: 13=>21 03-30 13:18:05.765
30923-30923/ru.neverdark.timepickerproblem V/MainActivity: onClick:
18=>18
Any workaround for this problem?
Same bug I found in Issue Tracker: https://code.google.com/p/android/issues/detail?id=208180 but in SDK25 not fixed...
Demo project on the github: https://github.com/yankovskiy/TimePickerProblem

Well, I have to admit, this is not my proudest code.
But as a workaround you can have this:
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Calendar cal = Calendar.getInstance();
int currentHour = cal.get(Calendar.HOUR_OF_DAY);
int currentMinute = cal.get(Calendar.MINUTE);
fixValues();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mTimePicker.setHour(currentHour);
mTimePicker.setMinute(currentMinute);
} else {
mTimePicker.setCurrentHour(currentHour);
mTimePicker.setCurrentMinute(currentMinute);
}
}
});
private void fixValues() {
// bug is not reproducible in APIs 24 and above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) return;
try {
int hour, minute;
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
hour = mTimePicker.getHour();
minute = mTimePicker.getMinute();
} else {
hour = mTimePicker.getCurrentHour();
minute = mTimePicker.getCurrentMinute();
}
Field mDelegateField = mTimePicker.getClass().getDeclaredField("mDelegate");
mDelegateField.setAccessible(true);
Class<?> clazz;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
clazz = Class.forName("android.widget.TimePickerClockDelegate");
} else {
clazz = Class.forName("android.widget.TimePickerSpinnerDelegate");
}
Field mInitialHourOfDayField = clazz.getDeclaredField("mInitialHourOfDay");
Field mInitialMinuteField = clazz.getDeclaredField("mInitialMinute");
mInitialHourOfDayField.setAccessible(true);
mInitialMinuteField.setAccessible(true);
mInitialHourOfDayField.setInt(mDelegateField.get(mTimePicker), hour);
mInitialMinuteField.setInt(mDelegateField.get(mTimePicker), minute);
} catch (NoSuchFieldException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
}
Tested on APIs 21, 22 and 23.
Bug is not reproducible in APIs 24, 25.

protected Dialog onCreateDialog(int id) {
checkMark = (Button) findViewById(R.id.button13) ;
checkMark.setVisibility(View.VISIBLE) ;
switch (id) {
case TIME_DIALOG_ID:
// set time picker as current time
return new TimePickerDialog(this,
timePickerListener, hour, minute,false);
case TIME_DIALOG_ID_ON:
// set time picker as current time
return new TimePickerDialog(this,
timePickerListenerOn, hour, minute,false);
}
return null;
}
How about this?
picker.setCurrentHour(date.getHours())
picker.setCurrentMinute(date.getMinutes())

Related

Unable to calculate time difference?

I am getting time when screen off and screen on .
I am getting time when screen off in "text1".
and getting time when screen on in "text2".
Now i want to calculate time difference between screen off and screen on.
Unable to calculate time difference .
I want to show time difference in "text3".
MainActivity.java
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.util.Log;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends Activity {
TextView text1,text2,text3;
Date Date1,Date2;
Date d,d1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text1 = (TextView) findViewById(R.id.text1);
text2 = (TextView) findViewById(R.id.text2);
text3 =(TextView) findViewById(R.id.text3);
Timer updateTimer = new Timer();
updateTimer.schedule(new TimerTask()
{
public void run()
{
try
{
String string1 = "s";
Date time1 = new SimpleDateFormat("HH:mm:ss ").parse(string1);
Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(time1);
String string2 = "s1";
Date time2 = new SimpleDateFormat("HH:mm:ss ").parse(string2);
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(time2);
calendar2.add(Calendar.DATE, 1);
Date x = calendar1.getTime();
Date xy = calendar2.getTime();
long diff = x.getTime() - xy.getTime();
int Hours = (int) (diff/( 60 * 60));
int Mins = (int) (diff/(60)) % 60;
//System.out.println("diff hours" + diffHours);
String diff1 = Hours + ":" + Mins; // updated value every1 second
text3.setText( diff1);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}, 0, 1000);
// INITIALIZE RECEIVER
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreeReceiver();
registerReceiver(mReceiver, filter);
// YOUR CODE
}
#Override
protected void onPause() {
// WHEN THE SCREEN IS ABOUT TO TURN OFF
if (ScreeReceiver.wasScreenOn) {
// THIS IS THE CASE WHEN ONPAUSE() IS CALLED BY THE SYSTEM DUE TO A SCREEN STATE CHANGE
d = new Date();
CharSequence s = DateFormat.format("hh:mm:ss", d.getTime());
// d=format.parse(d);
// s=d.getTime();
///Log.i(""+s);
System.out.println("SCREEN TURNED OFF");
text1.setText("SCREEN TURNED OFF" + s);
Log.i("hi", "s"+s);
//System.out.println("s");
} else {
// THIS IS WHEN ONPAUSE() IS CALLED WHEN THE SCREEN STATE HAS NOT CHANGED
}
super.onPause();
}
#Override
protected void onResume() {
// ONLY WHEN SCREEN TURNS ON
if (!ScreeReceiver.wasScreenOn) {
// THIS IS WHEN ONRESUME() IS CALLED DUE TO A SCREEN STATE CHANGE
d1 = new Date();
CharSequence s1 = DateFormat.format("hh:mm:ss", d1.getTime());
text2.setText("SCREEN TURNED ON" + s1);
Log.i("hi", "s"+s1);
// System.out.println("s");
System.out.println("SCREEN TURNED ON");
} else {
}
super.onResume();
}
}
ScreenReceiver.java
public class ScreeReceiver extends BroadcastReceiver {
public static boolean wasScreenOn = true;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
// DO WHATEVER YOU NEED TO DO HERE
wasScreenOn = false;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
// AND DO WHATEVER YOU NEED TO DO HERE
wasScreenOn = true;
}
}
}
1:
String string1 = "s";
can't be parsed as a Date. Why don't you use the d and d1 fields you've stored?
long diff = d1.getTime() - d.getTime();
2:
public long getTime() Returns the number of milliseconds since January
1, 1970, 00:00:00 GMT represented by this Date object.
(Bold my emphasis)
You calculate the time difference as if it were in seconds.
Try:
int Hours = (int) (diff/( 60 * 60 * 1000));
int Mins = (int) (diff/(60 * 1000)) % 60;
Attaching image in which i am getting screen on/off time. and difference time between them.
public class MainActivity extends Activity {
TextView text1,text2,text3;
Date d,d1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text1 = (TextView) findViewById(R.id.text1);
text2 = (TextView) findViewById(R.id.text2);
text3 =(TextView) findViewById(R.id.text3);
// INITIALIZE RECEIVER
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreeReceiver();
registerReceiver(mReceiver, filter);
// YOUR CODE
}
#Override
protected void onPause() {
// WHEN THE SCREEN IS ABOUT TO TURN OFF
if (ScreeReceiver.wasScreenOn) {
// THIS IS THE CASE WHEN ONPAUSE() IS CALLED BY THE SYSTEM DUE TO A SCREEN STATE CHANGE
d = new Date();
CharSequence s = DateFormat.format("hh:mm:ss", d.getTime());
System.out.println("SCREEN TURNED OFF");
text1.setText("SCREEN TURNED OFF" + s);
Log.i("hi", "s"+ s);
} else {
// THIS IS WHEN ONPAUSE() IS CALLED WHEN THE SCREEN STATE HAS NOT CHANGED
}
super.onPause();
}
#Override
protected void onResume() {
// ONLY WHEN SCREEN TURNS ON
if (!ScreeReceiver.wasScreenOn) {
// THIS IS WHEN ONRESUME() IS CALLED DUE TO A SCREEN STATE CHANGE
d1 = new Date();
CharSequence s1 = DateFormat.format("hh:mm:ss", d1.getTime());
text2.setText("SCREEN TURNED ON" + s1);
Log.i("hi", "s"+ s1);
System.out.println("SCREEN TURNED ON");
Timer updateTimer = new Timer();
updateTimer.schedule(new TimerTask()
{
public void run()
{
try
{
runOnUiThread(new Runnable() {
#Override
public void run() {
//stuff that updates ui
long diff = d1.getTime() - d.getTime();
int Hours = (int) (diff/( 1000* 60 * 60));
int Mins = (int) (diff/(1000*60)) % 60;
Log.i("Difference ", ""+ diff);
String diff1= Hours + ":" + Mins; // updated value every 60 second
text3.setText( diff1 );
Log.i("Differ", "diff"+ diff1);
}
});
}
catch (Exception e)
{
e.printStackTrace();
}
}
}, 0, 600000);
} else {
}
super.onResume();
}
}

How to run a function just one time

I need to run a function only once (when it's night, change the image of the imageview) and when I use it in oncreate(), it runs every time I start the
activity.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startAnim();
}
}
private void startAnim(){
Date dateNow=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yy-MM-dd HH:mm:ss");
String night=String.format("%tF",dateNow)+" 19:00:00";
try {
Date dateNight=sdf.parse(night);
if(dateNow.after(dateNight)){
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels; // 屏幕宽度(像素)
int height = metric.heightPixels; // 屏幕高度(像素)
RotateAnimation ra=new RotateAnimation(0,100,width/2,height/2-80);
ra.setDuration(4000);
sunMoon.startAnimation(ra);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
Either a file or store in a Shared Preference. Example for a save method:
private void saveLastRanTime(String key, long lastRunTime) {
SharedPreferences prefs = getApplicationContext().getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putLong(key, lastRunTime); // Store the key somewhere instead of passing in each time
editor.apply();
}
Example check:
private boolean wasLastRunToday(String keyOfPreference) {
SharedPreferences prefs = getApplicationContext().getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
long lastRanAt = prefs.getLong(keyOfPreference, -1); // Save key somewhere..
if (lastRanAt == -1) { // In the event it was never saved before.
return false;
}
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(lastRanAt);
int dayLastRanAt = cal.get(Calendar.DAY_OF_YEAR);
cal.setTimeInMillis(System.currentTimeMillis());
int today = cal.get(Calendar.DAY_OF_YEAR);
return today == dayLastRanAt;
}
Which would make your startAnim() method look more like:
private void startAnim() {
if (wasLastRunToday("LAST_ANIMIATION_RUNTIME")) {
return;
}
Date dateNow=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yy-MM-dd HH:mm:ss");
String night=String.format("%tF",dateNow)+" 19:00:00";
try {
Date dateNight=sdf.parse(night);
if(dateNow.after(dateNight)) {
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels; // 屏幕宽度(像素)
int height = metric.heightPixels; // 屏幕高度(像素)
RotateAnimation ra=new RotateAnimation(0,100,width/2,height/2-80);
ra.setDuration(4000);
sunMoon.startAnimation(ra);
saveLastRanTime("LAST_ANIMIATION_RUNTIME", dateNow.getTime());
}
catch (ParseException e) {
e.printStackTrace();
}
}
}
Record the time of your last time running startAnim() in a file. Read this file when you start the activity to decide run startAnim() or not.

How do I implelment Android 6.0 Runtime Permissions On Existing App

Problem:
I have an existing app that I would like to implement Android 6.0's Runtime Permissions on. I have read a lot of different things on Runtime Permissions, but I just can't seem to wrap my head around all the different snippets. Nothing I have found actually shows how to implement this into an existing Activity.
Other Points
When I run my existing application targeting SDK v23 I get the permission error as expected, but the permission error I get is not even a permission that I am requesting. I have the SEND_SMS permission in the Manifest file, but the error I am getting is for READ_SMS. My app runs fine on pre 6.0 without READ_SMS.
I would like the my app to ask for permission as soon as the app is launched because the sole purpose of the app is the send an SMS message, so without that permission there is no other use for the app.
Questions:
How would I implement Runtime Permissions for SEND_SMS into my existing Activity as soon as the app is launched?
Does the handling of these permission need to run in a background thread?
Do I also need permissions for READ_SMS since that is the permission error that it is giving (even though that permission has never been used on my app)?
My Existing Activity:
public class MainActivity extends Activity implements OnClickListener {
SimpleCursorAdapter mAdapter;
AutoCompleteTextView txtContract;
EditText txtTrip;
EditText txtDate;
Button btnSend;
Button btnUpdate;
String today;
String SENT = "SMS_SENT";
String DELIVERED = "SMS_DELIVERED";
private static final String API_KEY = "abcxyz";
private static final String CONTRACT_REGEX = "^([a-zA-Z0-9_-]){5}$";
private static final String TRIP_REGEX = "^([a-zA-Z0-9_-]){1,10}$";
private static final String DATE_REGEX = "^\\d{2}\\/\\d{2}\\/\\d{4}$";
private static final String PHONE_NUMBER = "1234567890";
private static final String DATE_FORMAT = "MM/dd/yyyy";
private BroadcastReceiver sendBroadcastReceiver;
private BroadcastReceiver deliveryBroadcastReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// TODO - IMPLEMENT RUNTIME PERMISSIONS FOR ANDROID >= 6.0
try {
// Initialize Views
txtContract = (AutoCompleteTextView) findViewById(R.id.txtContract);
txtTrip = (EditText) findViewById(R.id.txtTrip);
txtDate = (EditText) findViewById(R.id.txtDate);
btnSend = (Button) findViewById(R.id.btnSend);
btnUpdate = (Button) findViewById(R.id.btnUpdate);
// Set Listeners
txtDate.setOnClickListener(this);
btnSend.setOnClickListener(this);
btnUpdate.setOnClickListener(this);
// Set Date To Today And Format
final Calendar td = Calendar.getInstance();
int tYear = td.get(Calendar.YEAR);
int tMonth = td.get(Calendar.MONTH);
int tDay = td.get(Calendar.DAY_OF_MONTH);
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH);
td.set(tYear, tMonth, tDay);
today = sdf.format(td.getTime());
txtDate.setText(today);
// Check If Device Is Capable Of Sending SMS
PackageManager pm = this.getPackageManager();
if (!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) &&
!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA)) {
Toast.makeText(this, "Sorry, your device probably can't send SMS...",
Toast.LENGTH_SHORT).show();
}
// Send Receiver
sendBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "Requesting trip...", 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;
}
}
};
// Delivery Receiver
deliveryBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "Trip request successful.", Toast.LENGTH_SHORT).show();
break;
case Activity.RESULT_CANCELED:
Toast.makeText(getBaseContext(), "Trip request failed.", Toast.LENGTH_SHORT).show();
break;
}
}
};
// Register Receivers
registerReceiver(deliveryBroadcastReceiver, new IntentFilter(DELIVERED));
registerReceiver(sendBroadcastReceiver , new IntentFilter(SENT));
// Set Up Adapter For Autocomplete
initializeAutoCompleteAdapter();
}
catch (Exception ex) {
Toast.makeText(this, "Error in MainActivity.onCreate: " + ex.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onDestroy() {
unregisterReceiver(sendBroadcastReceiver);
unregisterReceiver(deliveryBroadcastReceiver);
super.onDestroy();
}
// Auto Complete Adapter
public void initializeAutoCompleteAdapter() {
// Set Database Handler
final DBHelper DBHelper = new DBHelper(getBaseContext());
// Set Up Adapter For Autocomplete (This does not run on the main UI thread)
mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, null,
new String[] { "contract" },
new int[] {android.R.id.text1},
0);
txtContract.setAdapter(mAdapter);
mAdapter.setCursorToStringConverter(new SimpleCursorAdapter.CursorToStringConverter() {
#Override
public CharSequence convertToString(Cursor cursor) {
final int colIndex = cursor.getColumnIndexOrThrow("contract");
return cursor.getString(colIndex);
}
});
mAdapter.setFilterQueryProvider(new FilterQueryProvider() {
#Override
public Cursor runQuery(CharSequence description) {
String strContract = txtContract.getText().toString();
return DBHelper.getContract(strContract);
}
});
}
// OnClickListener Handler
#Override
public void onClick(View v) {
// Handle Clicked View
switch (v.getId()) {
// Date Field
case R.id.txtDate:
// Get Current Date
final Calendar c = Calendar.getInstance();
c.set(c.get(Calendar.YEAR),c.get(Calendar.MONTH),c.get(Calendar.DAY_OF_MONTH),0,0,0);
int mYear = c.get(Calendar.YEAR);
int mMonth = c.get(Calendar.MONTH);
int mDay = c.get(Calendar.DAY_OF_MONTH);
// Set Up DatePicker Dialog
DatePickerDialog datePickerDialog = new DatePickerDialog(this,
new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int month, int day) {
// Define A New Calendar For Formatting
final Calendar cf = Calendar.getInstance();
// Format Selected Date
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH);
cf.set(year,month,day);
String selectedDate = sdf.format(cf.getTime());
// Add Selected Date To EditText Field
txtDate.setText(selectedDate);
}
}, mYear, mMonth, mDay);
// Set Max Date
c.add(Calendar.DATE, 2);
c.add(Calendar.SECOND, -1);
datePickerDialog.getDatePicker().setMaxDate(c.getTimeInMillis());
// Set Min Date
c.add(Calendar.DAY_OF_MONTH,-5);
c.add(Calendar.SECOND, 1);
datePickerDialog.getDatePicker().setMinDate(c.getTimeInMillis());
// Display DatePicker
datePickerDialog.show();
break;
// Submit Button
case R.id.btnSend:
Boolean rval = true;
if (!Validation.isValid(txtContract, CONTRACT_REGEX, "Invalid Contract #", true)) rval = false;
if (!Validation.isValid(txtTrip, TRIP_REGEX, "Invalid Trip #", true)) rval = false;
if (!Validation.isValid(txtDate, DATE_REGEX, "Invalid Date", true)) rval = false;
if(rval) {
new ValidateAndSend(this).execute();
}
break;
// Update Contract DB
case R.id.btnUpdate:
TelephonyManager tMgr = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
new POSTAsync(this).execute(API_KEY, mPhoneNumber);
break;
}
}
// Validate And Send
class ValidateAndSend extends AsyncTask<String, String, Boolean>{
private final WeakReference<MainActivity> MainActivityWeakRef;
public ValidateAndSend(MainActivity mainActivity) {
super();
this.MainActivityWeakRef = new WeakReference<>(mainActivity);
}
// Define Variables
String strContract = txtContract.getText().toString();
String strTrip = txtTrip.getText().toString();
String strDate = txtDate.getText().toString();
String strMessage = strContract.concat("|").concat(strTrip).concat("|").concat(strDate);
Boolean rval = true;
#Override
protected void onPreExecute() {
}
#Override
protected Boolean doInBackground(String... contract) {
DBHelper DBHelper = new DBHelper(MainActivity.this);
if (DBHelper.validateContract(strContract) < 1) rval = false;
return rval;
}
#Override
protected void onPostExecute(Boolean rval){
if(rval){
// Hide Keyboard
View view = MainActivity.this.getCurrentFocus();
if(view != null){
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
if (MainActivityWeakRef.get() != null && !MainActivityWeakRef.get().isFinishing()) {
// Confirm Details
AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this);
alert.setTitle("Confirm Trip");
alert.setMessage("CONTRACT: " + strContract + "\nTRIP: " + strTrip + "\nDATE: " + strDate);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Send SMS
sendSMS(PHONE_NUMBER, strMessage);
// Clear Fields
txtContract.setText("");
txtTrip.setText("");
txtDate.setText(today);
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Cancelled
}
});
// Show Alert
alert.show();
}
}
else{
txtContract.setError("Invalid contract #");
Toast.makeText(MainActivity.this, "You may need to update contracts.",
Toast.LENGTH_LONG).show();
}
}
}
// Send SMS
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);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
}
}
The runtime permission model for Android 6.0 is mainly divided into part
1. Checking Permission
2. Requesting Permission
you can create two method for this thing in your activity, As follow
Check Permission
private boolean checkPermission(){
int result = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_SMS);
if (result == PackageManager.PERMISSION_GRANTED){
return true;
} else {
return false;
}
}
Request Permission
private void requestPermission(){
if (ActivityCompat.shouldShowRequestPermissionRationale(activity,Manifest.permission.READ_SMS)){
Toast.makeText(context,"Read Sms Allowed.",Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.READ_SMS},PERMISSION_REQUEST_CODE);
}
}
Last but not least you need to override the onRequestPermissionsResult method
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Snackbar.make(view,"Permission Granted, Now you can access SMS.",Snackbar.LENGTH_LONG).show();
} else {
Snackbar.make(view,"Permission Denied, You cannot access SMS.",Snackbar.LENGTH_LONG).show();
}
break;
}
}
as you asked do i need to run this in thread .. answer is No Just do this in main thread
If you want to do less code then, please use Dexter is an Android library that simplifies the process of requesting permissions at runtime.

Android Alarm going off as soon as created

Edit: I have figured out that when you set the alarm for a time before the current time it imediately goes off
I am creating an alarm app that has an activity that you use to create the alarm, and then it registers it with the android system. The problem I am having is that as soon as you create the alarm it goes off. I have also seen some odd behaviour with further testing, if you change the time in the time picker before you change the name it goes off at the correct time if not it just goes off as soon as it is created. Here is my alarm class which is used to create the pending-intent for the alarm(at least the important parts):
public class Alarm {
private String name;
private int id;
private Calendar time;
private boolean on = true;
public Alarm(String name, int id, Calendar time) {
this.setName(name);
this.setId(id);
this.setTime(time);
}
public Alarm() {
}
...
public PendingIntent createPendingIntent(Context context) {
Intent intent = new Intent(context, MathAlarmReceiverActivity.class);
intent.putExtra("name", getName());
PendingIntent pendingIntent = PendingIntent.getActivity(context,
id, intent, PendingIntent.FLAG_CANCEL_CURRENT);
return pendingIntent;
}
...
}
I thought that the problem might be where I created the intent, but when I changed the time in the time picker before I changed the name, it went off at the correct time so I was able to rule that out.
Next I have my Activity that actually has the time-picker:
public class EditActivity extends Activity {
public static int CODE_EDIT = 100;
public static int CODE_ADD = 101;
Button doneButton;
TimePicker tp;
EditText editName;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
doneButton = (Button) findViewById(R.id.buttonDone);
doneButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
done();
}
});
tp = (TimePicker) findViewById(R.id.timePicker);
editName = (EditText) findViewById(R.id.editTextAlarmName);
if (getIntent().getExtras().getInt("requestCode") == CODE_ADD) {
setTitle("Add Alarm");
doneButton.setText("Add Alarm");
} else {
doneButton.setText("Edit Alarm");
editName.setText(getIntent().getExtras().getString("name"));
Calendar c = TimeUtils.stringToCalendar(getIntent().getExtras().getString("time"));
tp.setCurrentHour(c.get(Calendar.HOUR_OF_DAY));
tp.setCurrentMinute(c.get(Calendar.MINUTE));
setTitle("Edit Alarm");
}
if (android.os.Build.VERSION.SDK_INT > 10) {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
...
private void done() {
String name = editName.getText().toString().trim();
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, tp.getCurrentHour());
c.set(Calendar.MINUTE, tp.getCurrentMinute());
String time = TimeUtils.calendarToString(c);
if (name.length() == 0) {
AlertDialog.Builder b = new AlertDialog.Builder(this);
b.setMessage("Please enter an alarm name!");
b.setNeutralButton("Ok", null);
b.show();
} else {
Intent returnIntent = new Intent();
returnIntent.putExtra("name", name);
returnIntent.putExtra("time", time);
if (getIntent().getExtras().getInt("requestCode") == CODE_EDIT) {
returnIntent.putExtra("id", getIntent().getExtras()
.getInt("id"));
returnIntent.putExtra("on",
getIntent().getExtras().getBoolean("on"));
}
setResult(RESULT_OK, returnIntent);
finish();
}
}
...
}
Then I thought well maybe when I didn't do it that specific way it somehow changed what was in the time-picker, but I wasn't sure how that could happen! Here I have my method for adding the alarm to the android system:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == EditActivity.CODE_EDIT) {
dataSource.update_byID(
data.getExtras().getInt("id"),
TimeUtils.stringToCalendar(data.getExtras().getString(
"time")), data.getExtras().getString("name"),
data.getExtras().getBoolean("on"));
AlarmManager am = (AlarmManager) getSystemService(Activity.ALARM_SERVICE);
for(int i = 0; i < dataSource.getAllAlarms().size(); i++) {
if(dataSource.getAllAlarms().get(i).getId() == data.getExtras().getInt("id")) {
Alarm tempAlarm = dataSource.getAllAlarms().get(i);
am.setRepeating(AlarmManager.RTC_WAKEUP, tempAlarm.getTime()
.getTimeInMillis(), AlarmManager.INTERVAL_DAY, tempAlarm
.createPendingIntent(this));
break;
}
}
}
if (requestCode == EditActivity.CODE_ADD) {
Alarm tempAlarm = dataSource.createAlarm(
data.getExtras().getString("name"),
TimeUtils.stringToCalendar(data.getExtras().getString(
"time")));
AlarmManager am = (AlarmManager) getSystemService(Activity.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, tempAlarm.getTime()
.getTimeInMillis(), AlarmManager.INTERVAL_DAY, tempAlarm
.createPendingIntent(this));
}
}
refreshList();
}
And also these are the methods I used to convert a Calendar to string and back, I thought maybe I made an error here, but I tested the methods and they work:
public static String calendarToString(Calendar c) {
return String.valueOf(c.get(Calendar.HOUR)) + ":"
+ getMinuteInReadableFormat(c.get(Calendar.MINUTE))
+ (((c.get(Calendar.AM_PM)) == Calendar.AM) ? "AM" : "PM");
}
public static Calendar stringToCalendar(String s) {
String[] t = s.split(":");
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR, Integer.valueOf(t[0]));
c.set(Calendar.MINUTE, minuteToInt(t[1]));
c.set(Calendar.AM_PM, (t[1].endsWith("AM") ? Calendar.AM : Calendar.PM));
return c;
}
public static String convert12(String s) {
String newString = null;
if (s.startsWith("0")) {
newString = s.replaceFirst("0", "12");
}
if (newString == null) {
return s;
} else {
return newString;
}
}
private static String getMinuteInReadableFormat(int m) {
if (m < 10) {
return "0" + String.valueOf(m);
} else {
return String.valueOf(m);
}
}
private static int minuteToInt(String m) {
String x = m;
if (m.startsWith("0")) {
x = m.replaceFirst("0", "");
}
String y = x.replace("AM", "");
String z = y.replace("PM", "");
return Integer.valueOf(z.trim());
}
My problem is that as soon as you create the alarm it goes off. I have also seen some odd behaviour with further testing, if you change the time in the time picker before you change the name it goes off at the correct time if not it just goes off as soon as it is created. And I am not sure what to do know because I don't know what the problem is.
Also Thank You for taking the time to read my question.
Well I've solved the problem. For anyone that has a similar problem here is the solution. When I was creating an alarm for a time earlier than the current time it would go off immediately. The solution is to add the equivalent of 24 hours to the time you want when setting the alarm.

Time Picker Android

How to set previous selected value in TimePicker?
I mean, click on TextView, TimePicker dialog occurs, then I select the time and set it in the TextView, e.g. 12:30 PM on TextView.
After that, if I want to change the time, click again to TextView and then TimePicker dialog should show the previous selected value. So the TimePicker should display 12:30 PM.
How can I do that?
If you create Time Picker Dialog with onCreateDialog and call it it will automatically store the previous value.
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case 0:
TimePickerDialog timeDlg = new TimePickerDialog(this,
new TimePickerDialog.OnTimeSetListener() {
#Override
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {
// TODO Auto-generated method stub
if (hourOfDay > 12) {
hourOfDay = hourOfDay - 12;
time = " PM";
} else if (hourOfDay < 12 && hourOfDay != 0) {
time = " AM";
} else if (hourOfDay == 12) {
time = " PM";
} else if (hourOfDay == 0) {
hourOfDay = 12;
time = " AM";
}
Toast.makeText(
getApplicationContext(),
new StringBuilder().append(pad(hourOfDay))
.append(":").append(pad(minute))
.append(time), Toast.LENGTH_SHORT)
.show();
}
}, 12, 00, false);
timeDlg.setMessage("Set Time:");
timeDlg.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "Dismiss",
Toast.LENGTH_SHORT).show();
}
});
return timeDlg;
}
return null;
}
Use showDialog(id); to Show the Dialog.

Categories

Resources