any browser but chrome on android

I know the title could be considered clickbait. I don’t care. I came to this conclusion after my Samsung Galaxy Tab S6 Lite updated to Android 13 and I spent a few hours surfing with this tablet, waiting at my Acura dealership while they performed regular maintenance on my MDX.

As you can see in the screenshot above, the Tab S6 Lite is now running Android 13 and Samsung’s One UI 5. Normally I don’t care for Samsung’s UI, but when it comes to the Settings panel, I’m shocked to say that Samsung’s is better organized, and as a consequence, easier to go find settings for the tablet. Who would have known???

The problem is with Google’s Chrome browser. Specifically that it will NOT block ads of any type. And I looked into Chrome’s setup; no ad blocking. Here’s an example of the crap I kept getting wherever I browsed with Chrome.

Slashdot in Chrome on Android 13

I don’t normally go slumming onto Slashdot, for many reasons, not the least is how the site is plastered with ads. It was Slashdot that motivated me to install an ad blocker on my PC Chrome years and years ago. This was a throwback to an earlier day I didn’t appreciate. Now let’s visit Slashdot with Vivaldi.

Slashdot in Vivaldi on Android 13

You’ll note the Vivaldi view has blocked quite a few ads on the Slashdot site, especially in the right side gutter. Ad blocking in Vivaldi makes the Slashdot site barely tolerable, as long as I stay out of the comments.

Let’s look at ArsTechnica in Chrome.

Using Chrome with a huge header ad that takes up 1/3 of the page.

ArsTechnica stories have a large ad at the top of each page, at least one in the middle, and one at the footer. The header ad has two strikes against it, the first being so damn large and the second that it’s Bono, and I do not like Bono at all. And there’s a bit of irony that there’s ads all over a story about the sin of Microsoft Store ads.

There is one key feature in Vivaldi missing in Chrome, it’s Settings | Tracker and Ad Blocker, Block Trackers and Ads. With that radio button selected all this crap is pretty much blocked and my webpages are very clean. Before I close this post, here are two more examples of before with Chrome, and after with Vivaldi.

With Chrome
With Vivaldi

I guess if I were still a teenager instead of a sexagenarian I’d find the ad full of buxom blondes and brunettes enticing. But at my age it’s called being a dirty old man, or worse. Besides, they look younger than my adult children, so that’s how I see them, as a bunch of kids. And that ad is the least annoying on that page. Other ads try to tell me about toe fungus, or the best way to clean out my bowels every day, and how wonderful Bitcoin is… You see my point. I do find useful text on many sites, but todays ads plastered everywhere are absolute shit, and they’re only getting worse. To help me control what I don’t want to see I run Vivaldi on Android. Before the question is raised, Chrome’s plugin store won’t support Android Chrome; it’s unsupported, so I can’t install an ad-blocker plugin.

Get Vivaldi, or perhaps Brave, or any other browser that inherently blocks ads. Don’t run with Chrome.

circuitpython 8.0 rc 1

A new version of CircuitPython is near final release. Version 8 RC 1 was released today (yesterday, actually, but it wasn’t officially documented until today). I’m interested because now there’s an official CircuitPython released specifically for the Raspberry Pi Pico W ( https://circuitpython.org/board/raspberry_pi_pico_w/ ). I’m starting with one of my Pico W boards, and then moving around to all the devices that currently run 7.3.3. So far nothing has leaped out as a problem, but these are very early days. I know that WiFi works, but I don’t know if Bluetooth is working or not.

One application I’ve been tweaking along the way is an automatic quote displayer that queries the Adafruit quote server and prints it out. The response comes back in JSON. The original code, written for CP 7, only printed the response out in a raw format. This version parses the JSON and line wraps long quotes to less than 80 columns. Here’s a typical output.

...
   Injustice anywhere is a threat to justice everywhere.
 - Martin Luther King, Jr.

   I never am really satisfied that I understand anything; because, understand 
   it well as I may, my comprehension can only be an infinitesimal fraction 
   of all I want to understand.
 - Ada Lovelace

   Adversity is revealing of character.
 - Unknown

   The most exciting phrase to hear in science, the one that heralds new discoveries, 
   is not 'Eureka!' but 'That's funny...'.
 - Isaac Asimov

   The whole point of getting things done is knowing what to leave undone.
 - Oswald Chambers
...

And here’s the code.

# Copyright (c) 2023 William H. Beebe, Jr.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Derived/modified from"
# 2022 Liz Clark for Adafruit Industries

import os
import time
import ssl
import wifi
import socketpool
import microcontroller
import adafruit_requests
import json
import gc

# Adafruit quotes URL
#
quotes_url = "https://www.adafruit.com/api/quotes.php"

# Connect to a local access point.
# WIFI_SSID and WIFI_PASSWORD should be defined in your settings.toml file.
#
wifi.radio.connect(os.getenv('WIFI_SSID'), os.getenv('WIFI_PASSWORD'))

pool = socketpool.SocketPool(wifi.radio)
session = adafruit_requests.Session(pool, ssl.create_default_context())
print("\n\nFetching quotes from {}\n".format(quotes_url))
wrap_limit = 72

while True:
    try:
        time.sleep(5)
        gc.collect()

        # Get a quote. Parse the JSON response.
        #
        response = session.get(quotes_url)
        dic = dict(json.loads(response.text)[0])
        qstr = dic['text'] + "."

        # Primitive line wrapping for long text lines.
        #
        while len(qstr) > wrap_limit:
            cut = qstr.find(" ", wrap_limit, len(qstr)) + 1
            if cut > 0:
                print("   {}".format(qstr[:cut]))
                qstr = qstr[cut:]
            else:
                break

        if len(qstr) > 0:
            print("   {}".format(qstr))
        print(" - {}\n".format(dic['author']))

        response.close()
        gc.collect()
    # pylint: disable=broad-except
    except ValueError as e:
        print("Error: bad JSON")
        response.close()
    except Exception as e:
        print("Error:\n", str(e))
        print("Resetting microcontroller in 10 seconds")
        time.sleep(10)
        microcontroller.reset()

As they say, more to come.