Friday, May 21, 2021

Mobile ad networks /

Nautical Calculator for Android

Currently I am building a Nautical Calculator for Android. You can pre-register for the app on Google Play Store here:

In case you would like to try it out already, send a note to the developer email address that is displayed in the app's Play Store page.

I have also decided to daily publish development progress in a form of testing videos. So, you can get a glimpse of app's functionality in the following YouTube playlist:

And finally, a hosting company that I am using has a discount on .eu domain names, currently they go for $3.25 USD. There was no excuse for not purchasing one, so I've put up the app's homepage here:

Nautical Calculator for Android

Hosted on GitHub pages for free, under development, just as the app itself.

Thursday, May 13, 2021

ASUS N73 HDD Bracket/Caddy, 13GNZX1AM030-1 and 13GNZX10M10X-1 compatible

I had decided to install a second HDD in my ASUS N73, but I was missing a bracket for it. At that time there were no listings on eBay and that part was really hard to obtain. My improvised solutions weren't good enough and disk drive would sometimes get disconnected. It is a laptop anyway that you flip and carry around.

So, I've decided to make my own extra bracket. I took a caliper, measured the original bracket and modeled it in FreeCAD

The first bracket prototype was made on a 3D printer. I never thought that the plastic that thin will be strong enough to hold a HDD (of course it did not!), but I wanted to check is my model OK and make sure that everything does fit. The 'legs' broke right away and plastic shrank as it cooled so that experiment wasn't much of a success.

Obviously, a bracket that thin (0.55 mm) would be the best made of steel. I started to look for manufactures in China and soon enough I've found a company that offered to send me a free sample made in Cold Rolled Steel Plate technique.

If you need similar products in bigger quantity, you can reach them at:

JM FCX Metal Industrial Co., Ltd.
Chaolian Industrial Area, Jiangmen city, GD., P.R China
Tel: 0086-750-2037012
0086-189-2308-8730 (WhatsApp, Wechat)

If you are looking  for CAD files (iges, stl and FCStd formats) for the bracket, you can download them from here.

Monday, May 3, 2021

How NOT TO get banned from AdMob for 'click fraud'

  1. During development: use the test ad unit id. 
  2. For release: add test device(s) to your AdMob account.

As simple as that. In more details:

1. During development: use test ad unit id

Following  the AdMob integration instructions, you will be provided with the test ad unit id. Obviously, you will not hard-code it in your app, you will access it just like any other string resource - via Activity.getString method.

The example might be the following:

String    adId      = getString(R.string.ad_unit_id);
AdRequest adRequest = new AdRequest.Builder().build();

RewardedInterstitialAd.load(this, adId, adRequest,
new RewardedInterstitialAdLoadCallback() { ... });

Here I am creating a rewarded interstitial ad, but principle is the same for any other type of ads - banner, interstitial or native. 

Now we will place the given test ad unit id in a resource file, donottranslate.xml being an ideal candidate for that:

<?xml version="1.0" encoding="utf-8"?>
<string name="ad_unit_id">ca-app-pub-xxxxxxxxxxxxxxxx/x...</string>

Instead of placing this file in /src/main/res/values folder we'll put it in /src/debug/res/values (create it if it doesn't exist). 

This string resource will now exist only when we are building a debug version of our app, so we need to do the similar thing for a release version. We will create the folder (path) /src/release/res/values and we will put another donottranslate.xml file inside. This file will look exactly the same as the previous one, except that you will replace the test ad unit id with the real one that you got when you have created an ad. Your project structure should look something like this:

We're done regarding this part! Our debug builds will use the test ad and release builds the real one. Now let's get ourselves covered and make sure that we are not shown a real ad when we are testing a release build on our device(s).

2. For release: add test device(s) to your AdMob account

Once you are logged in your AdMob account, on the left hand side, close to the bottom of the navigation bar, open Settings and then Test Devices tab. Click on the Add Test Device button and fill out the form. Voila!


This blog post was inspired by the following blog post: Never run Google ads if you have an Android app, especially by its subtitle: Google can and will permanently ban your Android app if Google thinks you’ve clicked on your own ads. This does not need to happen and, as it has been shown, accident of clicking (or even watching) your own ads can be easily prevented.

Thursday, April 15, 2021

CORS header 'Access-Control-Allow-Origin' missing and Java Servlet

 As it is answered here, HttpServlet.doOptions() method has to be overridden the following way:


import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

    name = "MyServlet",
    urlPatterns = {"/myservlet"}
public class MyServlet extends HttpServlet {
    protected void doOptions
HttpServletRequest req,
            HttpServletResponse resp
        )         throws IOException {         resp.setHeader("Access-Control-Allow-Origin", "*");      resp.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");      resp.setHeader("Access-Control-Allow-Headers", "*");     }     @Override     protected void doPost
            HttpServletRequest req,
            HttpServletResponse resp
        )         throws IOException {         resp.setHeader("Access-Control-Allow-Origin", "*");         resp.setContentType("text/plain");         resp.setCharacterEncoding("UTF-8");         resp.getOutputStream().println("OK");     }     @Override     protected void doGet
            HttpServletRequest req,
            HttpServletResponse resp
        )         throws IOException {         doPost(req, resp);     } }

Sunday, April 11, 2021

Covid19 Travel Information - updated daily

Another web project finished. This time daily updated corona virus related travel information at:

Covid19 Travel Information

HTML, javascript without any frameworks, only Papa Parse for CSV parsing and python for data processing. Data is fetched from The Humanitarian Data Exchange. There is no database at all and site is hosted on GitHub Pages!