2

I've followed Shai's tutorial for native interfaces but I'm stuck at implying the android native code in codenameone. I need to get the battery level (percentage) as soon as the device turns off. I've done it in native android and I've built app in cn1 which need that feature too. Below I've provided the code. Please help me apply it in cn1. Thankyou

Native android code:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //for mobile shutdown starts
    IntentFilter filter = new IntentFilter(Intent.ACTION_SHUTDOWN);
    BroadcastReceiver mReceiver = new ShutDownReceiver();
    registerReceiver(mReceiver, filter);
    //for mobile shutdown ends
}

//for mobile shutdown
public class ShutDownReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent)
    {
        if (intent.getAction().equals(Intent.ACTION_SHUTDOWN))
        {
            Log.e("shutdown","mobile shutdown");
            Log.e("shutdown battery percentage",getBatteryPCT() + "");
        }
    }
}

public float getBatteryPCT()
{
    IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    Intent batteryStatus = this.registerReceiver(null, ifilter);
    int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
    //Check if charging.
    boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL;
    //Check if charger plugged in.
    int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
    //check if charging via USB.
    boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
    //check if charging via AC.
    boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
    int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
    int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
    float batteryPct = level / (float)scale;
    //Get the current battery percentage.
    return batteryPct*100;
}

Below is what I've tried in cn1 but build fails

public class MyNativeImpl {

    public boolean isSupported() {
        return true;
    }

    public void getShutDownBattery() {
        IntentFilter filter = new IntentFilter(Intent.ACTION_SHUTDOWN);
        BroadcastReceiver mReceiver = new ShutDownReceiver();
        registerReceiver(mReceiver, filter);

        getBatteryPCT();
        Log.e("battery status", getBatteryPCT() + "");
    }

    public class ShutDownReceiver extends BroadcastReceiver {

        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Intent.ACTION_SHUTDOWN)) {
                Log.e("shutdown", "mobile shutdown");

                Log.e("shutdown battery percentage", getBatteryPCT() + "");
            }
        }
    }

    public float getBatteryPCT() {
        IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        Intent batteryStatus = this.registerReceiver(null, ifilter);
        int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
        boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL;
        int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
        boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
        boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
        int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
        int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
        float batteryPct = level / (float) scale;
        return batteryPct * 100;
    }
}

MyNative interface

public interface MyNative extends NativeInterface{
    public void getShutDownBattery();
}

Update 1:

Hello Shai, I've a couple of questions regarding your answer below:

1)Move the ShutdownReceiver class to a top level class and not an inner class

Why doesn't inner class work here?

2)need to get the activity from AndroidNativeUtil for registerReceiver

I didn't find anything abt AndroidNativeUtil frm the link you've given. Is the following line correct?

import com.codename1.impl.android.AndroidNativeUtil.registerReceiver(mReceiver, filter);

3)permissions

what permissions do I need here? It didn't need any permission in native android code.

Updated code:

public class MyNativeImpl{

    public boolean isSupported() {
        return true;
    }

    public void getShutDownBattery() {
        IntentFilter filter = new IntentFilter(Intent.ACTION_SHUTDOWN);
        BroadcastReceiver mReceiver = new ShutDownReceiver();
        AndroidNativeUtil.registerReceiver(mReceiver, filter);
    }
}

class ShutDownReceiver extends BroadcastReceiver {

    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SHUTDOWN)) {
            Log.e("shutdown", "mobile shutdown");

            Log.e("shutdown battery percentage", getBatteryPCT() + "");
        }
    }

    public float getBatteryPCT() {
        IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        Intent batteryStatus = this.registerReceiver(null, ifilter);
        int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
        //Check if charging.
        boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL;
        //Check if charger plugged in.
        int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
        //check if charging via USB.
        boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
        //check if charging via AC.
        boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
        int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
        int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
        float batteryPct = level / (float) scale;
        //Get the current battery percentage.
        return batteryPct * 100;
    }
}
beck
  • 2,967
  • 3
  • 16
  • 27

1 Answers1

0

Move the ShutdownReceiver class to a top level class and not an inner class. registerReceiver is a method of activity so you will need to get the activity from AndroidNativeUtil as I explained in the video.

There are two things missing in the native code which you need to do and those are permissions. You need to add permissions to the manifest and you can do that via the build hint android.xpermissions hint.

You also need to request Android 6+ permissions in code and you can do that via the AndroidNativeUtil call checkForPermission as explained here.

Shai Almog
  • 51,749
  • 5
  • 35
  • 65
  • Hello Shai, I've a couple of question shai. Please have a look at update above in the question. – beck Aug 05 '17 at 04:25
  • I suggest filing a new question as this is hard to follow. 1. It's possible Android will try dynamically loading a class so it's always a better practice. 2. https://www.codenameone.com/manual/advanced-topics.html `AndroidNativeUtil.getActivity().registerReceiver(mReceiver, filter);` 3. https://stackoverflow.com/questions/14133077/android-action-shutdown-broadcast-not-working mentions `DEVICE_POWER` – Shai Almog Aug 05 '17 at 05:44
  • I'm getting the build error. I tried it in native android and it works.I have replicate the question https://stackoverflow.com/questions/45520411/native-interface-in-codenameone-for-getting-battery-information-duplicate – beck Aug 05 '17 at 09:38