USB broadcast receiver (ACTION_POWER) not working

I am trying to implement a basic receiver for USB connection. Found a reference here.

I searched a lot, but can’t make it to work…

package com.example.usbtethering;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "USB connected.", Toast.LENGTH_SHORT).show();
        Log.v("AAAAAAAA", "AAAAAAAAAAAAAAAAAAAAAAAA");
    }
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.usbtethering">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.USBTethering">
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main"
            android:theme="@style/Theme.USBTethering.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".MyReceiver">
            <intent-filter>
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

On emulator, I am changing the following setting:

enter image description here

I see the status is changing on the phone bar, but my code is not executed.

Any idea what I am missing?

TL;DR (XY)

My goal is to enable USB tethering automatically when connected to USB, only if hour is between 8:00-22:00. The idea is to block internet usage outside of the specified hours.

On the phone – settings, app-store, browsers, Youtube and hotspot are password locked. So the internet can only be used for Whatsapp, waze, and USB tethering. However this currently requires the “administrator” to manually enable/disable USB tethering in settings each time.

So I intend to create this app which I think should be simple, give it permission to change settings:

  1. Enable tethering on each USB connection between 8:00 and 22:00.
  2. Disable tethering (if enabled) on 22:00.

I have moderate C++/python programming experience, and some Java, but this is my first attempt to Android.

Answer

As part of the Android 8.0 (API level 26) Background Execution Limits, apps that target the API level 26 or higher can no longer register broadcast receivers for implicit broadcasts in their manifest. However, several broadcasts are currently exempted from these limitations. Apps can continue to register listeners for the following broadcasts, no matter what API level the apps target.

So from the API > 28 Version you must register the reciver for that you can use this piece of code in your Activity or if you want to listen to the Power Connection changes in the background use a Service

IntentFilter ACTION_POWER_CONNECTED = new IntentFilter("android.intent.action.ACTION_POWER_CONNECTED");
IntentFilter ACTION_POWER_DISCONNECTED = new IntentFilter("android.intent.action.ACTION_POWER_DISCONNECTED");
registerReceiver(new MyReceiver(), ACTION_POWER_CONNECTED);
registerReceiver(new MyReceiver(), ACTION_POWER_DISCONNECTED);

I believe you want to use a Service this is an example :

First you need to Create a Service (PowerSerivce) in the manifest file :

<service
        android:name=".PowerService"
        android:stopWithTask="false" />
        <!-- If set to true,
        this service with be automatically stopped when the user remove a task rooted in an activity owned by the application-->

And this is the PowerService.java :

import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;

public class PowerService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        IntentFilter ACTION_POWER_CONNECTED = new IntentFilter("android.intent.action.ACTION_POWER_CONNECTED");
        IntentFilter ACTION_POWER_DISCONNECTED = new IntentFilter("android.intent.action.ACTION_POWER_DISCONNECTED");
        registerReceiver(new MyReceiver(), ACTION_POWER_CONNECTED);
        registerReceiver(new MyReceiver(), ACTION_POWER_DISCONNECTED);
        Log.d("Service", "onStartCommand: " );
        return Service.START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("Service", "onDestroy: " );
    }
}

And this is MyReciver :

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.intent.action.ACTION_POWER_CONNECTED")){
            Toast.makeText(context, "CONNECTED", Toast.LENGTH_LONG).show();
        }else if(intent.getAction().equals("android.intent.action.ACTION_POWER_DISCONNECTED")){
            Toast.makeText(context, "DISCONNECTED", Toast.LENGTH_LONG).show();
        }
    }
}

And finaly you need to start this Service in my case i started it only for API>=26 normally in APIs below 26 you don’t need this Service (you can check it by yourself). in this code I started the PowerService only for version above API 26

 // add this code in your first activity or where you want 
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
     startService(new Intent(this, PowerService.class)):
    }

References :