I have the following memory details from the DDMS perspective of Eclipse.
However in spite of implementing the following code, I'm unable to obtain the values shown in the above image.
private void logHeap() {
long maxMemory = Runtime.getRuntime().maxMemory()/ (1024*1024);
long totalMemory = Runtime.getRuntime().totalMemory() / (1024*1024);
long heapSize = Debug.getNativeHeapSize()/(1024*1024);
long allocatedHeapSize = Debug.getNativeHeapAllocatedSize() / (1024*1024);
long freeHeapSize = Debug.getNativeHeapFreeSize() / (1024*1024);
DecimalFormat df = new DecimalFormat();
df.setMaximumFractionDigits(2);
df.setMinimumFractionDigits(2);
Log.d(TAG, "debug. =================================");
Log.d(TAG,"Max memory: "+df.format(maxMemory)+" MB");
Log.d(TAG,"Total memory: "+df.format(totalMemory)+" MB");
Log.d(TAG,"Heap Size: "+df.format(heapSize)+" MB");
Log.d(TAG,"Allocated Heapsize: "+df.format(allocatedHeapSize)+" MB");
Log.d(TAG,"Free Heapsize: "+df.format(freeHeapSize)+" MB");
}
I'm getting the following values:
Max Memory : 36.00MB
Total Memory : 7.00 MB
Heap Size : 3.00 MB
allocated heapsize : 3.00 MB
free heapsize : 0.00 MB
Are there any other APIs to obtain the details?
Related
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.
I am trying to find data usage by specific SIM slot. For this I am using TrafficStats.getMobileRxBytes() method but it gives total usage of both the SIM in dual SIM device.
Below is my code that return me total usage:
long rxBytes = (TrafficStats.getTotalRxBytes()- mStartRX)/ 1048576;
RX.setText(Long.toString(rxBytes));
long txBytes = (TrafficStats.getTotalTxBytes()- mStartTX)/ 1048576;
TX.setText(Long.toString(txBytes));
Log.d("totalWifiRe", (TrafficStats.getTotalRxBytes() - TrafficStats.getMobileRxBytes())/ 1048576+" MB");
Log.d("totalWifiTx", (TrafficStats.getTotalTxBytes()- TrafficStats.getMobileTxBytes())/ 1048576+" MB");
Log.d("totalDataRe", (TrafficStats.getMobileRxBytes()/ 1048576)+" MB");
Log.d("totalDataTx", (TrafficStats.getMobileTxBytes()/ 1048576)+" MB");
Log.d("SIM_STATUS", TrafficStats.getThreadStatsTag()+"");
Log.d("DailyNetUsage", "");
Log.d("CurrentTx", txBytes+" MB");
Log.d("CurrentRx", rxBytes+" MB");
I want particular data usage of individual SIM. Any suggestions will be appreciated.
Some Application are doing that like smartapp.
When i run my app on LG G4 or Note 3 which has 3GB of RAM, it shows that the device has 2GB of ram. Can someone explain where is the problem?
ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
long freeMemory = mi.availMem / 1048576L;
long totalMemory = mi.totalMem / 1048576L;
long usedMemory = totalMemory - freeMemory;
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(Util.MyPREFERENCES, 0);
String status = sharedPreferences.getString(Util.KEY_STATUS, null);
if (status.equals("clean")) {
tvFree.setText(freeMemory + " MB");
tvTotal.setText(totalMemory + " MB");
tvUsed.setText(usedMemory + " MB");
stateImage.setImageResource(R.drawable.greenstate);
rippleBackground.stopRippleAnimation();
}
It does not seem to be a clear API for that but I used a simple hack:
Setup a lookup table with some of the power of 2s (like first 15-20) and find the nearest value to the "OS memory" retrieved from the API.
Had a similar problem to yours:
Get android device's all RAM memory programmatically and not only what is only allocated to user processes
This code return total internal memory size:
public static String getTotalInternalMemorySize() {
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long totalBlocks = stat.getBlockCount();
return formatSize(totalBlocks * blockSize);
}
But this size is without system used memory.
For example, at the GALAXY NOTE 3 is the total internal memory of 32 GB, but this function returns only 26.18 GB.
How to determine the overall internal memory including missing 5.82 GB of system memory?
The basic idea that may work is to compute the first number which is power of two, and it is bigger than the number you got returned from the function.
Ex: 2^5 = 32 > 26
In this case your number is 32. You should convert to integer before comparing obviously.
i know how to get free capacity on internal memory and on external storage.
But i want to know max capacity of internal memory and max capacity of external storage, but i can't find any info about it on google
it is possible to achieve it?
thanks
Some new methods were introduced in API 18. This is the code I used to get total storage (internal + external).
private static final long KILOBYTE = 1024;
StatFs internalStatFs = new StatFs( Environment.getRootDirectory().getAbsolutePath() );
long internalTotal;
long internalFree;
StatFs externalStatFs = new StatFs( Environment.getExternalStorageDirectory().getAbsolutePath() );
long externalTotal;
long externalFree;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
internalTotal = ( internalStatFs.getBlockCountLong() * internalStatFs.getBlockSizeLong() ) / ( KILOBYTE * KILOBYTE );
internalFree = ( internalStatFs.getAvailableBlocksLong() * internalStatFs.getBlockSizeLong() ) / ( KILOBYTE * KILOBYTE );
externalTotal = ( externalStatFs.getBlockCountLong() * externalStatFs.getBlockSizeLong() ) / ( KILOBYTE * KILOBYTE );
externalFree = ( externalStatFs.getAvailableBlocksLong() * externalStatFs.getBlockSizeLong() ) / ( KILOBYTE * KILOBYTE );
}
else {
internalTotal = ( (long) internalStatFs.getBlockCount() * (long) internalStatFs.getBlockSize() ) / ( KILOBYTE * KILOBYTE );
internalFree = ( (long) internalStatFs.getAvailableBlocks() * (long) internalStatFs.getBlockSize() ) / ( KILOBYTE * KILOBYTE );
externalTotal = ( (long) externalStatFs.getBlockCount() * (long) externalStatFs.getBlockSize() ) / ( KILOBYTE * KILOBYTE );
externalFree = ( (long) externalStatFs.getAvailableBlocks() * (long) externalStatFs.getBlockSize() ) / ( KILOBYTE * KILOBYTE );
}
long total = internalTotal + externalTotal;
long free = internalFree + externalFree;
long used = total - free;
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
long bytesAvailable = (long)stat.getBlockSize() * (long)stat.getBlockCount();
long megAvailable = bytesAvailable / 1048576;
Source
Also, use this for internal size.
StatFs stat = new StatFs(Environment.getDataDirectory().getPath());
This method will not work on all phones, most phones return the total amount of memory available to the user, less system memory. you might try using the 'df -h' linux command in a c++ method using the NDK, but some phone make that a system (su) command only. So the long and short of it is you can't.
StatFs - Retrieve overall information about the space on a filesystem. This is a wrapper for Unix statvfs().
From API level 18 we use
long getTotalBytes - The total number of bytes supported by the file system.
For older API use
int getBlockCount ()
int getBlockSize ()
StatFs stat = new StatFs(**path**);
long bytesAvailable = (long)stat.getBlockSize() *(long)stat.getBlockCount();
As path You use Environment.getExternalStorageDirectory(), please review this value. In devices with multiple shared/external storage directories, this directory represents the primary storage that the user will interact with.
You need use string values of path like this:
"/mnt/external_sd/"
"/mnt/extSdCard/"
You can retreive list of all /mnt/ devices and use one of this values.
File allMounted = new File("/mnt/");
if(allMounted.isDirectory()){
String[] dirs = allMounted.list();...}
or something like
var myfile=new Java.IO.File("storage/");
var listOfStorages=myfile.ListFiles();
or
String[] externals = System.getenv("SECONDARY_STORAGE").split(":");