MTK SmartPhone Record-(3)

来源:互联网 发布:公司内部网络ip建设 编辑:程序博客网 时间:2024/06/05 20:57
51. 如何使得用户在将预置的 APK 卸载后,恢复出厂设置时能恢复?
为了让用户在将预置的 APK 卸载后,恢复出厂设置时能恢复,敝司做了一个 Feature,但在ALPS.GB.TDFD.MP.V1.7和 ALPS.GB.FDD2.MP.V4.7版本后支持,若贵司版本低于此版本,请申请 Patch ALPS00092543;
大致的做法是:
- 在out/target/product/project_name/system目录下新建一个名为appbackup的文件夹,将该应用的apk文件copy到appbackup文件夹下
- 在mediatek/config/project_name/ProjectConfig.mk文件中添加定义:MTK_SPECIAL_FACTORY_RESET=yes
- 在out/target/product/project_name/data/app下创建一个.restore_list,并且在其中添加语句:
/system/appbackupx.apk(注意,.restore_list中的每一行都要以"/system” 开头)
当卸载了data/app下的apk后,再恢复出厂设置,系统会从 .restore_list 中读取apk的名字,然后从 appbackup 文件中把apk重新拷贝到data/app下,从而恢复data/app下已经卸载了的apk。
以上操作过程,DCC 上面也有相应的文档可供参考,文档的名字叫: Android SD upgrade application note.docx,里面有一项:MTK special factory reset,就详细地介绍了以上操作步骤。


52. 实现列表菜单
(1)TestingSettings.java
package com.android.settings;
import android.os.Bundle;
import android.preference.PreferenceActivity;

public class TestingSettings extends PreferenceActivity {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       
       addPreferencesFromResource(R.xml.testing_settings);
   }
}
(2)testing_setings.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
       android:title="@string/testing" >
           
   <PreferenceScreen
           android:title="@string/testing_phone_info">
       <intent android:action="android.intent.action.MAIN"
               android:targetPackage="com.android.settings"
               android:targetClass="com.android.settings.RadioInfo" />
   </PreferenceScreen>
.........
.........
   <PreferenceScreen
           android:title="@string/testing_wifi_info" >
       <intent
               android:action="android.intent.action.MAIN"
               android:targetPackage="com.android.settings"
               android:targetClass="com.android.settings.wifi.WifiInfo" />
   </PreferenceScreen>

</PreferenceScreen>


53. 编译Recover.img模块命令:
./mk mm bootable/recovery
./mk r kernel
./mk -opt=ONE_SHOT_MAKEFILE=build/target/board/Android.mk r recoveryimage


54. 工厂模式 VOLUME_DOWN + POWER
(1)\mediatek\custom\ald75_zs4\kernel\dct\dct\cust_kpd.h
#define MT65XX_META_KEY  10    /* KEY_HOME */
#define MT65XX_RECOVERY_KEY  9    /* KEY_VOLUMEUP */
#define MT65XX_FACTORY_KEY  0    /* KEY_VOLUMEDOWN */
(2)\mediatek\custom\ald75_zs4\uboot\inc\configs\ubconfigs.h
#define MT65XX_META_KEY10 //42/* KEY_2 */
#define MT65XX_RECOVERY_KEY9 //11
#define MT65XX_FACTORY_KEY0 //10
(3)\mediatek\custom\ald75_zs4\factory\inc\cust_keys.h
#define CUST_KEY_UPKEY_UP
#define CUST_KEY_VOLUPKEY_VOLUMEUP
#define CUST_KEY_DOWNKEY_DOWN
#define CUST_KEY_VOLDOWNKEY_VOLUMEDOWN
#define CUST_KEY_LEFTKEY_MENU
#define CUST_KEY_CENTERKEY_HOME //KEY_HOMEPAGE
#define CUST_KEY_RIGHTKEY_BACK
#define CUST_KEY_CONFIRMKEY_HOME //KEY_HOMEPAGE  
#define CUST_KEY_BACKKEY_BACK

55. 恢复模式Recovery ModeVOLUME_UP + POWER
\alps\mediatek\custom\handing15_x069\recovery\inc\cust_keys.h
#define RECOVERY_KEY_ENTER    KEY_POWER
#define RECOVERY_KEY_MENU     KEY_VOLUMEUP
\alps\bootable\recovery\ui.c
static int show_text = 1;//Daniel_mod 进入recovery mod 立即显示menu菜单,old_value: 0
编译Recover.img模块命令:
./mk mm bootable/recovery
./mk r kernel
./mk -opt=ONE_SHOT_MAKEFILE=build/target/board/Android.mk r recoveryimage


56. 工程模式手写IMEI
\mediatek\source\packages\EngineerMode\src\com\mediatek\engineermode\GPRS.java
public void onCreate(Bundle savedInstanceState) {
...
//Daniel_mod DisplayWriteIMEI mEditImeiValue.setEnabled(false);
//Daniel_mod DisplayWriteIMEI mBtnImei.setVisibility(View.INVISIBLE);
  //Daniel_mod DisplayWriteIMEI if(usermode.equalsIgnoreCase("user"))
     if(false)
     {        
      mBtnSim1.setVisibility(View.GONE);
      mBtnSim2.setVisibility(View.GONE);
      mBtnImei.setVisibility(View.GONE);
      mEditImeiValue.setVisibility(View.GONE);
     }
}


57. 如何获取android设备的imei号
java获得android的imei号权限添加 
TelephonyManager telephonyManager = (TelephonyManager) this .getSystemService(Context.TELEPHONY_SERVICE); 
String IMEI = telephonyManager.getDeviceId(); 
adb命令获得:adb shell dumpsys iphonesubinfo有时候返回为空是因为,模块电源关闭了。
重置后需要打开模块电源才能读出来查看机器的一些系统设置参数adb shell getprop


58. 默认24小时制
(1)在\frameworks\base\packages\SettingsProvider\res\values\defaults.xml
添加: <string name="time_12_24" translatable="false">24</string>
(2)在DatabaseHelper.java 文件
private void loadSystemSettings(SQLiteDatabase db) {
...
loadStringSetting(stmt, Settings.System.TIME_12_24, R.string.time_12_24);
...
}

59. 设置个别特殊字体
public void onCreate(Bundle icicle) {
...
lock_input_text = (EditText)findViewById(R.id.lock_input_text);
lock_input_text.setText(getIntent().getStringExtra("title_text"));
lock_input_text.requestFocus();
Typeface typeFace = Typeface.createFromAsset(getAssets(),"fonts/Kaiti.ttf");
lock_input_text.setTypeface(typeFace);
lock_input_text.selectAll();
...
}

60. 修改默认网络模式
设置-更多-移动网络-网络模式-首选网络模式:仅限GSM
(1)\frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java
private void loadSecureSettings(SQLiteDatabase db) {
...
            // Set the preferred network mode to 0 = Global, CDMA default
            int type;
            if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
                type = Phone.NT_MODE_GLOBAL;
            } else {
                type = SystemProperties.getInt("ro.telephony.default_network",
                        RILConstants.PREFERRED_NETWORK_MODE);
            }
            loadSetting(stmt, Settings.Secure.PREFERRED_NETWORK_MODE, 1);//Daniel_mod Old value: type
...
}
(2)\frameworks\base\telephony\java\com\android\internal\telephony\RILConstants.java
int PREFERRED_NETWORK_MODE      = NETWORK_MODE_GSM_ONLY;//Daniel_mod Old_value: NETWORK_MODE_WCDMA_PREF

61. 切换开关机动画的问题:Eng版本可以切换Logo.bin(开机第一张Logo),User版本切换不了Logo.bin
(1)\bootable\recovery\mtdutils\Android.mk
......
include $(CLEAR_VARS)
LOCAL_SRC_FILES := flash_image.c
LOCAL_MODULE := flash_image
LOCAL_MODULE_TAGS := optional#把eng改成optional
LOCAL_STATIC_LIBRARIES := libmtdutils
LOCAL_SHARED_LIBRARIES := libcutils libc
include $(BUILD_EXECUTABLE)
(2)把flash_image从 \out\target\product\ald75_zs4\system\bin 拷贝到 \vendor\mediatek\ald75_zs4\artifacts\out\target\product\ald75_zs4\system\bin目录下


62. Android代码宏控制方案(2013-04-12 10:29:59)转载▼ 分类: android  
目前107分支上,在各项目projectConfig.mk中已添加项目宏以及客户宏,例如:
QH_CUSTOM = songri
QH_PROJECT = s100 
使用上述projectconfig.mk中定义的宏,实现宏控制代码控制方法如下:
 
(1)对于java代码:
在common.mk中,根据上述宏定义添加property属性,如下。
ifdef QH_PROJECT
ifeq ($(strip $(QH_PROJECT)),s100)
   PRODUCT_PROPERTY_OVERRIDES += \
     ro.project.name=s100
endif
 
ifeq ($(strip $(QH_PROJECT)),s107)
   PRODUCT_PROPERTY_OVERRIDES += \
     ro.project.name=s107
endif
endif
 
在java代码中可以通过获取property属性来实现控制不同项目的代码,例如:
private static final boolean IS_PROJECT_S100 = SystemProperties.get("ro.project.name").equals("s100");
if (IS_PROJECT_S100)
{
// project s100 code
}
else
{
// other code
}
107分支上,上述项目和客户的property属性已经定义,java代码中如需使用可直接引用。
 
(2)在makefile中
可以直接使用 ifeq ifneq 判断来实现逻辑控制。
如:
ifeq ($(QH_PROJECT),s100)
LOCAL_CFLAGS += -D QH_PROJECT_S100
endif
 
(3)对于.c cpp .h中,
在projectConfig.mk中定义宏开关之外,还需在自己的android.mk中定义宏,如上述第2步。
然后直接使用android.mk中定义的宏进行控制,如:
#ifdef QH_PROJECT_S100
// code s100
#else
// other code
#endif

63. Android代码,用宏控制
(1)Projectconfig.mk
MMI_LANG_VERSION_SUPPORT = LANG_ZHCN
# candidate settings: LANG_ZHCN/LANG_FOREIGN
    (2)common.mk
      ifeq ($(strip $(MMI_LANG_VERSION_SUPPORT)),LANG_ZHCN)
 PRODUCT_PROPERTY_OVERRIDES += \
   ro.project.lang.version=Zhcn
   ro.product.locale.language= zh
   ro.product.locale.region= CN
   persist.sys.timezone=Asia/Shanghai
 else
 PRODUCT_PROPERTY_OVERRIDES += \
   ro.project.lang.version=Foreign
   ro.product.locale.language= en
   ro.product.locale.region= US
   persist.sys.timezone=Europe/London
 endif
(3) 在 \mediatek\config\xxx\system.prop 或 \build\tools\buildinfo.sh 添加如下
# Lang version
ro.project.lang.version=Zhcn
(4)*.java
import android.os.SystemProperties;
class XXX{
if ("Zhcn".equals(SystemProperties.get("ro.project.lang.version"))) {
//Zhcn
}else {//if ("Foreign".equals(SystemProperties.get("ro.project.lang.version"))){
//Foreign
}
}

64. Camera默认值修改 
上层camera_preferences.xml
hal层mediatek\custom\common\hal\imgsensor\sp2518_yuv\cfg_ftbl_sp2518_yuv.h
mediatek\custom\common\kernel\imgsensor\inc\kd_camera_feature_enum.h
mediatek\source\external\camera\MTKCameraHardware.cpp

65. 在Android.mk里添加复制语句
(1)拷贝图片资源
ifeq ($(BIRD_DOOV_STYLE), yes)
$(shell cp -rf $(LOCAL_PATH)/Doov/*.* $(LOCAL_PATH)/res/drawable-hdpi/)
else ifeq ($(BIRD_SET_COLOR_ICON), yes)
$(shell cp -rf $(LOCAL_PATH)/Doov/*.* $(LOCAL_PATH)/res/drawable-hdpi/)
endif
(2)拷贝APK,*.so
ifeq (LANG_FOREIGN,$(strip $(MMI_LANG_VERSION_SUPPORT)))
LOCAL_POST_PROCESS_COMMAND := $(shell cp -r $(LOCAL_PATH)/Foreign_apps/*.apk $(TARGET_OUT)/app/) 
LOCAL_POST_PROCESS_COMMAND := $(shell cp -r $(LOCAL_PATH)/Foreign_apps/*.so  $(TARGET_OUT)/lib/)
endif


66. 将packages/apps/下的app导入eclipse 的源码
当刚接触android自带的一个模块时,如何去熟悉它?相信不少人第一步都会尝试着去了解其内容的调用流程,而此时若能够单步调试则显得非常重要了,于是有了文章标题所说的尝试。
作者这里要导入的是Settings文件夹,基于android 4.0(MTK6515所用):
=== 1、将Settings整个文件夹拷贝一份备用 ===
=== 2、基于Settings建立一个eclipse工程 ===
打开eclipse,File > New > Project > Android Project > Create project from existing source,选择第1步所拷贝的Settings文件夹。
=== 3、导入部分framework library ===
执行完第2步会出现很多诸如"com.android.internal.R cannot be resolved"的错误,这主要是由于framework部分资源找不到,这时我们可以手动添加,当然前提是你要用整个工程的代码且已经编译。
在eclipse中右键工程名Settings,选择 Build Path > Configure Build Path > Libraries > Add External JARS,然后选择以下路径的jars:
1)out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar 
--这个主要是android的框架类
2)out/target/common/obj/JAVA_LIBRARIES/android-common_intermediates/classes.jar 
--这个包含com.android.common.Search这个类
3)out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar
--这个包包含dalvik.system.VMRuntime这个类
4)out/target/common/obj/JAVA_LIBRARIES/mediatek-framework_intermediates/classes.jar
--这个主要是mediatek的框架类
这样基本上就能解决大部分framework资源找不到的问题
*ps 这里也可将上述classes.jar重命名后复制到某一文件夹后统一导入
=== 4、导入app自身 ===
如这里导入:
out/target/common/obj/APPS/Settings_intermediates/classes.jar
=== 5、去除uid ===
打开 AndroidManifest.xml,找到 android:sharedUserId并去除之:
android:sharedUserId="android.uid.system"
否则在运行时会提示如下错误:
INSTALL_FAILED_SHARED_USER_INCOMPATIBLE

67. 打开新的Activity,传递若干个参数给它
public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState){
......
button.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
Intent intent = new Intent(MainActivity.this, NewAcitvity.class);
Bundle bundle = new Bundle();//该类用作携带数据
bundle.putString("name","lxt008");
bundle.putInt("age",80);
intent.putExtras(bundle);//附带上额外的数据
startActivity(intent);
}
});
}
}
在新的Activity中接收前面Activity传递过来的参数:
public class NewActivity extends Activity{
@Override
protected void onCreate(Bundle saveInstanceState){
......
Bundle bundle = this.getIntent().getExtras();
String name = bundle.getString("name");
Int age = bundle.getInt("age");
}
}

68. 广播接收者 - BroadcastReceiver
要实现一个广播接收者方法如下:
第一步:继承BroadcastReceiver,并重写onReceive()方法。
public class IncomingSMSReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent){
......
//一个BroadcastReceiver对象的生命周期不超过5秒,
//所以在BroadcastReceiver里不能做一些比较耗时的操作,
//如果需要完成比较耗时的工作,可以通过发送Intent给Activity或Service,由它们来完成。
//发送Intent启动服务,由服务来完成比较耗时的操作
Intent service = new Intent(context, XxxService.class);
context.startService(service);
//发送Intent启动Activity,由Activity来完成比较耗时的操作
Intent newIntent = new Intent(context, XxxActivity.class);
context.startActivity(newIntent);
}
}
第二步:订阅感兴趣的广播Intent,订阅方法有两种:
第一种:使用代码进行订阅
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
IncomingSMSReceiver receiver = new IncomingSMSReceiver();
registerReceiver(receiver,filter);
第二种:在 AndroidManifest.xml 文件中的<application>节点里进行订阅:
<receiver android:name=".IncomingSMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED">
</intent-filter>
</receiver>
在 AndroidManifest.xml 文件中添加以下权限:
<uses-permission android:name="android.permission.RECEIVE_SMS"/> <!--接收短信权限-->
<uses-permission android:name="android.permission.SEND_SMS"/> <!--发送短信权限-->

69. 添加菜单
public boolean onCreateOptionsMenu(Menu menu){
super.onCreateOptionsMenu(menu);
menu.add(0,1,"say hello");
menu.add(0,2,"exit");
return true;
}

public boolean onOptionsItemSelected(Item item){
super.onOptionItemSelected(item);
int id = item.getId();
switch(id){
case 1:
AlertDialog.show(this,getString(R.sring.app_name),getString(R.string.msg_dialog),
getString(R.string.ok_dialog),true);
break;

case 2:
finish();
break;
}
}

70. 延时
timer = new Timer();
timer.schedule(new TimerTask(){
public void run(){
NotificationManager manager=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Notification nf = new Notification(R.drawable.icon,"这是信息的详细描述",null,"信息的标题",null);
magager.nofify(0,nf);

HelloTwoDService.this.stopSelf();
}
},5000); //延时5秒钟
0 0