Time of Android phone on first boot after unboxing? - android

What will be the display time and date on first boot after unboxing android device if it is not connected to internet connection or without sim? On what basis the time and date is setup by default?

On the first boot, android will set the system time with Build.TIME. And Build.TIME is get from system prop ro.build.data.rtc, which is the time when the image is build. Some factory test will be executed in factory, so it will have been boot some times. It may not be the first boot when user unbox the phone, and boot it.
This is done by AlarmManagerService.java#onStart.
#Override
public void onStart() {
mInjector.init();
...
synchronized (mLock) {
mHandler = new AlarmHandler();
mConstants = new Constants();
...
// We have to set current TimeZone info to kernel
// because kernel doesn't keep this after reboot
setTimeZoneImpl(SystemProperties.get(TIMEZONE_PROPERTY));
// Ensure that we're booting with a halfway sensible current time. Use the
// most recent of Build.TIME, the root file system's timestamp, and the
// value of the ro.build.date.utc system property (which is in seconds).
final long systemBuildTime = Long.max(
1000L * SystemProperties.getLong("ro.build.date.utc", -1L),
Long.max(Environment.getRootDirectory().lastModified(), Build.TIME));
if (mInjector.getCurrentTimeMillis() < systemBuildTime) {
Slog.i(TAG, "Current time only " + mInjector.getCurrentTimeMillis()
+ ", advancing to build time " + systemBuildTime);
mInjector.setKernelTime(systemBuildTime);
}

Related

I'm trying to get а real traffic stats data. But, When i count `TrafficStats.getMobileTxBytes()` for whole day its more than my data pack?

eg. I have a 1.5 GB data pack. It gives the total sum of 2.0 GB or more than that .
any idea about how to get correct speed every second.
TrafficStats.getTotalRxBytes() does not return your data pack value. It refers to the total received bytes (either wifi/mobile) since the last boot (turning ON phone). For mobile data, it will be TrafficStats.getMobileRxBytes(). More importantly, these values get reset in every reboot of device.
I have a 1.5 GB data pack. It gives the total sum of 2.0 GB or more
than that .
The android system does not know anything about your data pack. You are adding it again and again. When you call TrafficStats.getMobileRxBytes() at a moment, it returns total mobile data received upto this moment since last boot. Following is an explanation. Hope this helps.
// Suppose, you have just rebooted your device, then received 400 bytes and transmitted 300 bytes of mobile data
// After reboot, so far 'totalReceiveCount' bytes have been received by your device over mobile data.
// After reboot, so far 'totalTransmitCount' bytes have been sent from your device over mobile data.
// Hence after reboot, so far 'totalDataUsed' bytes used actually.
long totalReceiveCount = TrafficStats.getMobileRxBytes();
long totalTransmitCount = TrafficStats.getMobileTxBytes();
long totalDataUsed = totalReceiveCount + totalTransmitCount;
Log.d("Data Used", "" + totalDataUsed + " bytes"); // This will log 700 bytes
// After sometime passed, another 200 bytes have been transmitted from your device over mobile data.
totalDataUsed = TrafficStats.getMobileRxBytes() + TrafficStats.getMobileTxBytes();
Log.d("Data Used", "" + totalDataUsed + " bytes"); // Now this will log 900 bytes
any idea about how to get correct speed every second.
You cannot get actual speed this way. You can only calculate and show how much bytes have been received/transmitted in a second. All the speed meters in android do the same I think. Something like the following:
class SpeedMeter {
private long uptoNow = 0;
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private ScheduledFuture futureHandle;
public void startMeter() {
final Runnable meter = new Runnable() {
public void run() {
long now = TrafficStats.getMobileRxBytes() + TrafficStats.getMobileTxBytes();
System.out.println("Speed=" + (now - uptoNow)); // Prints value for current second
uptoNow = now;
}
};
uptoNow = TrafficStats.getMobileRxBytes() + TrafficStats.getMobileTxBytes();
futureHandle = scheduler.scheduleAtFixedRate(meter, 1, 1, SECONDS);
}
public void stopMeter() {
futureHandle.cancel(true);
}
}
And use like this:
SpeedMeter meter = new SpeedMeter();
meter.startMeter();
Although this code is not perfect, however it will suit your needs.

Using UsageStatsManager to get the foreground app

I'm trying to use UsageStatsManager to get the foreground app on a Nexus 5 with Marshmallow. I remember it used to work, but for some reason I'm getting null strings for package/class names now.
Here's my implementation
public String[] getForegroundPackageNameClassNameByUsageStats() {
String packageNameByUsageStats = null;
String classByUsageStats = null;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager mUsageStatsManager = (UsageStatsManager)getSystemService("usagestats");
final long INTERVAL = 1000;
final long end = System.currentTimeMillis();
final long begin = end - INTERVAL;
final UsageEvents usageEvents = mUsageStatsManager.queryEvents(begin, end);
while (usageEvents.hasNextEvent()) {
UsageEvents.Event event = new UsageEvents.Event();
usageEvents.getNextEvent(event);
if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
packageNameByUsageStats = event.getPackageName();
classByUsageStats = event.getClassName();
Log.d(TAG, "packageNameByUsageStats is" + packageNameByUsageStats + ", classByUsageStats is " + classByUsageStats);
}
}
}
return new String[]{packageNameByUsageStats,classByUsageStats};
}
For some reason, it doesn't go into the while loop, i.e. usageEvents.hasNextEvent() is false. Because of this, it returns null package/class names.
Any idea what I'm doing wrong?
Thanks.
OK, so I found that once I set the interval to 10000 instead of 1000, it works. Apparently a 1s interval is too small.
I am using this myself. I think the usage stats will only be updated when an app comes to foreground. So if the foreground app got to the foreground (and stayed) before your 'begin' timestamp then you will not get it. :(
On the other hand when you use a long time ago you will get a giant list where you only need the highest time to determine the foreground app.
So what I do is I create 3 different times: 1min ago, 1 hour ago and 12 hours ago.
When I get an empty list on 1min I repeat request with 1h and so on. That way I get foreground most of the time. But I never get it to work ALL of the time.
I really miss the old way of just asking the package manager which app is foreground (prior to android 5), the new way is a bit messy.

Android C++ - socket select is driving me nuts! why is it not respecting the timeout value I specify?

I have a loop in a thread. At the beginning of each loop cycle, I define a socket set and then I use select to wait for activity on any of the sockets in the socket set. I have set the time out value to 2 sec and 500ms. For some reason, the 'select' function returns immediately (like after 1ms) and it doesn't seem to respect the time-out value I defined. So what am I doing wrong?
Here's the code snippet:
/* Define a time-out value of 2 seconds and 500ms */
struct timeval sock_timeout;
sock_timeout.tv_sec = 2;
sock_timeout.tv_usec = 500 * 1000;
while (m_keepRunning)
{
fd_set UdpSocketSet;
SOCKET maxfd = INVALID_SOCKET;
std::map<uint16_t, UdpChannel*>::iterator k;
/* Define socket set */
pthread_mutex_lock(&m_udpChannelsMutex);
FD_ZERO(&UdpSocketSet);
for (k = m_udpChannels.begin(); k != m_udpChannels.end(); ++k)
{
UdpChannel* thisUdpChannel = k->second;
FD_SET(thisUdpChannel->m_udpRxSocket, &UdpSocketSet);
if (maxfd == INVALID_SOCKET)
{
maxfd = thisUdpChannel->m_udpRxSocket;
}
else
{
if (thisUdpChannel->m_udpRxSocket > maxfd) maxfd = thisUdpChannel->m_udpRxSocket;
}
}
pthread_mutex_unlock(&thisAudioStreamer->m_udpChannelsMutex);
/* TIMES OUT LITERALLY EVERY MILLISECOND!!! WHY????? */
int retval = pal_select(maxfd + 1, &UdpSocketSet, NULL, NULL, (timeval*)&sock_timeout);
UPDATE:
I hate Android Studio. It doesn't pick up incremental changes, so I was launching the same app over and over again without noticing that it didn't pick up the changes in the native library.
EJP's suggestion must have helped because once I did a clean rebuild of the apk with EJP's suggested change, the problem went away.
You have to reset the socket timeout struct every time around the loop. From man select (Linux):
select() may update the timeout argument to indicate how much time was left.

How to prevent my application to get cached value of TimeZone.getDefault()?

I am using TimeZone.getDefault() to set the timezone of Calendar class:
Calendar cal = Calendar.getInstance(TimeZone.getDefault());
Log.i("TEST", cal.get(Calendar.HOUR) + ":" + cal.get(Calendar.MINUTE));
However, when users change the timezone of their device from Setting, my application represents the time using the former timezone until they force stop (from App info settings) the application and restart it.
How could I prevent the caching of getDefault()?
It's not pretty, but you could potentially call setDefault(null) to explicitly wipe the cached value. As per the documentation, this will only affect the current process (that is, your app).
Having nulled out the cached value, the next time you call getDefault(), the value is reconstructed freshly:
/**
* Returns the user's preferred time zone. This may have been overridden for
* this process with {#link #setDefault}.
*
* <p>Since the user's time zone changes dynamically, avoid caching this
* value. Instead, use this method to look it up for each use.
*/
public static synchronized TimeZone getDefault() {
if (defaultTimeZone == null) {
TimezoneGetter tzGetter = TimezoneGetter.getInstance();
String zoneName = (tzGetter != null) ? tzGetter.getId() : null;
if (zoneName != null) {
zoneName = zoneName.trim();
}
if (zoneName == null || zoneName.isEmpty()) {
try {
// On the host, we can find the configured timezone here.
zoneName = IoUtils.readFileAsString("/etc/timezone");
} catch (IOException ex) {
// "vogar --mode device" can end up here.
// TODO: give libcore access to Android system properties and read "persist.sys.timezone".
zoneName = "GMT";
}
}
defaultTimeZone = TimeZone.getTimeZone(zoneName);
}
return (TimeZone) defaultTimeZone.clone();
}
You should probably combine this with a broadcast listener for ACTION_TIMEZONE_CHANGED and only null out the default value if you receive such a broadcast.
Edit: come to think of it, a neater solution would be to extract the newly set time zone from the broadcast. From the broadcast documentation:
time-zone - The java.util.TimeZone.getID() value identifying the new time zone.
You can then simply use this identifier to update the cached default:
String tzId = ...
TimeZone.setDefault(TimeZone.getTimeZone(tzId));
Any subsequent calls to getDefault() will then return the correct/updated time zone.

check current time between time interval android

I want to create an app that will allow the user to check whether or not the current time falls between a specified time interval. More specifically, I created a sql table using sqllite program, with the table specifying an end time and a start time for each record. The problem is that the type of data each field can be is limited to text, number, and other type other than a datetime type. So, how would I be able to check if the current time is between the start and end time since the format of time is in h:mm and not just an integer value that I could just do less than or greater than? Do I have to convert the current time to minutes?
You should be able to do the comparison even if time is not stored in the datetime type, here is a link that explains the conversion from string to time.
If that doesn't work, convert the time to seconds (int) and calculate the difference.
Try this. You can save and retrieve your time as String:
String to long: String.valueOf()
long to String: Long.valueOf()
Then, you use this procedure to check time:
//Time checker
private boolean timeCheck(long startTimeInput, long endTimeInput) {
long currentTime = System.currentTimeMillis();
if ((currentTime > startTimeInput) && (currentTime < endTimeInput)) {
return true;
} else {
return false;
}
}
And in your main program check it like this:
//You kept the times as String
if (timeCheck(Long.valueOf(start), Long.valueOf(end))) {
//it is in the interval
} else {
//not in the interval
}
I hope it helps.

Categories

Resources