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.
Related
I created an android app that has to set device's time because the device cannot remember time. don't know how to set device's time.
Date c = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yyyy
HH:mm:ss");
String formattedDate = df.format(c);
SharedPreferences time = getSharedPreferences("PREFS",0);
Date Time = null;
try {
Time = df.parse(time.getString("time",""));
} catch (ParseException e) {
e.printStackTrace();
}
if (Time == null)
{
SharedPreferences.Editor editor = time.edit();
editor.putString("time", formattedDate);
editor.apply();
Toast.makeText(MainActivity.this, formattedDate,
Toast.LENGTH_SHORT).show();
}
else
{
try {
if (Time.before(df.parse(formattedDate)))
{
SharedPreferences.Editor editor = time.edit();
editor.putString("time", formattedDate);
editor.apply();
**** I want set device's time here from "time"
}
if (Time.after(df.parse(formattedDate)))
{
**** I want set device's time here from "time"
}
} catch (ParseException e) {
e.printStackTrace();
}
}
Add these lines inside your Manifest file to request permission:
<uses-permission android:name="android.permission.SET_TIME"
tools:ignore="ProtectedPermissions" />
<permission android:name="android.permission.SET_TIME" android:protectionLevel="signature|system"/>
And inside your java code:
Calendar c = Calendar.getInstance();
c.set(year, month, day, hour, minutes, seconds);
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
am.setTime(c.getTimeInMillis());
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())
I want to run Async Task in Android every intervals.
my interval is = { 15 min , 30 min , 1 hour ....etc
Depending on the users' choice.
When I start my application then I want to fetch my current time and after every n interval I want to execute Async Task
int intv = 15;
SimpleDateFormat sd = new SimpleDateFormat(
"HH:mm:ss");
Date date = new Date();
sd.setTimeZone(TimeZone.getTimeZone("GMT+05:30"));
System.out.println(sd.format(date));
String currenttime = sd.format(date);
Date myDateTime = null;
try
{
myDateTime = sd.parse(currenttime);
}
catch (ParseException e)
{
e.printStackTrace();
}
System.out.println("This is the Actual Date:"+sd.format(myDateTime));
Calendar cal = new GregorianCalendar();
cal.setTime(myDateTime);
cal.add(Calendar.MINUTE , intv ); //here I am adding Interval
System.out.println("This is Hours Added Date:"+sd.format(cal.getTime()));
try {
Date afterintv = sd.parse(sd.format(cal.getTime()));
if(afterintv.after(myDateTime)){ //here i am comparing
System.out.println("true..........");
new SendingTask().execute; //this is the function i have to execute
}
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
But I am not getting how to do.
If you want to run the AsyncTask after sometime you can use Thread.sleep in your AsyncTask. In this case is the SendingTask class. Here is a sample:
class SendingTask extends AsyncTask{
// Interval is in milliseconds
int interval = 1000;
public SendingTask(int interval) {
// Setting delay before anything is executed
this.interval = interval;
}
#Override
protected Object doInBackground(Object[] params) {
// Wait according to interval
try {
Thread.sleep(interval);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
// update UI and restart asynctask
textView3.setText("true..........");
new SendingTask(3000).execute();
}
}
I want to compare the current date and the date that set by user in my "cal_set" calendar, i want to accept the date if date is today date or upcoming date else show toast if date is passed.
This is my onDateSet method.
public void onDateSet(DatePicker arg0, int year, int month, int day)
{
// TODO Auto-generated method stub
cal_set.set(Calendar.DAY_OF_MONTH,day);
cal_set.set(Calendar.MONTH, month);
cal_set.set(Calendar.YEAR, year);
if(cal_set.getTime().after(cal_now.getTime))
{
tv_date.setText(new StringBuffer().append(day).append("/").append(month).append("/").append(year));
}
else
{
Toast.makeText(getApplicationContext(),"Please select upcoming date", Toast.LENGTH_LONG).show();
}
}
};
i am setting date in cal_now when user click on view that calles onDateSet method.
iv_date.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
// TODO Auto-generated method stub
day_now = Calendar.getInstance(Locale.getDefault()).get(Calendar.DAY_OF_MONTH);
month_now = Calendar.getInstance(Locale.getDefault()).get(Calendar.MONTH);
year_now = Calendar.getInstance(Locale.getDefault()).get(Calendar.YEAR);
cal_now = Calendar.getInstance();
showDialog(ID_DATE);
}
});
protected Dialog onCreateDialog(int id)
{
// TODO Auto-generated method stub
switch (id)
{
case ID_DATE:
return new DatePickerDialog(this, onDateSetListener, year_now, month_now, day_now);
default:
break;
}
return null;
}
any help please.
you can compare Date with compareTo(). However, in your case, you can use Calendar methods setMaxDate() and setMinDate().
You can simply use "now = new Date();" to get the actual date.
Then to test if the entered date is superior or equal to the actual date, use:
if (setdate.compareTo(now)>=0) {
// do your stuff here.
}
public static boolean CompareDates(String strDate1,String strDate2)
{
try
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = sdf.parse(strDate1);
Date date2 = sdf.parse(strDate2);
System.out.println(sdf.format(date1));
System.out.println(sdf.format(date2));
if(date1.compareTo(date2)==0)
{
return true;
}else
{
return false;
}
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
}
I solved my problem finally, now i let the datepicker get date from user and than i set that date in EditText, when user clicks on submit button i just get strings from edittext and parse them into date format like this:
s_date_temp = date_format.parse(et_sdate.getText().toString());
e_date_temp = date_format.parse(et_edate.getText().toString());
After that i compare these dates like this:
if(s_date_temp.after(e_date_temp))
{
Toast toast = Toast.makeText(getApplicationContext(), "Error: The Start Date Must Occur Prior To Th End Date!", Toast.LENGTH_LONG);
toast.show();
}
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.