Moto X announcement
Moto X announcement
I’m quite disappointed by the Moto X announcement. It’s a well designed phone, battery life should be spectacular, and they got rid of some of the terrible themed junk that they put on their Droids, but it falls down on a few major points.
- Running 4.2.2, not 4.3 - how am I going to use BLE?
- To be priced as a high-end phone, even though it’s not really
- Sold on contract, as opposed to unlocked, sold outright
- Launching with a dated version of Android, and updates will need to be approved by carriers
- Google Play Edition missing at launch
I really don’t want to buy another phone that ties me to a particular carrier (and phone) for another two years, when it’s likely that the phone won’t provide me with a good experience for more than one year. It seems unlikely that the Google Play Edition, when launched, will support Verizon. I don’t care as much about the Google Play Edition as I do about the fact that the carriers have to approve updates. Verizon is just plain awful at that; it’s a big reason why I’m running CyanogenMod on my Verizon Galaxy Nexus.
The customizations and optimizations look cool, but I’ll be holding out for the next Nexus phone.
ViewPager inside a ViewStub inside a TabHost inside a ViewStub
ViewPager inside a ViewStub inside a TabHost inside a ViewStub
This is a wacky experiment to hash out what’s necessary to create some views. I had some specific needs in a project that I’m working on. I needed a TabHost within a ViewStub, which contained ViewStubs, when inflated became ViewPagers. I also didn’t want to use fragments for this, so this is all done with normal views. It should be a fairly lightweight strategy. I populated it with a bunch of images, so those will chew up quite a bit of heap space, but the app should launch quickly, and be generally responsive.
There are no dependencies, and no permissions used for this. Feel free to pull down the code and run it yourself, this whole thing will make a lot more sense once you do. As I said, the code that I’ll be discussing was written as a sample implementation for another project that I am working on. Therefore, I didn’t spend much time optimizing it, or flattening out the hierarchy as much as I could have. There are some obvious questions that I have about things that might be removed, and I’ll try to note them as we go.
Pretty screenshots
In case you are too lazy, or can’t, for some reason, install the app, here’s a few screenshots that might illuminate things for you:
.
.
One thing to note from the above images is that swiping between pages does not change the current tab.
Main layout
Let’s start by looking at the main layout file, since that’s usually a good place to start, and will generally give you a rough idea of what you might expect to see on screen.
As you can see, there’s not much here. We’ve got a toggle button and a couple of empty views. The FrameLayout view will be used what gets set to VISIBLE/GONE by the toggle button. I probably could’ve ditched that, and used a view inside the ViewStub, but this was slightly easier to understand, slightly. Inside the FrameLayout, you’ll see a ViewStub; this allows us to inflate another layout in that spot whenever we need it. It’s cheap and light-weight, because you’re not inflating anything until it’s needed, so when the view is initially built, this will be empty until you inflate it.
Inside the ViewStub
If you look at the layout parameter defined in the ViewStub, it’s specifying another layout file called tabstub.xml. Let’s look at that.
This layout is a bit more interesting, as there are more things going on here. Mainly though, it’s just a standard tab layout where the tabs are not the parent view (not sure if this is strictly necessary), and where the contents of each tab are ViewStubs.
Tab layout
The layout for the individual tab, once inflated, is pretty simple, it’s just a ViewPager that we’ll be programmatically inflating and adding more views to.
Layouts
Here we have the object that’s going to keep track of all of the layouts in all of the ViewPagers across all the tabs. It’s an enum, so that the logic will be a bit cleaner. Each of the enum’s constants represents a tab, and contains an array of layout references.
Individual page
Here’s what one of the pages looks like, couldn’t be any simpler.
Starting out in the code
When we first launch this app, the view is blank, except for a toggle button. We need to click the button to get started. Here’s what gets run when you click ‘toggle’.
This does a couple of things, first it needs to initialize the tabs, in case they haven’t yet been inflated. Second, it sets the visibility of the view that contains the tabs.
Initializing the tabs
When we clicked the toggle button, the first thing that happened was that we needed to initialize the tabs. This means both inflating the views, as well as setting the TabHost’s contents.
If the tabs are already initialized, we don’t need to do anything. Otherwise, we need to build them, and inflate the first ViewPager, since that’s visible. This is done with initPager()
.
Initializing the ViewPagers
Each tab has its own custom instance of ViewPager, and layout file. This method simply associates the two.
When we swipe between pages in the ViewPager, we need to make sure that the layouts for each page are inflated, so we override instantiateItem
in our PagerAdapter.
What happens when tabs are clicked
When tabs are clicked, we need to make sure that each ViewPager is initialized, just like the first one.
Conclusion
While I’m still in the middle of implementing this strategy in my project, the demo worked out perfectly. I’m fairly pleased with the performance, though the images used do chew up quite a bit of memory. If you’re looking at DDMS when this is running, you might see your heap size grow to ~30MB.
AngularJS with IndexedDB using a helper library
AngularJS with IndexedDB using a helper library
In working on my podcast app, podrad.io, I wanted to be able to persist data, so that users could keep their subscriptions between visits, without losing anything, and without my needing to do anything server-side. When I was writing podrad.io, however, my goal was to get something written as quickly as I could, get it out, and then iterate on it as I have time. With those goals in mind, I used LocalStorage for persistence, it was simple, and did the job. Now, I’m going back and looking at what needs to be added or fixed, and the data persistence is top on my list.
HTML5 client-side data persistence
While I’m sure most of you know this already, there are three competing APIs for doing data persistence client-side in HTML5, LocalStorage, IndexedDB and WebSQL. LocalStorage is supported everywhere, but it only allows the mapping of strings, which means that you are serializing and de-serializing data whenever you want to touch the disk. That’s fine for really small amounts of data, but it won’t scale, unless you want to design around this odd constraint. WebSQL and IndexedDB both have support in various browsers, however neither of them are supported everywhere, and WebSQL is being deprecated in favor of IndexedDB. WebSQL is a limited SQL implementation that uses sqlite3 (again, it’s not part of the HTML5 spec, so it’s a non-starter). IndexedDB is an indexed NoSQL object store, meaning that you create a data-store and put your objects there. As I mentioned, IndexedDB isn’t fully supported yet, however there is a polyfill lib that helps here.
IndexedDB
If you look at some code that uses IndexedDB, one of your first reactions will likely be, ‘gee, that’s an unnecessarily verbose API!’ That was my first reaction too. My second reaction was that the code linked above doesn’t work, fantastic. As I was googling around for a fix, I stumbled upon IDBWrapper, a wrapper class for IndexedDB. The API for the wrapper is quite simple, and easy to understand; to me, it’s what the IndexedDB API should have looked like - or at least closer to that.
Sample app
I wrote a sample todo list app (in AngularJS) that uses some of IDBWrapper’s functionality.
Generic bits, index.html and app.js
Starting with the index file:
I cut out all of the redundant, and auto-generated bits, and just left this with the bare-bones for us to look at. There are a couple of interesting pieces here. First, I used Font Awesome for the icon font, I’ve found that to be easier to deal with that Bootstrap’s font, and it scales better. Next, you’ll see that I included the IndexedDBShim, and according to the documentation there, that’s all that I should need to do to use it. However, I’m not sure if IDBWrapper will use it or not, I need to look into that. Finally, I installed IDBWrapper with Bower, so it’s in my components directory.
App routing in app.js:
No surprises here, just your standard app.js file.
Main view and controller
We’ve got two basic parts the input and the display for our todo list. The input is a basic form that populates $scope.itemname
in our controller, and calls $scope.addItem()
when submitted. The view part simply iterates over the items array and displays the contents of each object, using ng-repeat
. We also have a delete button that calls $scope.deleteItem(id)
on the list item that we want to remove. Pretty standard stuff.
The controller handles those calls for addItem
and deleteItem
, as well as does our querying of the data store. Very simply, we start out by initializing the data store, then getting any existing objects within it, and update the view with those. We need to call $scope.$apply()
in the getItemsSuccess
callback because otherwise, our view does not get updated. Here’s a write-up on why that is. As you can see, the IDBWrapper API is quite straight-forward, and easy to use.
Conclusion
That was all pretty simple stuff, I liked the wrapper, and will probably use it in the future. One thing that I’m not sure on is whether or not it will use the shim if it’s available, and I’ll be looking into that shortly. Full code available on GitHub.
Restore the national moto "E Pluribus Unum". | We the People: Your Voice in Our Government
Restore the national moto “E Pluribus Unum”. | We the People: Your Voice in Our Government
https://petitions.whitehouse.gov/petition/restore-national-moto-e-pluribus-unum/58JXzNBB
Go back to our original motto, as opposed to the religious one that was introduced in 1954. “E Pluribus Unum” means “out of many, one”, a unifying statement that does a great job of summing up the true nature of this country.
Meta Art
Meta Art
I had an idea for an art project that I’ve been wanting to try out for a few months now, and today, I finally got around to doing it. The general idea was to create some painting, or piece, and then attach a description to it, as you might see in a gallery, or in a museum. My idea was a bit more meta.
Before I describe much more, let’s look at the results:
You probably can’t read the description, here it is:
P. Munio Zubizarreta
нигилизм, 2003
wax on canvasWorking through a crippling depression, Zubizarreta created this series to show the hollowness of existence. Having suffered several personal tragedies within the span of the last four years of his life, Zubizarreta was near his breaking point, and had lost all hope. Out of touch with his remaining friends and relatives, Zubizarreta had become a recluse, his only escapes were his art and the heroin that would eventually kill him.
No, my name is not P. Munio Zubizarreta, and as far as I know, P. Munio Zubizarreta doesn’t even exist. The story is fictional. I thought it might be interesting to super-impose meaning onto art that may not really mean anything on its own. When you see a painting with a caption, and a little blurb about it, the blurb can change your perception of the work. That’s what I wanted to do here, to change people’s perceptions of the work, by adding a little story. Thus, meta art, the art is the reaction that people have to the combination of the images and the story that has been created.
I also thought that it would be kind of fun to have a description that contrasted strongly with the piece. The title, according to Google Translate, means nihilism in Russian. The story is depressing, whereas the images are bright and colorful.
My request to the US Copyright Office to make the exemption of circumvention of hardware permanent for mobile computing devices
My request to the US Copyright Office to make the exemption of circumvention of hardware permanent for mobile computing devices
Originally submitted by emil10001 on Thu, 01/26/2012 - 14:44
I am writing in to request that the exemption of circumvention of copyright protection systems be made permanent for device classes 4 and 5. Not extending the exemption will harm both the consumers and the manufacturers of mobile computing devices. Not allowing software modifications may violate the license of the software that the manufacturers use.
The ability for a community of users to legally, and easily, alter or replace the firmware that has shipped with their devices has made a large impact on the mobile computing world. Communities have picked up support for many smartphones and tablets and have continued development for these platforms long after the manufacturer had dropped support for them. This has increased the value of the hardware to the consumer. A consumer who has the ability to purchase a device, for which a community supported firmware is offered, will be assured that their device will be supported for an appropriate amount of time. They will be able to feel comfortable in that their major investment in such a rapidly changing technology will not be a poor investment, only providing them with six months, or a year’s support on a device that they are contractually stuck with for two years. It is in the manufacturer’s best interest to cultivate such a community and to encourage development of this sort. However, in cases where the manufacturer is disinterested, or prevented by the mobile network operator, the consumer should not be punished. Instead, the consumer should be provided the basic protection of being allowed to use their device as they see fit, for as long as they can make their device useful, and as long as they are not doing harm – which would be a separately addressable issue anyway.
Further, many devices ship with software licensed under the GPL. In order to comply with the GPL, manufacturers must provide source code and other necessary pieces to their consumers. Limiting the consumers’ ability to use the provided code would at the very least violate the intent of the GPL, but it may also violate the letter of the license. The GPL is used as a license to ensure that the code contributed for free by the large community of software developers, like myself, is not stolen by large corporations, with large budgets, and put to use in proprietary systems. Rather, we require that code that we release under the GPL be made available, such that users can modify it to fit their needs. If the exception for circumvention is not made permanent, it could have a chilling effect on the mobile computing industry, as manufacturers of devices might be put in a difficult position of not being able to use the operating systems that their consumers demand (Android).
Thank you, emil10001
Help the EFF’s efforts in this cause here.
Oppose PROTECT-IP
Oppose PROTECT-IP
Originally submitted by emil10001 on Wed, 11/02/2011 - 10:01
I wrote a letter to Congress, and you can too! The PROTECT-IP act, if passed, has the potential to break the internet. Claims could be made about a website that the operators of that site would be unable to defend, and their site would be permanently blacklisted. My letter follows.
Oppose S. 968: Preventing Real Online Threats to Economic Creativity and Theft of Intellectual Property Act of 2011
Dear Sen. Bill Nelson and Sen. Marco Rubio:
I oppose S. 968 (“Preventing Real Online Threats to Economic Creativity and Theft of Intellectual Property Act of 2011”) because as the owner of a small internet based business, this bill has me worried. If passed, it has the potential to kill my business. Someone could claim that I am infringing on their copyright, and without my knowledge, or ability to defend myself, my site could be blacklisted, and I would be unable to continue to get new business. Potential clients might see this as a black-mark and avoid doing business with me.
While I do not host much in the way of video, I have posted several videos that I have recorded. Someone could make the claim that I was not the owner. I also have a site that mainly consists philosophical essays, and someone who might be offended by this may claim that I have stolen their work. There are many other dangers that arise from such a piece of legislation as this bill.
As I see it, you run the risk of putting many legitimate businesses in jeopardy by passing this bill. You would break the internet’s architecture. And, you would be trampling free speech. I fail to see how this could possibly be something worth supporting.
emil10001 Florida’s 22nd district
This letter is pending delivery to Sen. Bill Nelson [D, FL] and Sen. Marco Rubio [R, FL].
Beliefs vs Assumptions
Beliefs vs Assumptions
Originally submitted by emil10001 on Tue, 11/01/2011 - 11:57
There are some interesting differences that result from making decisions based on beliefs as opposed to making decisions based on assumptions. Since you can rarely be in a situation in which you have all possible information available to you in making a decision, you will need to rely upon either beliefs or assumptions, or some combination of those to make your decision.
I need to make decisions based on some assumptions that I have because I don’t have all of the information needed to make a fully reasoned decision. I do not need to believe that my assumptions are correct, as I know that they are just assumptions. If they turn out wrong, there is no need for me to change my beliefs, just discard some incorrect assumptions.
Belief - 2. confidence in the truth or existence of something not immediately susceptible to rigorous proof: a statement unworthy of belief.
Assumption - 1. something taken for granted; a supposition: a correct assumption. Synonyms: presupposition; hypothesis, conjecture, guess, postulate, theory.
The difference is that I have no attachment to my assumptions. I can easily discard them if I find them to be incorrect, and I actually do not even need to believe that my assumptions are correct. However, as you pointed out, we can’t always make decisions based on rigorous logic, and a main reason for this is that we don’t have all of the information. So, instead, we make assumptions about things that we are unsure about and hope for the best. We tend to accept that our assumptions might be wrong, and because of that, we might end up making the wrong decision. While we may be held responsible for the choice that we make based on that set of assumptions, it is difficult to blame someone acting in good faith who made a decision based on a faulty assumption. That said, there are poor assumptions, and then there are good assumptions, and if someone made a very poor assumption, then it may be easier to place moral responsibility on that person.
Beliefs are not so easy to discard, and people tend to be much more attached to them. If you make a decision based on your beliefs, it is a different thing from making a decision based on an assumption. Beliefs are generally unfalsifiable, and therefore have no real basis for believing them. (Please note that I am not trying to minimize yours or anyone else’s beliefs here, simply that this is what it is to have a belief.) When it comes to making a decision based upon a belief, I think that it would be more reasonable for you to be held morally accountable for that decision, as opposed to someone who acted on an assumption.
Example: A motorist is driving a car, and he sees someone on the side of the road, who looks like he is injured. The motorist needs to decide if he should stop and attempt to help this person out.
- Outcome 1
Assumption: This person could be dangerous. The motorist decides to keep driving, because this person could be dangerous. Assumption: The police probably already know about this. The motorist decides not to call the police, because they probably already know about this.
Here, we might not want to hold the person morally responsible for the action resulting from the first assumption, but we probably would want to hold them morally responsible for the second. The reason is because calling the police would not have any possible negative impact on the caller.
- Outcome 2
Assumption: This person is probably not dangerous. The motorist decides to pull over and help the person. The motorist calls the police because even if they already know about it, it doesn’t hurt to tell them again.
Here is an assumption made that may have a good outcome. The person on the side of the road may, or may not be dangerous, so it is possible that this was not a good idea to pull over.
- Outcome 3
Belief: It is always good to help people. The motorist decides to pull over and help the person. The motorist calls the police because even if they already know about it, it doesn’t hurt to tell them again.
Is it always good to help people? What if this person is a murderer, and they look injured because another motorist pushed him out of a moving car to save her life? Now, by helping this person, the motorist is possibly aiding a murderer. We might be tempted to say the same thing about the case where the assumption caused the driver to pull over, but they never made the moral argument that it was always good to help people. They just assumed that the person was probably not dangerous.
In the reverse, where the injured person is just there by bad luck, we would want to assign moral praise to the motorist for pulling over.
- Outcome 4
Belief: It is sinful to sit on the side of the road, imposing on motorists. The motorist decides not to pull over and keep driving. The motorist feels annoyed that this person has imposed upon him by sitting on the side of the road, so the motorist do not call the police.
This belief is harmful to the person on the side of the road. Declaring that they are sinful because they happen to be in a bad situation is arbitrary. It is easier to hold the motorist morally responsible here, because they have an arbitrary moral rule about the situation that informs their actions.
Here, I am trying to balance assumptions and beliefs, you can have good or bad outcomes from beliefs or assumptions. However, making a decision based on a belief rather than an assumption might change the way in which we would want to hold the decider responsible.
My response to a Whole Foods post promoting homeopathy
My response to a Whole Foods post promoting homeopathy
Originally submitted by emil10001 on Thu, 10/20/2011 - 10:04
I just saw an article on the Whole Foods blog that I thought deserved a response. The post was promoting homeopathy, and I felt it necessary to point out both what homeopathy is, why it does not make sense, and its dangers. I decided that it would be a good idea to post this here as well, since I am not sure how long the post will stay up on the Whole Foods site.
Dear Whole Foods,
As one of your customers, this post makes me very uncomfortable. At worst, this perpetuates pseudoscience, and encourages people to waste their money on water wrapped up in a package, pretending to be a remedy. The sort of reasoning that encourages people to subscribe to homeopathic remedies, could end up doing real harm to them, even killing them, in certain situations, if they do not seek real medical attention.
There is no evidence to support the claims that homeopathy makes. The basic premise of the practice is that by taking some ingredient that would normally cause certain symptoms, and put that ingredient or ingredients into a solution and dilute it down to nothing in water. When you see a number like 12c, that means that the process of dilution has occurred such that there is a concentration of the ingredient of 10^-24. At 12c, there is only a 60% chance that there is even a single molecule of the original ingredient remaining in the solution. At 30c, you would need to consume 10^41 pills (a billion times the mass of the Earth) to consume a molecule of the original substance. If you think this is drastic, Oscillococcinum (sold at Whole Foods!) is at a concentration of 200c. What’s more, the homeopaths claim that the dilution process increases the effectiveness of a substance. That is, a concentration of 1 is less potent than a concentration of 10^-24.
Why do they claim this works? Well, the claim is that the original substance somehow imprints its energy in the water, and that that energy is carried through the dilution process, and remains present long after there are no more molecules of the substance in the solution (of water). This is physically impossible. There is no evidence that this is true, because if it were true, we would have a very different understanding of the physical world that we live in than we do. Not only that, but imagine how much human waste, or animal waste, has been in contact with water. According to homeopaths, even though the waste is completely removed from the water, the essence is still there. And, again, according to the homeopathic view the essence of waste would grow stronger the more that it was diluted. Should we stop treating our waste water, for fear of an overdose?
On the topic of overdoses, a number of skeptics have tried to overdose on homeopathic remedies, taking entire bottles of remedies at once. No one was injured, and no one was cured of anything either. The evidence available suggests that homeopathic remedies are about as effective as a placebo.
One more important note, not all homeopathic remedies are created equal. Some of them do actually contain real, active ingredients. There was a cold and sinus nasal spray on the market called Zicam, marketed as an unapproved homeopathic product, contained zinc acetate at 10^-2 and zinc gluconate at 10^-1. Both of the ingredients are biologically active, and actually caused some users of the product to lose their sense of smell, a condition termed anosmia.
Maybe it would be good to end on a joke: Do you know what they call alternative medicine that’s been proven to work? MEDICINE!
References and good reading:
- What’s the harm? http://whatstheharm.net/homeopathy.html
- http://en.wikipedia.org/wiki/Homeopathy
- http://www.quackwatch.org/01QuackeryRelatedTopics/altbelief.html
- How homeopathic remedies are manufactured: http://www.youtube.com/watch?v=Zj2_MIPpZus
- Chemists on the idea that chemicals are bad: http://www.youtube.com/watch?v=w6ZsYCnlvPs
- An excellent short film promoting critical thinking: http://herebedragonsmovie.com/
- A funny sketch about a homeopathic hospital: http://www.youtube.com/watch?v=HMGIbOGu8q0
Bad PeerGuardian
Bad PeerGuardian
Originally submitted by emil10001 on Sat, 10/01/2011 - 16:10
I will try to make this one brief. If you are on a mac, do not install PeerGuardian. This application gave me weeks of trouble for something that I had only used once or twice. Basically, PeerGuardian is a safety tool for using P2P. The idea is that it will blacklist certain IPs/domains based on whether the IP address might be dangerous. Generally, the blacklisted IPs belong to RIAA/MPAA associates, and while I wasn’t downloading any movies or music, I figured that I could use some protection if I’m going to be using P2P for anything.
The Issue
The problem with PeerGuardian for Mac is that it actually did more than just block traffic to certain unsavory IPs while the application was running. Instead, it blacklisted my server, but only for port 22 (possibly other untested ports as well), while leaving port 80 alone. PeerGuardian also blocked access to one of my client’s servers. I was able to ssh from my macbook to other machines, and from other machines on my local network to my EC2 boxes.
Explanation
(Disclaimer - This section is basically my guessing about factors contributing to my issue. I have no real way of verifying whether or not this is an accurate explanation.)
It seems possible that PG was liberally blocking traffic on certain ports to certain IP groups. If there were some legitimate IPs residing on the EC2 cloud, worthy of blocking, where my VPS is hosted, as well as my client’s, that gets us part-way there to an explanation. Again, traffic was flowing through port 80 to both boxes, so PG may have been blocking only certain ports.
The other issue, the thing that made this difficult to track down, was that I had not been running PG when I was experiencing these issues. In fact, since I had downloaded it several weeks ago, I think that I only used it twice. The implication here is that the blacklist exists all the time, and blocks traffic whether you are running PG or not. I did not see any processes running that indicated to me that PG was running in the background, and PG does not use the system’s hosts.deny file to define what traffic to blacklist. Now, it was probably not that smart of me to download and run something like this without really looking into how it worked, but how was I supposed to guess that the thing would block traffic whether it was running or not?
These factors contributed to making this a very difficult problem to diagnose, the fact that I didn’t use it much, it wasn’t running, and it was randomly blocking legitimate traffic to EC2 servers, while allowing other ssh traffic to other places.
Resolution
I spent about two weeks, in the few free hours I could find, trying to fix this myself before posting the question on EC2’s forums and ServerFault. My ServerFault question provides a detailed look at what was involved in tracking down the root cause of this problem. Basically, once someone suggested that I try a traceroute from my macbook, the failure gave me something new to google, leading me to people with similar issues. The other symptoms that I was seeing were common symptoms of other problems, thus leading to many dead ends.
My advice is to find a different tool for security while using P2P. PeerGuardian can cause more harm than good.
Original discussion on Reddit.