Okay, so I have a Android App that uses the built in NavigationDrawer Activity with Fragments for each view. One of the views pulls some data from a web service, but since the data doesn't change during a single day I store the values in the preferences as well as a timestamp for the day the tab was opened so that web service method isn't called every time the user opens that tab. The problem that I'm having though is that when the timestamp section just moves to the part of the code that updates the view some items aren't being drawn correctly (some are squished down while others aren't showing the correct placement on the screen). If I click the refresh button to call the web service methods and then update the view that way it always draws them correctly. I don't know where I'm messing up, but I'm sure it's me since Android is pretty new to me.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_sales, container, false);
thisActivity = this.getActivity();
mtdHeaderTextView = (TextView)rootView.findViewById(R.id.mtdHeaderText);
mtdSeekBar = (SeekBar)rootView.findViewById(R.id.mtdSeekBar);
mtdTopSeekBar = (SeekBar)rootView.findViewById(R.id.mtdTopSeekBar);
mtdValueTextView = (TextView)rootView.findViewById(R.id.mtdValueTextView);
mtdGoalTextView = (TextView)rootView.findViewById(R.id.mtdGoalTextView);
mtdDateTextView = (TextView)rootView.findViewById(R.id.mtdDateTextView);
return rootView;
}
#Override
public void onResume() {
super.onResume();
CheckTimeStamp();
}
public static void CheckTimeStamp() {
SharedPreferences preferences = HelperClass.PreferenceFileName(thisActivity);
String timeStamp = preferences.getString(Constants.keySalesTimeStamp, "");
Calendar calendar = Calendar.getInstance();
Date date = calendar.getTime();
String currentTime = HelperClass.GetSimpleDateFormat(date);
if (currentTime.equals(timeStamp)) {
foundMTDValue = preferences.getString(Constants.keyMTDValue, "");
foundYTDValue = preferences.getString(Constants.keyYTDValue, "");
UpdateMTDProgress();-->this is the method that adds values to the textviews and seekbars
}
else {
SharedPreferences.Editor editor = preferences.edit();
editor.putString(Constants.keySalesTimeStamp, currentTime);
editor.apply();
GetMTDValue(); -->this calls the web service to get values and then calls UpdateMTDProgress like above
}
}
Below is the code from the UpdateMTDProgres section
public static void UpdateMTDProgress() {
//First update Header Text View
SharedPreferences preferences = HelperClass.PreferenceFileName(thisActivity);
int mtdGoal = preferences.getInt(Constants.keyMonthlyGoal, 0);
double percentage = Double.parseDouble(foundMTDValue) / mtdGoal;
NumberFormat format = NumberFormat.getPercentInstance();
String percentageString = format.format(percentage);
mtdHeaderTextView.setText("MTD Commissions (" + percentageString + ")");
//Get Current Date and Number of Days in Month
Calendar calendar = Calendar.getInstance();
int currentDay = calendar.get(Calendar.DAY_OF_MONTH);
int totalDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
//Get Daily Goal for Rep based on mtdGoal and number of days
int dailyGoal = mtdGoal/totalDays;
//Get current day goal
int currentDayGoal = dailyGoal * currentDay;
//Check if current mtd value against currentdaygoal
if (Double.parseDouble(foundMTDValue) >= currentDayGoal) {
mtdSeekBar.setProgressDrawable(thisActivity.getResources().getDrawable(R.drawable.seekbar_green));
}
else {
mtdSeekBar.setProgressDrawable(thisActivity.getResources().getDrawable(R.drawable.seekbar_red));
}
//update progress seekbar values
mtdSeekBar.setMax(mtdGoal);
mtdSeekBar.setProgress((int) Double.parseDouble(foundMTDValue));
//update indicator seekbar values
mtdTopSeekBar.setMax(totalDays);
mtdTopSeekBar.setProgress(currentDay);
//Update Current Value and Goal TextViews
String currentValueString = HelperClass.ConvertStringToCurrency(foundMTDValue);
mtdValueTextView.setText(currentValueString);
String goalValueString = HelperClass.ConvertStringToCurrency(String.valueOf(mtdGoal));
mtdGoalTextView.setText(goalValueString);
Date date = calendar.getTime();
SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd");
String shortDate = dateFormat.format(date);
mtdDateTextView.setText(shortDate);
Related
I am working on a Android TV app (system app) where i am trying to use UsageStatsManager to get recently used app list.
By following approach ,
UsageStatsManager usm = getUsageStatsManager(context);
Calendar calendar = Calendar.getInstance();
long endTime = calendar.getTimeInMillis();
calendar.add(Calendar.YEAR, -1)
final List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, startTime, endTime);
Above approach gives right usage data, but after a device reboot it wont give previously used app usage data, until that app has been opened again after reboot .
But same code works fine (after reboot) in an android Phone .
I also tried this sample App from Github in Android TV which also fails to give details after reboot in Android TV (but works in Mobile , both OS version 8) .
Any reason why it's failing to get App usage data for Android TV ?
TIA
#Nainal here is a workaround.
As we had experienced that after a device power cycle , Android Tv box won’t return the usage stats of installed application. Here is a workaround I followed .
We fetch the details of installed application then store only last used time in a Hash map.
And we used a custom comparator to compare via last time used and sort our Installed application details list (ResolveInfo) , for recently used app list.
Now to overcome the situation of device power cycle scenario, We are maintaining a Hash map locally in app . Where we will store the installed App’s Last used time as Long millis (epoch) . lastTimeUsedMap = new HashMap();
And we update the map every time we get a new data from UsageStatsManager.
We simplify the map object and store as string in shared preference.
And after reboot first we will find in usage stats if installed package is having a time stamp or not . If not we will get the time from stored MAP .
Here is the code :
private void SortByRecentlyUsed(final List<ResolveInfo> info, final Context context){
/*load LastTimeUsedMap from pref*/
lastTimeUsedMap = loadLastTimeUsedMap(context);
UsageStatsManager usm = getUsageStatsManager(context);
Calendar calendar = Calendar.getInstance();
long endTime = calendar.getTimeInMillis();
calendar.add(Calendar.MONTH, -1);
long startTime = calendar.getTimeInMillis();
final List<UsageStats> usageStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startTime, endTime);
/*Update AppRecentTimeUsedMap with latest data from UsageStatsManager*/
updateAppRecentTimeUsedMap(usageStatsList,info);
class RecentUseComparator implements Comparator<ResolveInfo> {
#Override
public int compare(ResolveInfo lhs, ResolveInfo rhs) {
String lhsPackageName=lhs.activityInfo.applicationInfo.packageName;
String rhsPackageName=rhs.activityInfo.applicationInfo.packageName;
long lhsUsedTime = getLastUsedTime(lhsPackageName);
long rhsUsedTime = getLastUsedTime(rhsPackageName);
return (lhsUsedTime > rhsUsedTime) ? -1 : (lhsUsedTime == rhsUsedTime) ? 0 : 1;
}
private long getLastUsedTime(String packageDetails) {
long appRecentUsedtime = -1;
if (appRecentTimeUsedMap.containsKey(packageDetails)) {
appRecentUsedtime = appRecentTimeUsedMap.get(packageDetails);
}
return appRecentUsedtime;
}
}
RecentUseComparator mRecentComp = new RecentUseComparator();
Collections.sort(info, mRecentComp);
/*Save the updated LastTimeUsedMap in pref*/
saveLastTimeUsedMap(lastTimeUsedMap, context);
}
private void updateAppRecentTimeUsedMap(List<UsageStats> usageStatsList,List<ResolveInfo> info){
String packageName=null;
if (usageStatsList != null) {
for (ResolveInfo Rinfo : info) {
packageName = Rinfo.activityInfo.applicationInfo.packageName;
boolean added = false;
for (UsageStats usageStats : usageStatsList) {
if (packageName.equalsIgnoreCase(usageStats.getPackageName())) {
appRecentTimeUsedMap.put(usageStats.getPackageName(), usageStats.getLastTimeUsed());
updateLastTimeUsedMap(usageStats.getPackageName(), usageStats.getLastTimeUsed());
added=true;
}
}
if (!added && lastTimeUsedMap.containsKey(packageName)) {
appRecentTimeUsedMap.put(packageName, lastTimeUsedMap.get(packageName));
}
}
}
}
private void updateLastTimeUsedMap(String packageName,Long timeStamp){
lastTimeUsedMap.put(packageName, timeStamp);
}
/**
* Return Map containing Package name and recent used time from preference
*
* #param context
* #return Map<String,Long>
*/
private Map<String,Long> loadLastTimeUsedMap(Context context){
Map<String,Long> outputMap = new HashMap<String,Long>();
SharedPreferences pSharedPref = context.getSharedPreferences(LAST_TIME_USED_PREFS, Context.MODE_PRIVATE);
try{
if (pSharedPref != null){
String jsonString = pSharedPref.getString(LAST_TIME_USED_MAP, (new JSONObject()).toString());
JSONObject jsonObject = new JSONObject(jsonString);
Iterator<String> keysItr = jsonObject.keys();
while(keysItr.hasNext()) {
String key = keysItr.next();
Long value = jsonObject.getLong(key);
outputMap.put(key, value);
}
}
}catch(Exception e){
e.printStackTrace();
}
return outputMap;
}
/**
* Save the updated map containing Package name and recent used time in preference
*
* #param inputMap
* #param context
*/
private void saveLastTimeUsedMap(Map<String,Long> inputMap, Context context){
final SharedPreferences sharedPreferences = context.getSharedPreferences(LAST_TIME_USED_PREFS,Context.MODE_PRIVATE);
if (sharedPreferences != null){
JSONObject jsonObject = new JSONObject(inputMap);
String jsonString = jsonObject.toString();
final SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove(LAST_TIME_USED_MAP).commit();
editor.putString(LAST_TIME_USED_MAP, jsonString);
editor.commit();
}
}
So when the user clicks the button i want it to set the text to a future time. It works but when the user closes the activity the buttons reset. Also if someone could also guide me on creating a method that resets the button text after time is reached. Heres my code to setText on the button.
private void setReloadTime(int reload, Button btn) {
int minutes = (reload/1000/60)%60;
int hours = reload/1000/60/60;
Calendar c = Calendar.getInstance();
int min = c.get(Calendar.MINUTE);
int hr = c.get(Calendar.HOUR_OF_DAY);
if (reload ==0){
btn.setTextColor(R.color.colorAccent);
btn.setText("Ready Again In 24 Hours");
return;
}
if (minutes+min>60) hr++;
int finMin = (minutes + min) %60;
int finHr= (hours + hr)%24;
String fin = "Ready again at " +finHr + ":";
if (finMin<10){
fin = fin +"0"+finMin;
} else{
fin = fin + finMin;
}
btn.setTextColor(R.color.colorAccent);
btn.setText(fin);
}
Use shared preference
Eg:
public static final String MyPREFERENCES = "MyPrefs" ;
SharedPreferences sharedpreferences;
sharedpreferences = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);
Editor editor = sharedpreferences.edit();
editor.putString(Name, fin);
editor.commit();
if (sharedpreferences.contains(Name))
{
btn.setText(sharedpreferences.getString(Name, ""));
}
http://www.tutorialspoint.com/android/android_shared_preferences.htm
You should save that state of your application (Button, time etc) in SharedPreferences. On Reloading activity read from that
I have an empty list. I fill it with my class's instances in a loop. And right after adding an instance, I retrieve the last element and check its parameters. The values of parameters are fine.
Now, when I have filled all the values and control gets out of the loop, the date and time (which are instances of Calendar) of all the elements of that list are somehow replaced with the very last element's date and time, whereas the rest of parameters remain the same. I don't know if there is a logical error in my code or there is a bug in Android Studio.
I am printing out the values to Logcat, before entering the element and after entering that element. The values are same. But when the control reaches cursor.close(), all elements in that list are replaced.
public List<YearChart> readYearChart() throws Exception {
List<YearChart> yearChart = null;
SimpleDateFormat dateFormat = TheApplication.getDateFormat();
SimpleDateFormat timeFormat = TheApplication.getTimeFormat();
Cursor cursor = sqLiteDatabase.query(MyDatabaseHelper.table_YearChart, super.columnsToRetrieve, null, null, null, null, null);
if(cursor.moveToFirst()) {
yearChart = new ArrayList();
int id;
Calendar date = Calendar.getInstance();
int namazId;
Calendar time = Calendar.getInstance();
int i=0;
do
{
id = cursor.getInt(cursor.getColumnIndex(super.columnsToRetrieve[0]));
String dateStr = cursor.getString(cursor.getColumnIndex(super.columnsToRetrieve[1]));
namazId = cursor.getInt(cursor.getColumnIndex(super.columnsToRetrieve[2]));
String timeStr = cursor.getString(cursor.getColumnIndex(super.columnsToRetrieve[3]));
if(!dateStr.isEmpty() && !timeStr.isEmpty())
{
date.setTime(dateFormat.parse(dateStr));
time.setTime(timeFormat.parse(timeStr));
YearChart yc = new YearChart(id, date, namazId, time);
Log.v("YearChart_ID >", String.valueOf(yc.getId()));
Log.v("YearChart_Date>", TheApplication.getDateFormat().format(yc.getDate().getTime()));
Log.v("YearChart_NID >", String.valueOf(yc.getNamazId()));
Log.v("YearChart_Time>", TheApplication.getTimeFormat().format(yc.getTime().getTime()));
Log.v("*****", "*****");
yearChart.add(yc);
YearChart yc1 = yearChart.get(i);
Log.v("YearChart_ID >", String.valueOf(yc1.getId()));
Log.v("YearChart_Date>", TheApplication.getDateFormat().format(yc1.getDate().getTime()));
Log.v("YearChart_NID >", String.valueOf(yc1.getNamazId()));
Log.v("YearChart_Time>", TheApplication.getTimeFormat().format(yc1.getTime().getTime()));
Log.v("*****", "*****");
i++;
}
} while (cursor.moveToNext());
}
cursor.close();
return yearChart;
}
I am using Android Studio (v1.1.0).
You're passing the same reference to date and time - meaning each element in the list holds a reference to those exact objects. When you call date/time methods, you'll be updating those two variables which all your list items point to.
The solution is to move the instantiation of date and time into the do-while loop.
I am using SharedPreference in my Android app to store a string value, but it always takes the defValue from .getString(String key, String defValue), despite having a set value.
Here is my code:
public class AddAlert extends Activity {
[...]
public static final String LAST_ALERT_TIME = "1414931472952";
[...]
public boolean checkIfMoreThanTenMinutesFromLastAlert() {
SharedPreferences lastAlertTimeSettings = getSharedPreferences(LAST_ALERT_TIME, 0);
String lastAlertTime = lastAlertTimeSettings.getString(LAST_ALERT_TIME, null);
double currentDate = new Date().getTime();
if (getDifference(currentDate, Double.valueOf(lastAlertTime))/1000/60>10) {
return true;
} else return false;
}
public double getDifference(double currentDate, double lastAlertDate) {
//milliseconds
double difference = currentDate - lastAlertDate;
return difference;
}
}
The problem is that LAST_ALERT_TIME has a preset value, but it always returns the defValue("null" in this case").
Is there anything wrong I am doing?
Thank you!
before you GET a preference in your app,
make sure you set the source of data
provide a real value for your key that you are getting
PreferenceManager.setDefaultValues(this, R.xml.default_values, false);
SharedPreferences.Editor ed = PreferenceManager.getDefaultSharedPreferences(this).edit();
ed.putString("LAST_ALERT_TIME", getString(R.string.db_app_id));
ed.apply(); // or commit()
I'm trying to make an app that tells me whats the next meeting in my calendar.
What I did is place a cursor on the last event and start getting their start times until I get to the one that's smaller than right now, then, simply use the previous item.
It works fine when creating events in order but not if I create an event in between.
Here is an example:
Lets set the time to 13:00 hours
I have events that I added before at 15:00 (event 1), 16:00 (event 2), 17:00 (event 3)
The cursor goes to read the start time of event 3.
Since the start time is bigger than right now, it goes to previous one, event 2
since start time is also bigger, it goes to previous one, event 1.
Since start time is also bigger, it goes to previous one, some event yesterday.
Since start is smaller, it gets the id, title and start and end times from event 1.
That all works fine, the problem is, when I add something at lets say 14:00 (event 0) after initially added the others first, events 1, 2 and 3
It wont get to event 0, it keeps the information of event 1.
How can I make so that it is correctly made?
here is my code
Big thanks in advance
Regards
public class CalendarInfo extends Activity {
int idNumber = 0;
private Cursor mCursor = null;
private static final String[] COLS = new String[]
{ CalendarContract.Events.TITLE, CalendarContract.Events.DTSTART, CalendarContract.Events.DTEND, CalendarContract.Events._ID};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calendar_info);
Button buttonchange999 = (Button) findViewById(R.id.button999);
buttonchange999.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mCursor = getContentResolver().query(
CalendarContract.Events.CONTENT_URI, COLS, null, null, null);
mCursor.moveToLast();
Calendar cal = Calendar.getInstance();
long currentTimeStart = cal.getTimeInMillis();
long ammountOfDayPassed = currentTimeStart/86400000;
String title = "N/A";
Long start = 9223372036854775806L;
Long end = 0L;
int id = 0;
String title2 = "N/A";
Long start2 = 9223372036854775806L;
Long end2 = 0L;
int id2 = 0;
while(start>currentTimeStart){
try {
title = mCursor.getString(0);
start = mCursor.getLong(1);
end = mCursor.getLong(2);
id = mCursor.getInt(3);
} catch (Exception e) {
//ignore
}
if(start>currentTimeStart){
title2 = title;
start2 = start;
end2 = end;
id2 = id;
}
mCursor.moveToPrevious();
}
DateFormat formatter01 = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
Calendar calendar01 = Calendar.getInstance();
calendar01.setTimeInMillis(start2);
String startText = formatter01.format(calendar01.getTime());
DateFormat formatter02 = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
Calendar calendar02 = Calendar.getInstance();
calendar02.setTimeInMillis(end2);
String endText = formatter02.format(calendar02.getTime());
if(start2>currentTimeStart && end2>currentTimeStart){
settingsTextView.setText("Meeting: "+title2+"\n"+"At: "+startText+"\n"+"Until: "+endText+"\n"+"ID: "+id2);
idNumber=id2;
}
else{
settingsTextView.setText("No Next Meeting" + "\n" + "Meeting: "+title2+"\n"+"At: "+startText+"\n"+"Until: "+endText+"\n"+"ID: "+id2);
idNumber=id2;
}
}
});
}
Solved adding one if in this line:
if(start>currentTimeStart){
if(start<start2){
title2 = title;
start2 = start;
end2 = end;
id2 = id;
}
}