Mobile Network Glossary

This is an online help for the Network Signal Monitor app.

Signal strength: This is the power of the received signal. The weakest the worst. The acceptable value depends on the given network type. For example -90 dBm is good for an LTE network but low for a GSM network.

MCC: Mobile country code. The mobile country code consists of 3 decimal digits defined by E.212. More details are here.

MNC: Mobile network code. The mobile network code consists of 2 or 3 decimal digits defined by E.212. More details are here.

ASU: Arbitrary Strength Unit (ASU) is an integer value proportional to the received signal strength measured by the mobile phone. More details are here.

IP address: An Internet Protocol address (IP address) is a numerical label assigned to each device (e.g., computer, mobile phones) participating in a computer network that uses the Internet Protocol for communication. Example: 192.168.0.1

latency: This is the latency time of the server in ms.

Advertisements

Android: how to solve adview CPU consuming

adview can consume CPU when the application is in the background… This is a very common problem. Even if the application in the background or has been stopped, it can consume the CPU continuously.

Other symptom, if you disable ads, the CPU usage is minimal or zero.

This is caused by several reasons including possible adview bug too. Here, you can see how to solve the high CPU usage problem:

The first one is to destroy the adview in onDestroy() and onPause() (don’t forget to recreate it in onResume() and onCreate()):

private void destroyAdView() {
    if (adview != null) {
        adview.destroy();               
    }   
}

@Override
public void onDestroy() {
    destroyAdView();
    super.onDestroy();
}

@Override
public void onPause() {
    destroyAdView();
    super.onDestroy();
}

In newer admob sdk you can call adview.onPause() and adview.onResume() functions, but my experience that sometimes they don’t do what they promise.

If adview still consumes CPU, there is a second solution: removing the full adview from the layout, not only destroying it:

private void destroyAdView() {
    if (adview != null) {
        // In my case the adview has been added to a relativelayout
        RelativeLayout layout = (RelativeLayout) mainView.findViewById(R.id.adRelativeLayout);
        layout.removeView(adview);
        adview.destroy();               
    }   
    }

The two solutions above should solve the high CPU usage problem. Excepting only one case:
If you are using the new Google Play services library for adview. Google will only support this admob library after august, 2014.
It seems there is a bug in the library:
https://groups.google.com/forum/#!topic/google-admob-ads-sdk/1aidjtsin8A
https://groups.google.com/forum/#!topic/google-admob-ads-sdk/Qu4G19NFAuI

So if you experience high CPU usage after switching to the new library, you can use a workaround (pausing webview can have other effects too, so use it for your own risk):

@Override
    public void onDestroy() {
        destroyAdView();
        super.onDestroy();
    }
private void destroyAdView() {
    if (adview != null) {
        // In my case the adview has been added to a relativelayout
        RelativeLayout layout = (RelativeLayout) mainView.findViewById(R.id.adRelativeLayout);
        layout.removeView(adview);
        pauseWebView(adview);
        adview.destroy();               
    }   
    }

private void pauseWebView(ViewGroup v) {
    for (int i = 0; i < v.getChildCount(); i++) {
        View child = v.getChildAt(i);
        if (child instanceof WebView) {
            ((WebView) child).pauseTimers();
        }   
        pauseWebView((ViewGroup) child);
    }   
}

And finally, here is how I am creating the adview and a full example:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
createAdView();
...
}
private void createAdView() {
    if (adview == null) {
        RelativeLayout layout = (RelativeLayout) mainView.findViewById(R.id.adRelativeLayout);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);

        layout.setLayoutParams(lp);
        RelativeLayout.LayoutParams adsParams = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        adsParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        adsParams.addRule(RelativeLayout.CENTER_IN_PARENT);

        adview = new AdView(fragmentActivity);
        adview.setAdSize(AdSize.BANNER);
        adview.setAdUnitId("ca-xxxx");
        final AdListener listener = new AdListener() {
            @Override
            public void onAdLoaded() {
                //Here we will display the adview if there is ad
                adview.setVisibility(View.VISIBLE);
                super.onAdLoaded();
            }
        };

        adview.setAdListener(listener);

        //This needs to remove empty space when ad is not loaded, for example no internet conn.
        adview.setVisibility(View.GONE);

        layout.addView(adview, adsParams);

        AdRequest adRequest = new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
        .build();
        adview.loadAd(adRequest);
    }   
}

void resumeWebView(ViewGroup v) {
        for (int i = 0; i < v.getChildCount(); i++) {
            View child = v.getChildAt(i);
            if (child instanceof WebView) {
                ((WebView) child).resumeTimers();
            }
            try {                
                resumeWebView((ViewGroup) child);
            } catch (Exception e) {
                e.printStackTrace();
            }            
        }
    }

void pauseWebView(ViewGroup v) {     
        for (int i = 0; i < v.getChildCount(); i++) {
            View child = v.getChildAt(i);
            if (child instanceof WebView) {
                ((WebView) child).pauseTimers();
            }
            try {                
                pauseWebView((ViewGroup) child);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

private void destroyAdView() {
        if (adview != null) {
            RelativeLayout layout = (RelativeLayout) mainView.findViewById(R.id.relativeLayout);
            layout.removeView(adview);            
            adview.destroy();            
            adview = null;
        }

    }

 @Override
    public void onPause() {
        if (adview != null) {
            adview.pause();
            pauseWebView(adview);
        }
        super.onPause();
    }

    @Override
    public void onResume() {        
        if (adview != null) {
            adview.resume();
            resumeWebView(adview);
        }
        super.onResume();
    }

@Override
    public void onDestroy() {     
        destroyAdView();
        super.onDestroy();
    }

Android: UDP broadcast message is not received

Recently, I ran into an interesting trouble: I created an application that can send UDP broadcast messages and an Android application that can receive them.
As easy as pie I thought, then I realized that the broadcast message is received on a few devices but not received on other devices…
First of all, the message was sent to the correct broadcast address, and the android code was also fine:

...
try {
DatagramSocket brsocket = new DatagramSocket(port, InetAddress.getByName("0.0.0.0"));
brsocket.setBroadcast(true);
brsocket.setSoTimeout(10000);

byte[] recvBuf = new byte[255];
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
try {
brsocket.receive(packet);
} catch (IOException ex) {
brsocket.close();
Log.d("D", String.format("No broadcast message: %s", ex.getMessage()));
return;
}
Log.d("D", String.format("Message received from: %s", packet.getAddress().getHostAddress()));
...

Using my Asus tablet or Sony mobile phone it worked properly, the broadcast message was received. Using my HTC Desire, there was no broadcast message at all.

And what is the solution? You should create a MulticastLock before reading from the socket. I don’t know why it needs for a few type of devices and why not for others, but this solves the problem.

So here is what you should do:

WifiManager wifi;
wifi = (WifiManager) parentContext.getSystemService(Context.WIFI_SERVICE);
MulticastLock mLock = wifi.createMulticastLock("lock");
mLock.acquire();
//the receive code listed above
...
// at the end of this code
mLock.release();

And of course, don’t forget to add the proper permission to the manifest:

<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />

Android programming: button below scrollview or listview

How can you add buttons below a scrollview but located at the bottom of screen? Well, this is a quite common question.
If you simple add a button at the bottom of your layout file where there is a Scrollview or Listview above, you can experience bad results:

  • If the scrollview/listview is not full of items, the button position will be somewhere in the middle of the screen instead of bottom.
  • If the view is full of items, the button will disappear.
wrong_button_below_scrollview

Common problem: the buttons are not at the bottom of the screen

So, how can you solve it? The trick is to use RelativeLayout instead of LinearLayout and the android:layout_alignParentBottom=”true” keyword.

Let’s see an example code for scrollview:

<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android&#8221;
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:orientation=”vertical” >

<ScrollView
android:layout_width=”fill_parent”
android:layout_height=”wrap_content” >

<LinearLayout
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:orientation=”vertical” >

<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_gravity=”center”
android:gravity=”center”
android:text=”some text” />

<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_gravity=”center”
android:gravity=”center”
android:text=”some text2″ />
</LinearLayout>
</ScrollView>

<LinearLayout
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:layout_alignParentBottom=”true”
android:layout_centerHorizontal=”true”
android:orientation=”horizontal” >

<Button
style=”?android:attr/buttonStyleSmall”
android:layout_width=”wrap_content”
android:layout_height=”40dp”
android:layout_gravity=”bottom”
android:layout_marginRight=”3dp”
android:layout_marginTop=”1dp”
android:layout_weight=”1″
android:text=”button1″ />

<Button

style=”?android:attr/buttonStyleSmall”
android:layout_width=”wrap_content”
android:layout_height=”40dp”
android:layout_gravity=”bottom”
android:layout_marginRight=”3dp”
android:layout_marginTop=”1dp”
android:layout_weight=”1″
android:text=”button2″ />
</LinearLayout>

</RelativeLayout>

And the result:

button_below_scrollview

Using RelativeLayout the buttons can be below the scrollview at the bottom of the screen