Let me preface that I'm new to programming for Android. I've been doing my due diligence to research to no avail. I have the source code below and I'm having issues with returning the value for returning.
I have the code laid out on eclipse and it's not triggering any errors. But when I build the code below, it comes back with an error. After inspecting the values in debug view, I can see the proper values just not binded to the TextView.
public class MyFirstActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
calculateResult(2012, 9, 29);
}
private void calculateResult(int year, int month, int day) {
long days = 0L;
int returning = 0;
java.util.Calendar cal = new java.util.GregorianCalendar(year, month-1, day);
long todayMI = new java.util.Date().getTime();
long calMI = cal.getTimeInMillis();
long millDiff = calMI - todayMI;
if (millDiff < 0) {
returning = 0;
} else {
days = millDiff / 1000 / 60 / 60;
returning = (int) Math.ceil(days / 24f);
}
TextView days_int_remaining = (TextView) findViewById(R.id.days_int_remaining);
days_int_remaining.setText(returning);
}
}
If it helps, here's the TextView on my layout XML:
<TextView
android:id="#+id/days_int_remaining"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:shadowColor="#5000"
android:shadowDx="4"
android:shadowDy="3"
android:shadowRadius="1"
android:textColor="#fff"
android:textSize="70dip"
android:textStyle="bold"
/>
It may be something simple that I'm missing. Anything to help me further understand the code is appreciated!
I believe that the error you get is "runtime-error - close application".
If you look at method setText(...) that is overloaded you will see that it takes arguments with CharSequence (this is probably what you want) and int resId (this is what you provide).
resId - will seek if there is an resource in /values/strings.xml with given name attribute.
The resolution is to provide String:
days_int_remaining.setText(String.valueOf(returning));
just use
TextView days_int_remaining = (TextView) findViewById(R.id.days_int_remaining);
days_int_remaining.setText(String.valueOf(returning));
instead of
TextView days_int_remaining = (TextView) findViewById(R.id.days_int_remaining);
days_int_remaining.setText(returning);
Turn your returning int into a string.
Try this code :
Basically you have to convert your int value to a string before calling setText();
public class MyFirstActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView days_int_remaining = (TextView) findViewById(R.id.days_int_remaining);
int resultat = calculateResult(2012, 9, 29);
days_int_remaining.setText(Integer.toString(resultat));
}
private int calculateResult(int year, int month, int day) {
long days = 0L;
int returning = 0;
java.util.Calendar cal = new java.util.GregorianCalendar(year, month-1, day);
long todayMI = new java.util.Date().getTime();
long calMI = cal.getTimeInMillis();
long millDiff = calMI - todayMI;
if (millDiff < 0) {
returning = 0;
} else {
days = millDiff / 1000 / 60 / 60;
returning = (int) Math.ceil(days / 24f);
}
return returning;
}
}
Related
I want to reset my horizontal progressbar to 0 every night at 12.
Here is my code.
public class MainActivity extends AppCompatActivity {
private TextView textView;
Button btn;
private int Counter counter;
Progressbar progressbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.txtvw);
progressbar = findViewById(R.id.progressbar_Horizontal);
progressbar.setMax(10);
btn = findViewById(R.id.btn_clc);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
counter++;
textView.setText(String.valueOf(counter));
progressbar.setProgress(counter)
}
});
Calendar calendar = Calendar.getInstance();
int hour = 23;
int minute = 59;
int second = 59;
int curHour = calendar.get(Calendar.HOUR_OF_DAY);
int curMinute = calendar.get(Calendar.MINUTE);
int curSecond = calendar.get(Calendar.SECOND);
if (hour==curHour && minute==curMinute && second==curSecond) {
progressbar.setProgress(0);
}
}
}
In this method at the output there is no response to the progressbar! Is this the right way to do or is there any other way?
You don't get any response because you're defining the action in OnCreate method. This method is executed one time when you enter the Activity. So this action defined only works if you launch your Ativity exactly at 23:59:59.
If you want to do it right, implement AlarmManager. You can set the time you want (23:59:59) and do whatever you want (reset the bar) at that moment. You can implement it also when the app is closed, in the background or when the screen is off.
Take a look at this: Alarm Manager Example
It seems TimePicker is made of three inner NumberPickers. Is it possible to access them? it's needed to access and modify each of them.
public static class TimePickerFragment extends DialogFragment
implements TimePickerDialog.OnTimeSetListener {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
TimePicker dialog = new TimePicker(getActivity(), this, 22, 30,
DateFormat.is24HourFormat(getActivity()));
// Create a new instance of TimePickerDialog and return it
return dialog;
}
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
// Do something with the time chosen by the user
}
}
In dialog, I've created a TimePicker to be shown, but I have to modify TimePicker minutes column(spinner) and add 15min intervals. I want to know if there is any way to access those NumberPickers alone.
UPDATE
i posted answer below, however it was one of the hardest modification in android built-in components for me, i finally found the answer and shared it here but idk why it got down-vote?
finally i found a solution. i'm getting minute column here and setting a 15 minute interval there.
changeTimepicker(R.id.from_time_picker, 15);
method implementation:
try {
Class<?> rClass = Class.forName("com.android.internal.R$id");
// Field timePicker = rClass.getField(name);
TimePicker mTimePicker = (TimePicker) findViewById(id);
Field m = rClass.getField("minute");
NumberPicker mMinuteSpinner = (NumberPicker) mTimePicker.findViewById(m.getInt(null));
mMinuteSpinner.setMinValue(0);
mMinuteSpinner.setMaxValue((60 / increment) - 1);
List<String> displayedValues = new ArrayList<String>();
for (int i = 0; i < 60; i += increment) {
displayedValues.add(String.format("%02d", i));
}
mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));
} catch (Exception e) {
e.printStackTrace();
}
}
I'm looking for some solution which will be faster than mine. I get a time difference between current time and my saved, next step is to put the time in TextView. This solution works but it makes my app very slowly. Does anyone know faster solution?
Thread counter = new Thread(){
public void run()
{
long saved
long difference;
while(true)
{
saved = Long.parseLong(getString(c, "0", "saved"));// sharedPreferences
difference = System.currentTimeMillis() - saved;
seconds = (int) (difference / 1000) % 60;
difference-=seconds;
minutes= (int)((difference/ 60000 ) % 60);
difference=minutes;
hours = (int) ((difference/ 3600000) % 24);
days = (int) ((difference/86400000) % 30);
difference-=days;
months= (int) ((difference/2592000)/1000);
runOnUiThread(new Runnable() {
#Override
public void run() {
myTextView5.setText(Integer.toString(seconds));
myTextView4.setText(Integer.toString(minutes));
myTextView3.setText(Integer.toString(hours));
myTextView2.setText(Integer.toString(days));
myTextView1.setText(Integer.toString(months));
}
});
Your precision is 1s - so you can Thread.sleep (1000) in the while without missing a beat.
I would recommend the use of JodaTime library.
DateTime saved = //getSaved;
DateTime diff = DateTime.now().minus(saved);
//update TextView
txtView.setText(diff.getSecondsOfMinute().toString());
According to my understanding you are using runOnUiThread that created temporary shortlife objects that is the main reason your code is running slow because in each iteration it does it created a new instance of Runnable class and then updates your UI.
Read this topic to get a good understanding of Communication with Ui Thread
http://developer.android.com/training/multiple-threads/communicate-ui.html
You can use Handlers to overcome this issue all you need to do is pass message to handler and it will do the job for you.
This is how you do it.
First of all create a custom handler class
public class CustomMessageHandler extends Handler {
private IUpdateAudioProgressListView iUpdateRef;
public void setOnProgressUpdatedListner(IUpdateAudioProgressListView ref) {
this.iUpdateRef = ref;
}
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
YOUR HANDLING CODE HERE ......................
}
}
then in order to send message to UI thread from a custom thread you need to do following things
initialize a class level variable in your thread class like
public class Test {
CustomMessageHandler handler;
public Test() {
handler = new CustomMessageHandler();
Thread counter = new Thread() {
public void run() {
long saved
long difference;
while (true) {
saved = Long.parseLong(getString(c, "0", "saved"));// sharedPreferences
difference = System.currentTimeMillis() - saved;
seconds = (int) (difference / 1000) % 60;
difference -= seconds;
minutes = (int) ((difference / 60000) % 60);
difference = minutes;
hours = (int) ((difference / 3600000) % 24);
days = (int) ((difference / 86400000) % 30);
difference -= days;
months = (int) ((difference / 2592000) / 1000);
Message msg = handler.obtainMessage();
msg.obj = // send all your variables via a class or whatever logic you use
handler.sendMessage(msg);
}
}
};
}
}
If you don't want to use an external library, I would suggest the use of java.util.Calendar (Don't forget to import that!). For your solution, every time your value in SharedPreferences is changed, just run the code below.
Code to calc diff
Calendar c = Calendar.getInstance();
c.setTimeInMillis(difference);
int months = c.get(Calendar.MONTH);
int days = c.get(Calendar.DAY_OF_MONTH);
int hours = c.get(Calendar.HOUR_OF_DAY);
int minutes = c.get(Calendar.MINUTE);
int seconds = c.get(Calendar.SECOND);
myTextView5.setText(Integer.toString(seconds));
myTextView4.setText(Integer.toString(minutes));
myTextView3.setText(Integer.toString(hours));
myTextView2.setText(Integer.toString(days));
myTextView1.setText(Integer.toString(months));
Detect change in preferences
public class MyPreferences extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
// handle the preference change here
}
}
In Mike Dalasay's examples found here:
http://www.codeofaninja.com/2011/07/android-alertdialog-example.html
He presents AlertDialog examples. I am wanting to use the Time and Date Dialogs in these examples, making the functions return the value that was set by the Time and Date Pickers.
As a newbee to Java and Android, I know how the change the return void to String, but I don't know how to pass the picker values to the return value.
Here is his original code:
Show AlertDialog with date picker.
public void alertDatePicker() {
/*
* Inflate the XML view. activity_main is in res/layout/date_picker.xml
*/
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.date_picker, null, false);
// the time picker on the alert dialog, this is how to get the value
final DatePicker myDatePicker = (DatePicker) view.findViewById(R.id.myDatePicker);
// so that the calendar view won't appear
myDatePicker.setCalendarViewShown(false);
// the alert dialog
new AlertDialog.Builder(MainActivity.this).setView(view)
.setTitle("Set Date")
.setPositiveButton("Go", new DialogInterface.OnClickListener() {
#TargetApi(11)
public void onClick(DialogInterface dialog, int id) {
/*
* In the docs of the calendar class, January = 0, so we
* have to add 1 for getting correct month.
* http://goo.gl/9ywsj
*/
int month = myDatePicker.getMonth() + 1;
int day = myDatePicker.getDayOfMonth();
int year = myDatePicker.getYear();
showToast(month + "/" + day + "/" + year);
dialog.cancel();
}
}).show();
}
Where the showToast is i would set String myDate and somehow get the return value out of the function:
public String alertDatePicker() {
Thanks.
At the moment you have the variables month day and year declared in the AlertDialog class. If you move then to the calling method, or class then the scope of them will be different.
eg
int month = 0;
int day = 0;
new AlertDialog.Builder .....
}).show ();
System.out.println (month);
In my Android application i have a tracker activity in which i retrieve the exercises information(name , period , burned calories) from the sqlite data base based on the selected date and display these information in a linear layout , and my problem that as the user select new date the retrieved data are displayed in another "new " layout appear above the old one but what actually i want to do is to display the new retrieved data on the same layout " change the layout content with the new retrieved data ", i have tried the remove all views method but it didn't work since the data appear for few minutes then dis appear
How i can do this: when the user select a new date the new retrieved data displayed on the same layout " refresh the old data by the new one " not to display them in anew layout . how i can do that ? please help me..
java code
public class Tracker extends BaseActivity
{
private Button date_btn;
private ImageButton left_btn;
private ImageButton right_btn;
private ImageView nodata;
private TextView ex_name;
private TextView ex_BCals;
private LinearLayout excercises_LL;
private LinearLayout content_LL ;
private LinearLayout notes;
private LinearLayout details;
private int year,month,day;
private double tot_excals_burned;
private Calendar localCalendar;
private static final int DATE_DIALOG_ID=0;
private boolean has_ex_details;
private boolean has_meal_details=false;
private Cursor exercises_cursor;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.tracker);
date_btn=(Button)findViewById(R.id.btn_date);
date_btn.setText(FormatDate());
date_btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
localCalendar = Calendar.getInstance();
year = localCalendar.get(1);
month= localCalendar.get(2);
day = localCalendar.get(5);
showDialog(DATE_DIALOG_ID);
}
});
left_btn=(ImageButton)findViewById(R.id.btn_left);
left_btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
localCalendar.add(5, -1);
date_btn.setText(FormatDate(localCalendar,"EEEE, d/MMM/yyyy"));
RefreshExercisesData();
RefreshNoDataImage();
}
});
right_btn=(ImageButton)findViewById(R.id.btn_right) ;
right_btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
localCalendar.add(5, 1);
date_btn.setText(FormatDate(localCalendar,"EEEE, d/MMM/yyyy"));
RefreshExercisesData();
RefreshNoDataImage();
}
});
details=(LinearLayout)findViewById(R.id.ll_details);
notes=(LinearLayout)findViewById(R.id.ll_notes);
excercises_LL=(LinearLayout)findViewById(R.id.ll_exercises);
nodata=(ImageView)findViewById(R.id.nodata_imgV);
RefreshExercisesData();
RefreshNoDataImage();
}
private String FormatDate()
{
localCalendar = Calendar.getInstance();
return new SimpleDateFormat("EEEE, d/MMM/yyyy").format(localCalendar.getTime());
}
private String FormatDate(int year, int month, int day)
{
localCalendar = Calendar.getInstance();
localCalendar.set(year, month, day);
return new SimpleDateFormat("EEEE, d/MMM/yyyy").format(localCalendar.getTime());
}
private String FormatDate(Calendar calendar , String format)
{
return new SimpleDateFormat(format).format(calendar.getTime());
}
private void RefreshExercisesData()
{
tot_excals_burned=0;
DBAdapter db = new DBAdapter(this);
db.open();
String selected_date= date_btn.getText().toString();
Log.e("date", selected_date);
exercises_cursor = db.getExerciseInfo(selected_date);
if(exercises_cursor.getCount() !=0 )
{
has_ex_details=true;
details.setVisibility(0);
nodata.setVisibility(8);
notes.setVisibility(0);
//excercises_LL.removeAllViews();
excercises_LL.setWeightSum(1.0F);
excercises_LL.setVisibility(0);
excercises_LL.setOrientation(LinearLayout.VERTICAL);
LayoutInflater exc_LayoutInflater = (LayoutInflater)getApplicationContext().getSystemService("layout_inflater");
LinearLayout layout = (LinearLayout)exc_LayoutInflater.inflate(R.layout.tracker_header_item,null);
TextView tot_ex_cals_value=((TextView)(layout).findViewById(R.id.tv_tot_cals_value));
TextView exs_title=((TextView)(layout).findViewById(R.id.tv_item_title)) ;
exs_title.setText("Exercises ");
(layout).setPadding(0, 36, 0, 0);
excercises_LL.addView((View)layout, 0);
int i = 1;
if (exercises_cursor.moveToFirst())
{
do
{
content_LL=new LinearLayout(this);
ex_name=new TextView(this);
ex_name.setText( exercises_cursor.getFloat(1)+"," +exercises_cursor.getString(0) + "min ");
ex_name.setTextColor(R.color.black);
content_LL.addView(ex_name,0);
ex_BCals=new TextView(this);
ex_BCals.setText(Round(exercises_cursor.getFloat(2)) +" ");
ex_BCals.setTextColor(R.color.color_black);
content_LL.addView(ex_BCals,1);
tot_excals_burned = tot_excals_burned+exercises_cursor.getFloat(2);
excercises_LL.addView(content_LL, i);
i++;
}
while (exercises_cursor.moveToNext());
}
tot_ex_cals_value.setText(Round(tot_excals_burned) );
}
else if(exercises_cursor.getCount()==0 ||tot_excals_burned==0)
{
has_ex_details=false;
RefreshNoDataImage();
}
exercises_cursor.close();
exercises_cursor.deactivate();
db.close();
}
private void RefreshNoDataImage()
{
if(has_ex_details==false && has_meal_details==false)
{
notes.setVisibility(8);
excercises_LL.setVisibility(8);
nodata.setImageResource(R.drawable.bg_nodata);
nodata.setVisibility(View.VISIBLE);
}
else
nodata.setVisibility(8);
}
protected Dialog onCreateDialog(int id)
{
switch (id) {
case DATE_DIALOG_ID:
return new DatePickerDialog(this, mDateSetListener, this.year, this.month, this.day);
}
return null;
}
private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener()
{
public void onDateSet(DatePicker paramDatePicker, int year, int monthofYear, int dayofMonth)
{
Tracker.this.year=year;
month=monthofYear;
day=dayofMonth;
date_btn.setText(FormatDate(year,month,day));
RefreshExercisesData();
RefreshNoDataImage();
}
};
private String Round(double num) {
return String.format("%.1f%n", num);
}}
Looks like you need to edit your question, if you want us to see any code samples.
If this is only a few texts for an exercise, it should be sufficient to give those views ids in the layout xml, so they can be referenced in your activity.
Then you can just get your views with findViewById in OnCreate, and when you receive data for the new exercise, you update those views with e.g. TextView.setText().
If you have a layout, for example one like this:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/name_textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/calories_burned_textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
Then in your Activity where you have access to your data from your sqlite db, you can modify the existing textviews within this layout by finding the view and using the setText method.
// load new data occurs above, now want to set
TextView name = (TextView)findViewById(R.id.name_textview);
name.setText(newName);
TextView calsBurned = (TextView)findViewById(R.id.calories_burned_textview);
calsBurned.setText(newCalsBurned);
It's possible, from what it sounds like in your description, that you are adding these textviews to the Activity via code each time some load button is clicked. You can do this, just hold on to the reference to these textviews you added and use setText() later on when you load a new entry (but don't create the textviews a second time).