[MTK] How to auto update apn database by OTA

文摘 Android MediaTek 2020-07-3 阅读:851

[DESCRIPTION]

     通过fota 升级apns-conf.xml文件,系统不能自动去更新apn数据库,需要手动去操作。为了便于用户使用,需要进行客制化实现。

[SOLUTION]  

第一步: 修改code,并通过OTA升级更新上述修改

1) 定义OTA升级后的文件

File path: bootable/recovery/

int main(int argc, char **argv) {

     ...

     ...

         if (status != INSTALL_SUCCESS) {

           ui->Print("Installation aborted.\n");

           ui->Print("OTA failed! Please power off the device to keep it in this state and file a bug report!\n");

           // If this is an eng or userdebug build, then automatically

           // turn the text display on if the script fails so the error

           // message is visible.

           if (is_ro_debuggable()) {

               ui->ShowText(true);

           }

+       }else{

+           create_ota_done_file();

+       }

         ...

         ...

}          

+   static const char *OTA_DONE_FILE = "/cache/otadone";

+   int create_ota_done_file(void){

+  FILE *fd;

+  printf("--create_ota_done_file %s", OTA_DONE_FILE);      

+  fd = fopen_path(OTA_DONE_FILE, "w");

+  printf(" fd=%d , file open :", fd);

+  if (fd == NULL) {

+  printf(" failed, error code: %s", strerror(errno));

+  return -1;

+  }else{

+  printf("success ");

+  chown(OTA_DONE_FILE,2001,2001);

+  chmod(OTA_DONE_FILE,0777);      

+  }

+  fclose(fd);

+  return 0;

+   }

}  

2) file path : packagesappsSettingsAndroidManifest.xml

...

....

+   <receiver android:name="com.android.settings.ApnBootCompleteReceiver">

+  <intent-filter>

+             <action android:name="android.intent.action.BOOT_COMPLETED"></action>

+  </intent-filter>

+     </receiver>

   </application>

}          

3)新增一支处理APN 数据更新的文件

package com.android.settings;

import android.content.BroadcastReceiver;
import android.util.Log;
import java.io.File;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.net.Uri;
import java.util.List;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Environment;

public class ApnBootCompleteReceiver extends BroadcastReceiver{

    private static final String OTA_DONE_FILE="/cache/otadone";
    private static final String TAG = "ApnBootCompleteReceiver";
    private static final boolean DBG = true;   

   // public static final String RESTORE_CARRIERS_URI =  "content://telephony/carriers/restore";
   // private static final Uri DEFAULTAPN_URI = Uri.parse(RESTORE_CARRIERS_URI);

     public static final String UPDATE_CARRIERS_URI = "content://telephony/carriers/update_db"

     private static final Uri UPDATE_APN_URI = Uri.parse(UPDATE_CARRIERS_URI);
    private List<SubscriptionInfo> mSelectableSubInfos;

    private final String ACTION_BOOT ="android.intent.action.BOOT_COMPLETED";

    private void OtaDoneFile(Context context){
        File otaFile=new File(OTA_DONE_FILE);
        Log.d(TAG,"cachedirectory is:+"+Environment.getDownloadCacheDirectory());
        if (DBG) Log.d(TAG,"otaFile = " + otaFile);
        if(otaFile.exists()){
            Log.d(TAG,"OTA done success and update APN Info");
            ContentResolver resolver = context.getContentResolver();
                    /// M: add sub id for APN
                    // resolver.delete(DEFAULTAPN_URI, null, null);
            mSelectableSubInfos = SubscriptionManager.from(context).getActiveSubscriptionInfoList();

          if(mSelectableSubInfos ==null){

                Log.d(TAG,"no  sim is inserted");
                   return;

          }
            for(int i=0; i< mSelectableSubInfos.size();i++){
                  SubscriptionInfo mSubscriptionInfo=mSelectableSubInfos.get(i);
                  if(mSubscriptionInfo != null){
                            Log.d(TAG,"delete db start");
                            //int delete_id = resolver.delete(getDefaultApnUri(mSubscriptionInfo.getSubscriptionId()), null, null);

                                    int delete_id = resolver.delete(UPDATE_APN_URI, null, null);

                            Log.d(TAG,"delete id is:"+delete_id);
                            otaFile.delete();
                            Log.d(TAG,"delete db end");
                  }
           }
        }else{
            Log.d(TAG,"No OTA");
            return;
        }

    }

    private Uri getDefaultApnUri(int subId) {
        return Uri.withAppendedPath(DEFAULTAPN_URI, "/subId/" + subId);
    }

    @Override
    public void onReceive(Context context,Intent intent){
        if(ACTION_BOOT.equals(intent.getAction())){
          OtaDoneFile(context);
        }

 }

第二步: 在第一步基础上,再通过OTA 推送 APN 的数据更新  

补充说明:  为什么要经过两次OTA更新才能生效。由于OTA 升级会先启动recovery.cpp,虽然修改了recovery.cpp中的流程,但第一次OTA升级时默认会走recovery.cpp修改之前的逻辑,也就无法生成临时文件,无法触发APN 数据的自动更新。只有先通过OTA更新recovery.cpp的流程,让修改部分被执行, 再次OTA升级时,才能生成临时文件,触发APN数据的自动更新。



0条评论

© 2020 芯缘异码. Powered by Typecho