How to use MI-APP API?

Note

The MI-APP API is still under development. This page will be

kept updated with the evolution of MI-APP API.

MobileInsight provides two approaches for mobile apps to leverage runtime cellular information: plugin (MI-DEV) and in-app API (MI-APP). This article explains MI-APP API, which allows mobile apps to access MobileInsight’s cellular information inside their native codes. For plugin (MI-DEV), please refer to this toturial.

MI-APP: A Big Picture

Simply speaking, MI-APP provides an interface between MobileInsight and legacy mobile apps. It leverages the standard Android’s intent-broadcast mechanism to distribute runtime cellular information from MobileInsight to mobile apps.

The following figure shows the overview of MI-APP. Whenever MobileInsight receives latest cellular information, it can choose to broadcast this information to apps. For mobile apps that are interested in this information, they can implement a BroadcastReceiver to listen to these info, and develop callbacks to handle them. With such broadcast capability, MobileInsight can serve multiple applications simultaneously that are interested in same information.

+-------------+         +----+
|MobileInsight| ------> |App1|
+-------------+    |    +----+
                   |
                   |    +----+
                    --> |App2|
                   |    +----+
                    --> ...

How to use MI-APP?

If a mobile app wants to leverage MobileInsight’ runtime cellular information, it needs to implement a broadcast receiver in its code. Here we demonstrate an example. For how to use BroadcastReceiver, please refer to this tutorial.

Step 1: Register a broadcast receiver for cellular information. This is to modify AndroidManifest.xml in the Android project, as shown below:

<application
   android:icon="@drawable/ic_launcher"
   android:label="@string/app_name"
   android:theme="@style/AppTheme" >
   <receiver android:name="MyReceiver">

      <intent-filter>
         <action android:name="MobileInsight.LtePhyAnalyzer.LTE_BW">
         </action>
      </intent-filter>

   </receiver>
</application>

In declaring the broadcast receiver, the key is to specify the name of cellular information to be received. In MobileInsight, the broadcasted cellular information are named in the following form:

MobileInsight.ANALYZER_NAME.METHOD

where ANALYZER_NAME is the MobileInsight analyzer that generates this cellular information, and METHOD is the analyzer-specific label of the cellular information. In above example, the broadcast receiver would receive LTE_BW information generated by LtePhyAnalyzer.

Step 2: Implement the broadcast receiver. The application now can implement the corresponding broadcast receiver (in this example, MyReceiver). To process the cellular information, the broadcast receiver should overload OnReceive() method, as shown below

public class MyReceiver extends BroadcastReceiver {
   @Override
   public void onReceive(Context context, Intent intent) {
      String Lte_bw = = intent.getStringExtra("Bandwidth (Mbps)"); //LTE bandwidth
     // Do whatever you like
   }
}

This method would be called whenever MobileInsight broadcasts a new cellular information. The cellular information is encapsulated inside an Android Intent object as a dictionary of attribute (String)->value (String). These information can be extracted via Intent.GetExtra() method.

How is MI-APP implemented?

MobileInsight implements MI-APP API in a generic approach. In its Analyzer abstraction, it provides a method broadcast_info for all analyzers to broadcast cellular information they would like to distribute. It accepts two parameters: (1) analyzer-specific method label; (2) a string->string dictionary of the information to be broadcasted.

Let’s take LtePhyAnalyzer above as an example. To support MobileInsight.LtePhyAnalyzer.LTE_BW broadcast, it implements the broadcasted LTE_BW information in its message callback, as shown below:

class LtePhyAnalyzer(Analyzer):
    def __msg_callback(self,msg):
        # ...
        bcast_dict = {}
        bcast_dict['Bandwidth (Mbps)'] = str(log_item["TBS 0"]+log_item["TBS 1"]) # Real implementation uses averaged value
        self.broadcast_info('LTE_BW',bcast_dict)

The broadcast_info method is implemented in element.py as follows:

def broadcast_info(self, method, msg_dict):
        """
        (Mobile-version only) Broadcast monitor/analyzer information to other Android apps.
        This method is the interface between MobileInsight and Android apps requiring cellular info.
        It leverages Android's intent-based broadcast mechanism.

        The intent is per-analyzer/monitor based, and the action is named as follows:
        `MobileInsight.ANALYZER/MONITOR-NAME.method`

        where ANALYZER/MONITOR-NAME is the class name of the monitor/analyzer,
        and method is analyzer/monitor-specific method to notify the Android apps

        :param method: analyzer/monitor-specific methods for broadcast action
        :type method: string
        :param msg_dict: A dictionary that lists the information to be broadcasted.
        :type msg_dict: string->string dictionary
        """
        if not is_android:
            # Currently only support Android mobile version
            return

        if not isinstance(method,str) \
        or not isinstance(msg_dict,dict):
            return

        # Create broadcast intent
        intent = IntentClass()
        action = 'MobileInsight.'+self.__class__.__name__+'.'+method
        intent.setAction(action)

        # Put extras into intent
        for item in msg_dict:
            # self.log_info('key='+item+' value='+msg_dict[item])
            intent.putExtra(JavaString(item),JavaString(msg_dict[item]))

        # Broadcast message
        try:
            mi2app_utils.pyService.sendBroadcast(intent)
        except Exception, e:
            import traceback
            self.log_error(str(traceback.format_exc()))