Monday, August 31, 2020

How to set and verify Admob app-ads.txt using Blogger

Hi all!

If you are using Admob to monetize your mobile apps you might have noticed a warning or a request about app-ads.txt. For example:

There's a problem with your app-ads.txt implementation for one or more apps - your ad earnings are at risk.

Usually it means that you don't have app-ads.txt file specified and available online within your official website. In short app-ads.txt will let advertisers know which ad sources are authorized to sell ad inventory. 

Normally it should be placed under the root of your website. Please note this must match the website you specified in the Google Play publisher account within the app store listing. For example in our case it would be: https://devmainapps.blogspot.com/app-ads.txt

The content of the custom ads file you can get and copy from your Admob account.

If you have a full control of your web hosting account, you can simply add such file in a way it's available under your website address /app-ads.txt. However if you are using third party such as for example Blogger you will usually not have enough control to just upload any file and make it available in the correct place.

So how to set it up if you are using Blogger / blogspot ?

Follow the steps below:

1. Login to your Blogger account and under your blog navigate to Settings sections.

2. Find section called Monetization, under which you should find option to Enable custom ads.txt

3. Enable it and in the text input paste the content copied from your Admob. Something like this:
google.com, pub-<id>, DIRECT, <id>

4. If you save it, the file called ads.txt should be available under the root of your blog url: https://<your-blogname>.blogspot.com/ads.txt
However Admob expect it to be /app-ads.txt. To fix this you can set custom redicrects for your blog.
 
5. Also under the Settings find Custom redirects section. There you should specify redirection from /app-ads.txt to /ads.txt. 
That should do the trick. 

6. Test if everything works as expected:
Go to: https://<your-blogname>.blogspot.com/app-ads.txt
And it should redirect to https://<your-blogname>.blogspot.com/ads.txt


Sunday, June 28, 2020

Troubleshoot Android device USB connection and ADB

Hi,

In this article we can explore some workarounds and fixes related to issues with connecting a real Android device to computer via USB not only to be able to copy files over but also for Android ADB tool to be able to see it and connect to it.

Disclaimer: I cannot guarantee if it will work for you and in some cases it may break things further for your system or device - so you are following the instructions below at your own risk.


First thing to check is if Android developer options are available on your device: How to turn on Android developer options

Solution A: Configure Android developer options

1. Navigate to the developer options on you device and make sure the following options are set:
  • USB debugging is enabled
  • USB transfer mode is set to Media File Transfer or something similar
  • It's also useful to enable "Stay awake" option as it will make your life a little bit easier.

2. Make sure USB cable is connected to your device and run ADB command to check if it can see your device. ADB tool is located under Android/Sdk/platform-tools directory:
./adb devices

You should see your name for your device but if you see nothing or question marks "???????" instead of the text as a name then continue to read for further troubleshooting options.


Solution B: Add custom udev / adb rules for USB device connected

1. While your device is connected run lsusb command to find details of the USB connection:
lsusb

In the output you should find something like this corresponding to your device:
Bus 001 Device 006: ID 11a8:2d77 Motorola PCS
Where:
- 11a8 is vendor id
- 2d77 is product id

2. Under /lib/udev/rules.d/ create a new file containg custom "adb" rules for your device:
sudo gedit /etc/udev/rules.d/10-adb.rules

3. Put the following content in that file making sure all is in one single line:
SUBSYSTEM=="usb", ATTR{idVendor}=="11a8", ATTR{idProduct}=="2d77", MODE="0600",
OWNER="your_username"

4. After saving the file, reload the rules:
sudo udevadm control --reload-rules

5. Then, restart the ADB server - stop/kill  the adb server and start again:
sudo adb kill-server

sudo adb start-server

6. Final step is to reconect your device via USB and run adb devices command to see if your device is now visible:
./adb devices

If you can see your device it's great otherwise there is one more thing you can try - continue reading...


Solution C: install additional packages & manually download libmtp

If above didn't work so far then this might do the trick.

1. Install additional packages:
sudo apt-get install libusb-dev
sudo apt-get install gmtp
sudo apt-get install libmtp-common libmtp9 libmtp-runtime

2. Manually download the latest libmtp from: https://sourceforge.net/projects/libmtp/files/libmtp/

3. Extract it and build it from within it's root dir:
./configure --prefix=/usr
make
sudo make install

4. Copy file called 69-libmtp.rules (located in libmtp folder you are in) to udev rules:
sudo cp 69-libmtp.rules /etc/udev/rules.d/

5. Run lsusb as in point 1 from Solution B to find out product and vendor IDs for your device.

6. Edit the copied rules file and add something similar to below with the correct product and vendor IDs from lsusb output:
ATTR{idVendor}=="0fce", ATTR{idProduct}=="4169", SYMLINK+="libmtp-%k", ENV{ID_MTP_DEVICE}="1", ENV{ID_MEDIA_PLAYER}="1"
ATTR{idVendor}=="0fce", ATTR{idProduct}=="0169", SYMLINK+="libmtp-%k", ENV{ID_MTP_DEVICE}="1", ENV{ID_MEDIA_PLAYER}="1"

7. After saving the file, reload the rules:
sudo udevadm control --reload-rules

8. Then, restart the ADB server:
sudo adb kill-server

sudo adb start-server

9. Finally unplug and plug USB cable from your device to reconnect and check ADB devices:
./adb devices

If all went well you should see your device!

Thursday, June 25, 2020

How to manually install APK file on Android emulator

Hi,

This will probably be one of the shortest (if not the shortest) How To guide. It's about manually installing APK on Android emulator. Additionally it might also work on installing it on the real device connected to your PC via USB.

Let's assume your Android emulator is up and running and you already have the APK file ready. So all you need to do is to simply invoke single adb command to install the given APK:
./adb install <path-to-the-apk-file>

For example:
./adb install myapp.apk


FYI: adb command line tool is located under Android/Sdk/platform-tools


Sunday, June 21, 2020

Android MasterKeys deprecated - How to create EncryptedSharedPreferences

Hi,

Today I was playing with security-crypto Android security library regarding using it to store encrypted shared preferences within the app. Previously I was using the following version:
implementation "androidx.security:security-crypto:1.0.0-rc02"
After some Android Lint analysis I upgraded to the latest one at the time of writing this:
implementation "androidx.security:security-crypto:1.1.0-alpha01"

Then after running a build I got some deprecation warnings which was kind of expected:

MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC) // deprecated
EncryptedSharedPreferences.create(...) // deprecated

In fact the whole MasterKeys class is now deprecated. Unfortunately at the time of writing this the official Android developer docs haven't been updated yet to reflect the changes: https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences

Anyway after looking into the underlying implementation of getOrCreate and also MasterKeys.AES256_GCM_SPEC turns out it can be easily fix by new ways of doing it. Continue reading to find out :)

Fix for MasterKeys deprecated

First part is to overcome MasterKeys deprecation. So instead of getting / creating something called master key alias we can get/create the master key itself. The following example is in Java code but of course it can be done in a similar way using Kotlin:
MasterKey getMasterKey() {
try {
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
MASTER_KEY_ALIAS,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setKeySize(KEY_SIZE)
.build();

return new MasterKey.Builder(MainActivity.this)
.setKeyGenParameterSpec(spec)
.build();
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "Error on getting master key", e);
}
return null;
}

Fix for EncryptedSharedPreferences.create deprecated

Now the second bit is to use different version of create method in the EncryptedSharedPreferences. Again the following code example is in Java:
private SharedPreferences getEncryptedSharedPreferences() {
try {
return EncryptedSharedPreferences.create(
MainActivity.this,
"your-app-preferences-name",
getMasterKey(), // calling the method above for creating MasterKey
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "Error on getting encrypted shared preferences", e);
}
return null;
}

With that you can use those SharedPreferences as usual to save and get data.

Saturday, June 20, 2020

How to turn on Android developer options

Hi,

Android developer options is a hidden menu section in the settings of your mobile phone or tablet. It has several useful settings under the hood such as for example:
  • stay awake on/off
  • take bug report
  • view memory usage per app
  • view and stop individual running services
  • switch on USB debugging (aka Debug mode when USB is connected)
  • set background process limit
  • option to destroy every activity once the user leaves it
There are many more useful options within it. It's basically a 'must have' if you are a developer as it helps while implementing a mobile app.

Making developer options available is very simple and pretty much the same (or at least very similar) on each Android device I've seen. Follow the instructions below.

1. First, go to the Settings

2. Then find section called "About" or "About phone" or similar. It's usually at the very bottom of the Settings screen. However sometimes it's further down under the "System" section in which case you would go to Settings, then to "System" section and then "About phone" (most likely at the very bottom again)

3. In the "About" screen you can see various things about your device such as device model, Android version and Build number. To turn on the developer options tap on "Build number" 7 times :)

After that, new section called "Developer options" should appear either directly under the Settings screen or in the "System" screen.



Tuesday, June 16, 2020

How to start Android emulator from the command line

Hi,

Usually I start Android emulator from within the Android Studio while developing Android app. However sometimes you might want to start it without needing to run entire Android Studio. Therefore in this How To article I will show how can you start Android emulator from the command line.

Let's assume you already have some AVD / devices available.

1. First you need to find out the name of AVD you want to run. For that you can use AVD manager command line tool located under Android/Sdk/tools/bin:
./avdmanager list avd

2. Next, you can use emulator command line to start the given AVD device. Emulator tool should be located in one folder above, i.e. Android/Sdk/tools:
./emulator -avd Nexus_S_API_23
In the above example Nexus_S_API_23 is the AVD device name


Troubleshooting

Please make sure you are running correct version of Java, check here for potential error: https://devmainapps.blogspot.com/2020/06/avdmanager-command-line-tool-fix.html



Saturday, June 13, 2020

avdmanager command line tool fix NoClassDefFoundError

Hello!

Command line tool avdmanager is located under tools directory in your Android SDK. On some environments and configurations trying to run avdmanager may fail with the following error message:
Exception in thread "main" java.lang.NoClassDefFoundError
javax/xml/bind/annotation/XmlSchema
at SchemaModuleVersion (SchemaModule.java:156)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema

Solution

In my case it was because of Java version, i.e. running java -version turns out I'm on 11 openjdk. The solution was to have use JDK 8:

1. Uninstall all Java / JDK versions:
sudo apt-get autoremove openjdk*

2. Install JDK 8:
sudo apt-get install openjdk-8-jdk

After that, AVD manager from command line works fine!