I can't tell if I'm being respectful and courteous to the user or if I'm unnecessarily handicapping the utility of my app in the name of treating the phone like a china doll.
I have a successful app in the Android Market. One main functionality is that it records sports stats from a game the user is scoring. The current level of detail is fairly basic: a row for each player and a field for each basic stat. However, I could conceivably dramatically increase the detail and level of usefulness of the app if I recorded additional information, blowing this up to numerous relational tables and conceivably thousands upon thousands of records.
My question is, is this a responsible thing to do? Up to this point, I've shied away from it, thinking that "it's just a phone" and "it's just SQLite", but I've never really looked at whether that's a legitimate reason to hold back on doing things that I wouldn't give a second thought to doing on a web or desktop app.
So with that, how much data (very quantifiable, I know) is it reasonable to expect a phone app to do in regards to storing and sifting through database records?
EDIT:
To be clear, I'm not simply talking about adding more fields as I know the impact of that is trivial. I'm talking about going from the level of detail of "This player has 5 singles and 3 homers" to storing information about each pitch that comprised each at-bat that lead to 5 singles and three homers. Obviously this will call for additional tables and conceivably a great many records.
For my masters thesis project at CMU, I worte an Android app that collected roughly 300mb (2.5 Million rows in the main table) of data during one day in sqlite. It drained the battery of the phone in about 10 hours and CPU utilization was at around 50%, but nothing of that had a lot to do with data. We were doing online learning on physiological data coming in over bluetooth with 72Hz. With the math intensive parts cut out, the phone was quite fine and useabel while the service was running. And the 10 hours were mostly due to bluetooth running continously. Without bluetooth, we got about 16-18 hours of continous uptime. Which I don't even get these days on the HTC Desire.
AND THIS WAS ON A G1
I think you're fine if you stay in the Megabytes or maybe low 10's of megabytes. As long as you have a a good design and don't do expensive querys in the main thread. SQLite handles well formed queries quite well, and dumping data into it is REALLY fast.
[edit:] just thought of something: Why don't you provide a second version of your app with the additional fields? More calculation obviously means a bit more battery drain, so I would give users some kind of choice. But my intution is that the performance hog won't really be noticeable.
Sounds like SQLite will do just fine for what you need. I wouldn't hesitate to push it's limits. It's a very well implemented product and should be able to handle what you describe. If you get to the point where your application is handling larger volumes of data (more than 100-200MB), you might want to consider Berkeley DB. Berkeley DB supports the SQLite3 API and provides additional data management capabilities that provide better performance, scalability and reliability than native SQLite, especially when dealing with larger data sets. - Dave
Related
Well i have read a lot of answers of similar questions (even if they are old from like 2013-2014) and i understood that it is not possible to know it exactly since android doesnt count the hardware usage as usage of the app, and some other possible problems like services etc.
At the moment I'm trying to test the perfomance of an App using a protocol to reach a goal and the perfomance of the same App using another protocol (not well known by everyone) to reach the same goal, the default android battery analyzer is good for me since both cases are like 90% the same and i know how the protocols work
My problem is that i'm not sure which one is the best to measure the mAph consumed by my App, i know that there are some external apps that shows it but i would prefer using the one of default, I believe this is something important not only for me but for other people who might have to compare different protocols.
I know that i can measure it programmatically and I've done it too, i save the percentage when the app is opened and how much has been consumed until it gets closed, but it isnt an exact measure since while the app is opened some other apps can do heavy work and add some kind of noise of what i'm measuring so i would prefer to use the android's battery analyzer.
Get a spare device. Load it completely, then run the protocol until shutdown without other interaction (no youtube or anything), note the time it lasted. Repeat with the other protocol. Imho that is a fair way to compare. Note that every device behaves differently and it may or may not be possible to transfer this result to other devices e.g. with different network chips, processors or even firmware versions.
For a more fair comparison I think you should compare how the protocols work. I.e. number of interactions, payload size etc. because the power consumption can only ever be an estimate.
I'm going to write a music player for android which satisfies specific needs (which doesn't matter to my question).
I'd like to identify internal playlists with directories (inside of one main directory) on sdcard because I know my users will set up organized directories. So simply reading all audio files in a single list to let the user create playlists manually afterwards would probably be annoying.
I'm wondering whether it's worth to generate a hierarchical playlist file for this purpose.
My current plan is to run a "library inspector" when the app is started. This inspector will use a "library state" containing of hierarchical data of the form
String filename;
long modified; // timestamp of last modification
to check the library recursive for the need of creating a new playlist file. If this matching check fails, this hierarchical file (metadata: title, artist, album, ... - for example xml) is created including a new "library state". This file should prevent to read all the metadata every single run of the app.
To make that clear: I'm searching for an efficient way to play music - but safe battery!
Since I'm new to the development of mobile apps, I'm not very familiar with battery saving. Is it that more saving to read one file instead of recursive metadata reading? Or maybe I'm about to overdo things? Do you know some strategies of established applications?
I'm very interested in your thoughts :) and I hope my bad english doesn't prevent your understanding ... I'm sorry for that.
Thank you!
Max
I can't answer from the perspective of using MediaStore or SQLite, but can give you some suggestions about minimizing battery usage.
Don't use recursion. Recursion is structurally compact but awful in terms of efficiency. Every call is very expensive due to accessing stacks, possible doing context switches, etc. If the recursion is very deep, there are also issues with regards to disk usage, page swapping, etc.
Use an efficient searching algorithm for any large list. The faster you complete what you're doing, the more the processor is idle, the deeper the power state, the more power savings.
Gather your searches / accesses together as much as possible. For example, if you have to do 3 searches, each 1 second apart and taking .5 seconds to execute, you'll keep the processor active in a high power state for over 4.5 secs before letting it rest and drop into a lower power state. If you gather your queries together, you spend 1.5s in a high power state, and 3 seconds in a lower power state. Roughly speaking, you use <1/3 the power.
Use on board memory as much as possible. I don't know how slow accesses to sdcards are, but it'll slow down your algorithm and possibly increase your power consumption.
Try to setup your database entries and other data structures so that they are naturally aligned with your processor's caches (e.g. 16B aligned). That will speed up routines by a significant amount (L1 cache access might be 1 cycle, L2 10 cycles, and memory 100 cycles - these values are illustrative but ballpark). And the fast your routine, the more idle, and the greater the power savings.
My timing durations (e.g. 1 sec apart) are just for illustration purposes. There are multiple idle states and different rules for dropping into those states that can make a real illustration very complicated.
I don't know much about the power efficiency of databases. I do know there are some data bases designed for mobile and low power devices. Unfortunately, I don't recall what they are. (Don't quote me on this, but I recall something about Berkeley and real time.
PS Your English seems excellent.
I'm working with the data generated with the sensor accelerometer. I save every sensor event in sqllite. I don´t have any problem With smartphones like Nexus 5 but with old devices, I think that not all the registers are being recorded in the database because the smartphone doesn´t have enought capacity.
I'm thinking in save all the sensorevent in an array and then save all of them with a transaction, but only for the old devices. How can I know the capacity of a smartphone or at least the year?
Thanks,
Manuel
There are multiple options. For example you might:
You may check for old android Versions like Gingerbread, which are usally old devices
You can get the CPU specs (link)
Do a quick benchmark by yourself. E.g. perform some simple sql tasks and measure the time, when you start your app the first time.
You can check the Device Name via Build.DEVICE (link)
There might be an other way. These are just ideas which came to my mind while reading your question.
My game uses too much battery. I don't know exactly how much it uses as compared to comparable games, but it uses too much. Players complain that it uses a lot, and a number of them note that it makes their device "run hot". I'm just starting to investigate this and wanted to ask some theoretical and practical questions to narrow the search space. This is mainly about the iOS version of my game, but probably many of the same issues affect the Android version. Sorry to ask many sub-questions, but they all seemed so interrelated I thought it best to keep them together.
Side notes: My game doesn't do network access (called out in several places as a big battery drain) and doesn't consume a lot of battery in the background; it's the foreground running that is the problem.
(1) I know there are APIs to read the battery level, so I can do some automated testing. My question here is: About how long (or perhaps: about how much battery drain) do I need to let the thing run to get a reliable reading? For instance, if it runs for 10 minutes is that reliable? If it drains 10% of the battery, is that reliable? Or is it better to run for more like an hour (or, say, see how long it takes the battery to drain 50%)? What I'm asking here is how sensitive/reliable the battery meter is, so I know how long each test run needs to be.
(2) I'm trying to understand what are the likely causes of the high battery use. Below I list some possible factors. Please help me understand which ones are the most likely culprits:
(2a) As with a lot of games, my game needs to draw the full screen on each frame. It runs at about 30 fps. I know that Apple says to "only refresh the screen as much as you need to", but I pretty much need to draw every frame. Actually, I could put some work into only drawing the parts of the screen that had changed, but in my case that will still be most of the screen. And in any case, even if I can localize the drawing to only part of the screen, I'm still making an OpenGL swap buffers call 30 times per second, so does it really matter that I've worked hard to draw a bit less?
(2b) As I draw the screen elements, there is a certain amount of floating point math that goes on (e.g., in computing texture UV coordinates), and some (less) double precision math that goes on. I don't know how expensive these are, battery-wise, as compared to similar integer operations. I could probably cache a lot of these values to not have to repeatedly compute them, if that was a likely win.
(2c) I do a certain amount of texture switching when rendering the scene. I had previously only been worried about this making the game too slow (it doesn't), but now I also wonder whether reducing texture switching would reduce battery use.
(2d) I'm not sure if this would be practical for me but: I have been reading about shaders and OpenCL, and I want to understand if I were to unload some of the CPU processing to the GPU, whether that would likely save battery (in addition to presumably running faster for vector-type operations). Or would it perhaps use even more battery on the GPU than on the CPU?
I realize that I can narrow down which factors are at play by disabling certain parts of the game and doing iterative battery test runs (hence part (1) of the question). It's just that that disabling is not trivial and there are enough potential culprits that I thought I'd ask for general advice first.
Try reading this article:
Android Documents on optimization
What works well for me, is decreasing the use for garbage collection e.g. when programming for a desktop computer, you're (or i'm) used to defining variables inside loops when they are not needed out side of the loop, this causes a massive use of garbage collection (and i'm not talking about primitive vars, but big objects.
try avoiding things like that.
One little tip that really helped me get Battery usage (and warmth of the device!) down was to throttle FPS in my custom OpenGL Engine.
Especially while the scene is static (e.g. a turn-based game or the user tapped pause) throttle down FPS.
Or throttle if the user isn't responsive for more then 10 seconds, like a screensaver on a desktop pc. In the real world users often get distracted while using mobile devices. Don't let your app drain battery while your user figures out what subway-station he's in ;)
Also on the iPhone, sometimes 60FPS is the default, throttling this manually to 30 FPS is barely visible and safes you about half of the gpu cycles (and therefore a lot of battery!).
I'm developing an Android app which needs to download a lot of data.
To improve the usability, I'd like to measure the data traffic my app produces and give the users a hint if the app downloaded a specific amount of data.
My current idea: Sum all downloaded bytes together and react on a specified limit. However, as I downloaded things in many different situations and in many different positions in the code, is there any other possibility to measure the data usage per app?
AFAIK, sys/net/NETINTERFACE/statistics/rx_bytes reports the total amount of the whole system, so this is not a solution.
However, as I downloaded things in many different situations and in many different positions in the code, is there any other possiblity to measure the data usage per app?
TrafficStats may be able to report things by UID. I say "may" because it seems tied to devices. I suspect that Android 3.0+ will consistently report by UID, but my 2.2 and 2.3 experience has been mixed.
Here is a sample application demonstrating recording this information.