I'm trying to make use of a mobile information about neighbouring cells, available on Android via TelephonyManager class and its getNeighboringCellInfo method. Below I'm posting a part of code (mostly taken from publicly available sources) which does the job, and one example of output which this code produces (shown in attached screenshot). The code and the image are placed "as is" without any changes, so it should be relatively easy to associate one with the other and make sure it should work correctly (of course, there can be errors which I overlooked).
The problem is that the list of neighbouring cells does often contain elements with "incorrect" (to my understanding) data, such as:
a NeighboringCellInfo with all properties - lac, cid, psc - set to -1, and only rssi field seems meaningful;
a NeighboringCellInfo with lac equal to 0; does this mean that the lac is the same as current active cell?
a NeighboringCellInfo with rssi value outside the range [0, 31] and not UNKNOWN_RSSI; such values can be as positive (33, as shown in the screenshot), as negative (they look like a proper raw rssi value, that is without the need to convert from asu);
list elements obtained in the same geolocation do not demonstrate consistency as much as I'd expect, that is in two consecutive scans every one can have an element omitted in the other one, and the omitted elements' rssi levels are not of a most low level in the list (in fact their rssi's can be larger than for currently used cell); I admit this could be right behaviour if every cell signal tends to be very unstable, but I'm not sure if it's true in general for GSM and/or UMTS networks. Current cell always has all fields defined well, but its rssi can vary very quickly in a range of 30 dBm (say from -60 to -90).
The same as 4, but about consistency from one day to another. In a highly urbanized and matured environment I'd expect to see the same list of cells every day, yet they vary in such a way, that one day I don't even see a mention about a cell that was active cell in a previuos day.
Does all this mean a normal functioning of mobile technology, some sort of possibly powersaving optimizations, or a flaw in a specific device (LG Optimus One in my case)?
Please suggest how can one obtain consistent readings from cell environment on Android, if this is possible.
GsmCellLocation cellLocation = (GsmCellLocation)telephonyManager.getCellLocation();
String networkOperator = telephonyManager.getNetworkOperator();
int type = telephonyManager.getNetworkType();
String mcc = networkOperator.substring(0, 3);
String mnc = networkOperator.substring(3);
textMCC.setText("mcc: " + mcc + " mnc: " + mnc);
textMNC.setText("operator: " + networkOperator);
int cid = cellLocation.getCid();
int lac = cellLocation.getLac();
int psc = cellLocation.getPsc();
textGsmCellLocation.setText(cellLocation.toString());
textCID.setText("lac: " + String.valueOf(lac) + " cid: " + String.valueOf(cid) + " psc: " + String.valueOf(psc) + " type: " + String.valueOf(type) + " rssi: " + String.valueOf(currentCellRSSI));
TextView Neighboring = (TextView)findViewById(R.id.neighboring);
List<NeighboringCellInfo> NeighboringList = telephonyManager.getNeighboringCellInfo();
String stringNeighboring = "Neighboring List - Lac : Cid : Psc : type : RSSI\n";
for(int i = 0; i < NeighboringList.size(); i++)
{
String dBm;
int rssi = NeighboringList.get(i).getRssi();
if(rssi == NeighboringCellInfo.UNKNOWN_RSSI)
{
dBm = "Unknown RSSI";
}
else
{
if(rssi >= 0 && rssi < 32)
{
dBm = String.valueOf(-113 + 2 * rssi) + " dBm";
}
else
{
dBm = "Unknown value:" + Integer.toString(rssi);
}
}
stringNeighboring = stringNeighboring
+ String.valueOf(NeighboringList.get(i).getLac()) + " : "
+ String.valueOf(NeighboringList.get(i).getCid()) + " : "
+ String.valueOf(NeighboringList.get(i).getPsc()) + " : "
+ String.valueOf(NeighboringList.get(i).getNetworkType()) + " : "
+ dBm + "\n";
}
Neighboring.setText(stringNeighboring);
Neighboring cells are reported in two different ways:
On GSM/GPRS (which seems to be the network you were on when you took your screenshot) you should get the MCC/MNC/LAC/CID tuple for the neighboring cells. I see you get valid CID values. The PSC will always be -1 if you're on a GSM (2.xG) network, as the PSC has no meaning on GSM (PSC is a CDMA parameter and GSM is TDMA-based).
On UMTS things are different: For neighboring cells only the PSC is reported, and you will not find out their other parameters unless you connect to them.
LTE is in principle similar to UMTS, but with slightly different names: instead of LAC and CID you have TAC (Tracking Area Code) and CI (Cell Identity); instead of a PSC you have a PCI (Physical Cell ID). However, they do essentially the same as their UMTS counterparts.
Note, however, that implementation varies greatly between devices: Some phones will not report PSC even on 3G networks, and some will never report neighboring cells. The Nexus S (as most Samsung-built devices) reports neither.
Not sure about the LAC=0, though. It might mean "same LAC as current cell", in which case it would be interesting to see the output from the boundary of a Location Area, where the phone can pick up cells with multiple LACs. (Would we be seeing cells from both LAs? Or just from "our" LA? What LAC would be reported for cells from a neighboring LA?)
The mobile device should be aware of the neighbouring cells, so that it can hand over to a better cell if necessary. In any case, you've told it to get information about neighbouring cells, so that's what it should do. Your results don't seem to match up to what is described in the Android documentation either.
I would report this problem to the device vendor as a firmware bug.
I can imagine a situation where you would see a neighbouring cell with a stronger signal if for example the cell was GSM, and the device preferred a UMTS cell with a weaker signal, but this should be obvious from the network type field.
Related
I'm working on project using oximeter.I want to smooth it out so I can use it for calculating hearthbeat. I'm gathering raw data from microphone , I put them in new array, lets say, sData[].
Signal is really crazy and jumps all over the plot as expected, so i tried smoothing it using moving average. So my main code looks something like this.
writeAudioDataToFile();
for (int a = 0; a < sData.length; a++) {
tempAvg += Math.abs(sData[a]);
if (a % numberOfSamplesAveraged == 0) { //Average from x samples
if (myIndex > SAMPLE_SIZE - 1) {
myIndex = 0;
}
tempAvg = tempAvg / numberOfSamplesAveraged;
if (tempAvg > 500) {
newDataArray[myIndex] = 500;
}else{
newDataArray[myIndex] = tempAvg;
} //This is suppose to clear the high peaks.
Log.d("isRecording - Average from " + numberOfSamplesAveraged + " numbers.", "newDataArray[" + myIndex + "] = " + newDataArray[myIndex]);
tempAvg = 0;
myIndex++;
}
}
notifier.notifyObservers();
Log.d("Notifier", "Notifier Fired!");
Thread.sleep(20); //Still experimenting with this value
It looks so messy, but the plot (I'm using AndroidPlot btw) looks good but it is so inaccurate so I can't calculate the hearthrate from it. It has so much "Bounce" in "high" state. I found on internet that some kind of filter (Maybe IIR filter) will do the job. So i just wanna ask you guys how can i achieve a nice smooth chart? Is IIR filter the way to go? Is there any free applet/lib to smoothen it out?
This is my first question here so I'm really sorry if it is badly written.
If you will need any more information to help me, just ask.
Here is a picture how my chart looks like now.
http://oi62.tinypic.com/2uf7yoy.jpg // Cant post images im new here.
This is a lucky one though.
I need smoother output.
Noises, which occur at measurement, have high frequency. You should filter your signal, that is you should retain low frequency part of signal and suppress high frquency part of signal. You can do it, making a low-pass filter. It could be, for example, first-order inertial model. I suggest make a pass-band till ~~10 kHz, since people hear sound from 2 kHz to 20 kHz. Then appriopriate sample time is 0,0001 sec (0,1 ms). Discrete model has following equation:
y[k] = 0.9048*y[k-1] + 0.09516*u[k-1],
where u is a measured vector (directly from microphone, input in our filter),
and y is a vector you want to analyze (so output from our filter).
As you can see,, you can calculate a sample number 1, and you can just assign 0 to the sample number 0. After all, you can try to plot y vector.
From this question I can see how to get total unread: Get number of unread sms
I have searched for this on Google but unfortunately do not understand how I may go about this.
I am wondering if it is possible to get the number of texts (unread) for a specific number, or, to do more work on my end, get the number of unread texts for each phone number in the list, and then make my own comparisons. The end result would be that I am able to, for example, take the number 111 and see how many unread tests I have from them or to simply get an ArrayList or similar construct containing numbers and unread texts for each, through which to loop and compare against the number 111.
Use columns from android.provider.Telephony.TextBasedSmsColumns in your ContentResolver query to find SMS messages that are from a specific address and not read:
Use these column contants:
Telephony.TextBasedSmsColumns.ADDRESS
Telephony.TextBasedSmsColumns.READ
Something like this:
ContentResolver resolver = context.getContentResolver();
Cursor cursor = resolver.query(Telephony.Sms.CONTENT_URI,
null,
"WHERE " + Telephony.TextBasedSmsColumns.READ + " = ? and "
+ Telephony.TextBaseSmsColumns.ADDRESS + "= ?" ,
new String[]{"false", "+1 555 555 1212"},
Telephony.Sms.Conversations.DEFAULT_SORT_ORDER);
int unreadCount = cursor.getCount();
Bit of context...
In my project I have one embedded for loop that outputs data whereby for each category show the item and within each item show its property so in reality the output I generated is 3 columns of data in the console (headings: Category/Item/Property) The for loop to show this data looks like this (Variables are set earlier on in the method):
for... (picks up each category)
for...(picks up items in category)
for (String propertyName : item.getPropertyNames()) {
out.println(category.getName() + "\t"
+ itemDesc.getName() + "\tProperty:"
+ propertyName);
}
}
}
The purpose of the project is to provide a more dynamic documentation of the properties of set components in the system. (The /t making it possible to separate them in to individual columns on a console and even in a file in say an excel spreadsheet should I choose to set the file on the printstream (Also at the start of this method.))
The Problem
Now for the problem, after the for loops specified above I have generated another for loop separate from the data but shows the list of all the functions and operators involved in the components:
//Outside the previous for loops
for (Function function : Functions.allFunctions) {
out.println(function.getSignature());
}
What I want is to set this list as the 4th column but the positioning of the for loop and the way it is set leaves it fixed on the first column with the categories. I cant add it after property names as the functions are more generic to everything in the lists and there maybe repetitions of the functions which I am trying to avoid. Is there a way to set it as the forth column? Having trouble finding the sufficient research that specifies what I am looking for here. Hope this makes sense.
One solution, if the total amount of output is small enough to fit in memory, is to simply save all the data into an ArrayList of String, and output it all at the very end.
List<String> myList = new ArrayList<String>();
for... (picks up each category)
for...(picks up items in category)
for (String propertyName : item.getPropertyNames()) {
myList.add(category.getName() + "\t"
+ itemDesc.getName() + "\tProperty:"
+ propertyName);
}
}
}
int i = 0;
// Here we assume that the total lines output by the previous set of loops is
// equal to the total output by this loop.
for (Function function : Functions.allFunctions) {
out.println(myList.get(i) + "\t" + function.getSignature());
i++;
}
I have been running the following query to find relatives within a certain "distance" of a given person:
#Query("start person=node({0}), relatives=node:__types__(className='Person') match p=person-[:PARTNER|CHILD*]-relatives where LENGTH(p) <= 2*{1} return distinct relatives")
Set<Person> getRelatives(Person person, int distance);
The 2*{1} comes from one conceptual "hop" between people being represented as two nodes - one Person and one Partnership.
This has been fine so far, on test populations. Now I'm moving on to actual data, which consists of sizes from 1-10 million, and this is taking for ever (also from the data browser in the web interface).
Assuming the cost was from loading everything into ancestors, I rewrote the query as a test in the data browser:
start person=node(385716) match p=person-[:PARTNER|CHILD*1..10]-relatives where relatives.__type__! = 'Person' return distinct relatives
And that works fine, in fractions of a second on the same data store. But when I want to put it back into Java:
#Query("start person=node({0}) match p=person-[:PARTNER|CHILD*1..{1}]-relatives where relatives.__type__! = 'Person' return relatives")
Set<Person> getRelatives(Person person, int distance);
That won't work:
[...]
Nested exception is Properties on pattern elements are not allowed in MATCH.
"start person=node({0}) match p=person-[:PARTNER|CHILD*1..{1}]-relatives where relatives.__type__! = 'Neo4jPerson' return relatives"
^
Is there a better way of putting a path length restriction in there? I would prefer not to use a where as that would involve loading ALL the paths, potentially loading millions of nodes where I need only go to a depth of 10. This would presumably leave me no better off.
Any ideas would be greatly appreciated!
Michael to the rescue!
My solution:
public Set<Person> getRelatives(final Person person, final int distance) {
final String query = "start person=node(" + person.getId() + ") "
+ "match p=person-[:PARTNER|CHILD*1.." + 2 * distance + "]-relatives "
+ "where relatives.__type__! = '" + Person.class.getSimpleName() + "' "
+ "return distinct relatives";
return this.query(query);
// Where I would previously instead have called
// return personRepository.getRelatives(person, distance);
}
public Set<Person> query(final String q) {
final EndResult<Person> result = this.template.query(q, MapUtil.map()).to(Neo4jPerson.class);
final Set<Person> people = new HashSet<Person>();
for (final Person p : result) {
people.add(p);
}
return people;
}
Which runs very quickly!
You're almost there :)
Your first query is a full graph scan, which effectively loads the whole database into memory and pulls all nodes through this pattern match multiple times.
So it won't be fast, also it would return huge datasets, don't know if that's what you want.
The second query looks good, the only thing is that you cannot parametrize the min-max values of variable length relationships. Due to effects to query optimization / caching.
So for right now you'd have to go with template.query() or different query methods in your repo for different max-values.
I'm trying to build out a simple app engine datastore entity that basically keeps count of how many times it was viewed. I've got the code setup in a JSP file that does increment the variable, however every time it seems to increment by 2 rather than one. Here's the code in question.
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Entity story = datastore.get(KeyFactory.stringToKey(request.getParameter("story_key")));
String json_out = "";
int num_views = 0;
if(story.getProperty("views") != null) {
num_views = Integer.parseInt(story.getProperty("views").toString());
}
//Update the donated status of this object.
story.setProperty("views", num_views + 1);
datastore.put(story);
json_out += "{";
json_out += "\"title\":\"" + story.getProperty("title") + "\", ";
json_out += "\"views\":\"" + num_views + "\"";
json_out += "}";
out.println(json_out);
Any idea why it would be incrementing by 2? I've even tried subtracting one when I get the number of views, but then the number just stays the same all the time as you'd expect. Really odd.
If you are implementing a counter using the datastore, you should you techniques that allow for high throughput. Your solution above could easily write to the datastore more than a few times per second, violating HRD policies. Also, it's not thread safe (not run in a transaction, so updates could apply out of order and your result is not what you expect). Try out shard counters, which fix these issues:
http://code.google.com/appengine/articles/sharding_counters.html