Hi, Habr. You need to save water, everybody knows it. This case is useful. And in order to stimulate citizens in this good deed, water meters are installed everywhere in our country. And without the counter you pay several times more.
The installation process itself looks like this: call the master from a certified office, he sets up the meter, seals it, signs and stamps the papers with which you go to a single settlement center, and your meter is registered.
Further, through the site, or by phone you pass the testimony. But as usual, bloodsuckers and crooks of various stripes stick to any good deed. To make my life easier and make it harder for spammers and scammers, I wrote the application “Journal of Counters”.
')

Under the cut, I will tell you about reflections, creative throwing, and the development process, in six parts, with intermission, lyrical digressions and technical details.
Part One - Militant
Here you set yourself counters, sealed up and submitted information to the Single Window service. You live quietly, you transfer the data according to indications, and you are not blowing. And then a year or two later the bell rang, from the Unified Settlement Center / Administration / City Metrology Center / Managing Company itself (underline the appropriate). In the tube, the warlike lady / young man says that the life of your counter has expired - and put on a new one more quickly - and when will our master arrive?
Scammers behave aggressively, throw out the flow of words, threaten to transfer to an increased tariff without meters, fines and sanctions. Since they call in the middle of the working day, when everything is at work, and the houses are mostly pensioners, they are mainly intended for them as the most gullible people.
General recommendation - do not be shy, and send these bad people to distant countries. And information about the timing of verification, you can look at the passport on your counter.
But sometimes you do not remember to point out when and what was changed and installed, and where the passport from the device was stuffed.
Dialogue with the spammer - I have a neighbor(C) -spammer, (I) - I
(C) - (and did not even say hello, hamlo) RoscosmosVodoNanoKanal named after Saint Metrology. You must change the water meter! You have expired!
(I) - (in a voice of panic) Oh! What to do!
(C) - (happy, fish got something) We will send you a master. When can you accept?
(I) - And what will the master do?
(C) - He will change your counters for new ones!
(I) - Why change it?
(C) - (angry) Because that's the way it should be! Speak the address!
(I) - Wait a minute. I have a neighbor, he is a professional builder. He told me that the parts are being changed, and I don’t have to take the counter off!
(C) - (already with a soul) Your neighbor does not understand anything! This is metrology!
(I) - (righteous anger) You are deceiving me! My neighbor is a PROFESSIONAL builder !!! He knows best of all !!!
(C) - (irritation and anger, mixed up in this voice) Oh, so !!! Well, then you will be sent a written notice !!! And you will pay at a higher rate !!! (beeps ....)
Part Two - Reflections.
So, in order not to look for information on the counters, it is necessary to have it at hand. Can write it in a notebook and put it on the table? And at the same time in this notebook I will write down the monthly readings of the counters.
The solution is simple and effective. Complicated by the fact that I have three funny kids for whom any paper is within reach (including documents and wallpapers) - a potential album that needs to be painted or torn into small pieces. For the same reason, at home sometimes you will not find a normal writing pen or pencil. And you have to write testimony on stubs of napkins (cuffs / clay tablets).
Well, I'll get a table in Excel, a tablet and I will write everything there. But then again, I will not take the computer to the bathroom and toilet to record the readings. Otherwise, we again return to the piece of paper and pen.
OK. I will use the tablet. But all that could at that time provide the Market - either paid, or does not correspond to my idea of ​​the beautiful. And in the end I am an Android developer, or where?
Dialogue with a spammer - Think of the soul, Maria(C) - Good afternoon, we want to offer you to switch to a new Internet, from the best provider. We have the most profitable ...
(I) - Excuse me, please introduce yourself.
(C) - Eeee ... Maria. So ...
(I) - (solemnly) Maria! I want to talk to you about God!
(WITH) - …
(I) - Do you want to talk to me about God? Mary, I can't hear you!
(C) - ... We actually ...
(makes an attempt to bring everything back to the original conversation)
(C) - Listen, we want to offer you favorable terms ...
(I) - (adding a pinch of righteous anger) Mary! What are you speaking about?!!! What could be more important than talking about God? !!!
(C) - As I understand, you do not want to talk. (beeps ...)
Part Three - Preparatory
So, we will make a plan in which we list everything that we need.
The first is to have on hand all the data on the counters. Namely: number, model, replacement date, personal account, service company contacts and master installer.
The second is a handy tool for recording monthly readings, as well as some simplest analysis tool.
The third is to be able to have several apartments, for example, to keep statistics on the apartment of parents.
Fourth - if you like to use, do not be greedy and share with the world.
Dialogue with the spammer - we are guided by the person(C) - Good afternoon (and calls, bastard, my name). My name is Vitaliy. I want to offer you a profitable offer for managing your capital.
(I) - Vitalka !!! It's you?!!! How many years!!! How many winters !!!
(C) - (slightly dumbfounded) I ...
(I) - Damn !!! I waited for your call !!! How are you?!!! As a wife?! Like children?!!!
(C) - (ohrenev deeper) I'm actually not married ...
(I) - Well, what a fool you are. A man without a wife, like a caterpillar without a tree!
(C) - Well, I understand how you got it with calls. Goodbye…
Part Four - Experiments.
The first option was simple and unsophisticated. Everything is built on a ListView. No settings. But in view of my then hobby for pixel art, I painted the icons myself.
Old designThe main thing is that the application worked. Statistics were kept (by the way, it came in handy when I had to run up with Mosenergo).
In view of the fact that the application suited me - I created a developer account in the Market, and I posted it to the public. In parallel, wrote a post on Picaba.
The main criticism was the unassuming appearance, the complete absence of Design Material, and badges that "seemed to be returned to the 90s." But overall, the reviews were positive.
In the meantime, I wrote another application, which I
told about in Habré. Quite unexpectedly for me, the number of downloads of the “Journal of Counters” jumped sharply upwards.
Feeling responsible to more than 5,000 users, I decided to rewrite the application.
To begin with, I sat down with a notepad (miraculously saved from my Indians), analyzed the comments, and wrote out the most interesting sentences. Moreover, some were very unexpected, but really add convenience to the user. For example, add the ability to turn on the flashlight, when recording the meter readings.
I had to rewrite a lot. And taking into account work and family, I had to work at night, and the alteration took almost more time than writing the first version.
Fully redesigned:
New designAdded settings, and the ability to save / load data to / from file:

I redraw the icons in the vector, fixed a bunch of glitches and errors, added a heat meter, and wrote instructions. In general, almost from scratch redid.
Dialogue with a spammer - Talking with the Gods(C) - Good afternoon. I speak with (my name). We are from a partner bank from Tinkoff Bank. Do you want to take a loan?
(Me not
(C) - You can find out why?
(I) - The gods forbade me to do this.
(C) - (pause ....) Excuse me, what?
(I) - The gods forbade me to take loans.
(C) - Maybe all the same ...
(I) - (indignantly) Do you want to argue with the Gods? !!!
(C) - Eeee ... no ... Goodbye ...
Part 5. Developer Tricks
When developing an application I ran into a bunch of interesting points. For example, if you want to create a ListView, within which there will be not just data, but also control elements (checkboxes, editable fields), you may encounter the fact that the information is not displayed correctly, or is passed to the parent activity.
For example, in my case it was a ListView and its adapter, filled in when making readings.
Dialog for data entryEverything was normal for ordinary, single-rate meters, but nonsense began for multitariff ones. That's how I conquered it. We get the adapter (amountList)
ListView lvAmounts = (ListView)mView.findViewById(R.id.lv_newAmount_Amount); insertAmountAdapter insertAmountAdapter = new insertAmountAdapter(getActivity(), amountList); lvAmounts.setAdapter(insertAmountAdapter);
Adapter class (there is also a class that monitors the entered AmountTextWatcher readings):
Adapter class public class insertAmountAdapter extends BaseAdapter { Context mContext; ArrayList<Amount> amountList; LayoutInflater mLayoutInflater; EditText etAmount, etTariff; TextView tvTariffTitle; public insertAmountAdapter(Context mContext, ArrayList<Amount> amountList) { this.mContext = mContext; this.amountList = amountList; mLayoutInflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { return amountList.size(); } @Override public Object getItem(int position) { return amountList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if(view == null){ view = mLayoutInflater.inflate(R.layout.item_insertamount, parent, false); etTariff = (EditText)view.findViewById(R.id.et_amount_tariffInfo); etTariff.addTextChangedListener(new AmountTextWatcher(view, etTariff, amountList)); etAmount = (EditText)view.findViewById(R.id.et_amount_Amount); etAmount.addTextChangedListener(new AmountTextWatcher(view, etAmount, amountList)); } etAmount.setTag(position); etAmount.setText(String.valueOf(amountList.get(position).getAmount())); etAmount.setFilters(new InputFilter[]{new DigitalFilter(3)}); tvTariffTitle = (TextView)view.findViewById(R.id.tv_amount_tariffTitle); tvTariffTitle.setText(amountList.get(position).getTariffTitle()+", "+amountList.get(position).getUnit()); etTariff.setTag(position); etTariff.setText(amountList.get(position).getTariffValue()); etTariff.setFilters(new InputFilter[]{new DigitalFilter(2)}); return view; } } class AmountTextWatcher implements TextWatcher { private View view; private EditText editText; private ArrayList<Amount> amountList; public AmountTextWatcher(View view, EditText editText, ArrayList<Amount> amountList) { this.view = view; this.editText = editText; this.amountList = amountList; } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { if(editText.equals(view.findViewById(R.id.et_amount_Amount))){ amountList.get(Integer.parseInt(editText.getTag().toString())).setAmount(Double.valueOf(s.toString().isEmpty()?"0":s.toString())); } else if(editText.equals(view.findViewById(R.id.et_amount_tariffInfo))){ amountList.get(Integer.parseInt(editText.getTag().toString())).setTariffValue(s.toString().isEmpty()?"0":s.toString()); } return; } }
As you can see, the tracking of the working line goes through setTag and getTag.
Also, I wanted to make instructions not just with text, but with illustrations. For this, I decided to use html markup. But when working with her, there are some nuances.
Create an instruction in strings.xml:
String variable <string name="instructionText" formatted = "false"> <![CDATA[ <h3> :</h3> <p><img src="add_btn_instruction"> <b> </b></p> <p><img src="open_btn_instruction"> <b> </b></p> <h3>:</h3> <p> (, , ) - <b> </b>, .</p> <p> ( , ..) - <b> </b>.</p> <p> - , . .</p> <h3> :</h3> <h6>( , )</h6> <p><b></b> .</p> <p><b></b> , .</p> <p><b></b> .</p> <p>1)<b> /</b> - .</p> <p>2)<b> </b> - .</p> <p><b>/ </b>:</p> <p>1)<b> XML-</b> - <b>MLLDataOut.xml</b>, <b>MeterListLog</b></p> <p>2)<b> XML-</b> - <b>MLLDataIn.xml</b>, <b>MLLDataOut.xml</b>, <b>MeterListLog</b>.</p> <p><b>!!! , .</b></p> <h3> :</h3> <p><b></b> - , (: - ).</p> <p><b></b> - .</p> <p><b></b> - .</p> ]]> </string>
We add pictures, under the same names that are spelled out in the instructions, in the drawables folder (I have this: add_btn_instruction.png and open_btn_instruction.png).
In the required place we create a line, TextView and ImageGetter:
String instructionHTML = getString(R.string.instructionText); TextView tvInstruction = (TextView)findViewById(R.id.tv_instruction); tvInstruction.setText(Html.fromHtml(instructionHTML, htmlImageGetter, null)); Html.ImageGetter htmlImageGetter = new Html.ImageGetter() { public Drawable getDrawable(String source) { int resId = getResources().getIdentifier(source, "drawable", getPackageName()); Drawable ret = InstructionActivity.this.getResources().getDrawable(resId); ret.setBounds(0, 0, ret.getIntrinsicWidth(), ret.getIntrinsicHeight()); return ret; } };
Dialogue with a spammer - Time to sleep, and all in bed(C) - Is it a flat or a company ?!
(I) - What is the question?
(C) - We are conducting a sociological survey ...
(I) - Woman, do you even look at the clock? It's already ten o'clock!
(C) - (righteous indignation) Well, if you want to sleep, then you need to turn off the phone! (beeps ...)
Part 6. Advertising and all-all-all.
As already mentioned, the application was originally written for itself. And no investment in advertising is not done. The only thing is articles on Picaba, and indirectly on Habré. Translated into English, just in case.
Monetization, there is no. The app is free and without ads. As I said earlier, in another article, “The author does not receive any material benefit, except moral satisfaction (and only a little, to meet megalomania), and the desire to share a useful tool with the community.”
The plans for the next version add a reminder, expand the list of meters (meters with billing, drainage), translate into several languages ​​(German, Belarusian, Ukrainian, perhaps Kazakh).
That's actually the whole story of writing my very first application.
Dialogue with the spammer - Little Bulgakov(C) - Hello. How can I contact you?
(I) - Call me, Good Man, Good Man.
(beeps ....)
So let me leave. I hope someone will be useful. If someone has comments or hints, I’ll listen to them with great pleasure.