Android apk签名、第三方内置、图标添加与删除、开关机动画及铃声、启动第三方程序

Android apk签名、第三方内置、图标添加与删除、开关机动画及铃声、启动第三方程序的代码、添加壁纸选择列表(壁纸选择器)一:apk签名签名方法:1:添加权限    在AndroidManifest.xml文件下添加android:sharedUserId="android.uid.system"。
2:在Eclipse中导出无签名的应用文件   在工程中:右键->Android Tools -> Export Unsigned ApplicationPackage导出应用
3:找出系统签名密钥   系统密钥为:platform.pk8和platform.x509.pem   路径: build\target\product\security
4:找出系统签名工具   工具为:signApk.jar    路径:/out/host/linux-x86/framework/ signApk.jar
5:开始签名  将第2、3、4步找到的无签名应用、platform.pk8、platform.x509.pem和signApk.jar放到同一文件夹下如F:\sign。  打开 dos 操作界面,定们到F:\sign,输入命令:  java -jar signapk.jar platform.x509.pem platform.pk8 a.apk b.apk  (a.apk 为未签名应用 b.apk 为签名之后应用)

二:第三方app内置
内置APK有五种方式(第五种仅适合4.0以上的源代码)
1:步骤如下    A 将apk放入vendor/mediatek/***/artifacts/out/target/product/***/system/app     B 将apk用rar工具打开,提取lib目录下面的arm目录下面的所有so文件,将文件放入vendor/mediatek/***/artifacts/out/target/product/***/system/lib    C 确保mediatek/build/tools/mtkBegin.pl中104行的signApk的调用被注释掉编译源代码,完成后提取image文件烧机
2:如果你已经编译完了,则直接把apk文件放在/out/target/product/nollec73_gb/system/app下,
直接提取image文件烧进板子就可以了
3:使用这种方法,会将此APK加入到编译系统。当使用new时,此APK仍然会编译到系统中。这种方法必须要自己编写Android.mk文件(关于Android.mk可以参考),在研发中,自己有源码时,可以将APK的源码包置于Android源码中(比如:alps/package/apps中),然后需要编写Android.mk文件。然后执行命令:
./makeMtk<project_name> remake android <module_name> 具体步骤为:
①. 在alps/packages/apps/下新建一个目录,假定为Test。
②. 将###.apk(需要内置的apk)改名为Test.apk并放置在第一步新建的Test目录下。
③. 请将以下内容复制并保存为Android.mk ,同样放在Test目录下
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := user
LOCAL_PREBUILT_PACKAGE :=$(LOCAL_PATH)/Test.apk
LOCAL_PACKAGE_NAME := Test
LOCAL_CERTIFICATE := platform
include $(PREBUILT_PACKAGE)
注意:
要想用户能卸载内置的apk,请在Android.mk文件中把变量值
LOCAL_MODULE_TAGS由user改为tests
④. 在alps/build/target/product/<project_name>.mk文件中的PRODUCT_PACKAGES这一项添加一行Test
⑤. 将从###.apk解压出来的库###.so拷到
alps/vendor/mediatek/<project_name>/artifacts/out/target/product/<project_name>/system/lib/目录下(无so库的apk内置时,去掉此步骤)。
⑥. 在alps目录下执行
./mk <project_name> remake android。
特别注意:依照上述步骤制作,在编译时会出现错误而停止编译,这主要是LOCAL_MODULE_TAGS := user而引起的。
LOCAL_MODULE_TAGS :=user eng tests optional
user: 指该模块只在user版本下才编译
eng: 指该模块只在eng版本下才编译
tests: 指该模块只在tests版本下才编译
optional:指该模块在所有版本下都编译
所以将以上Android.mk中的user改为test或者potional都可以,至于user版本的编译是指在发布版中。我们这里的发布版的编译命令是:./makeMtk -opt=TARGET_BUILD_VARIANT=useryecon73v1 new  ⑦:注册apk和库文件 /build/core/user_tags.mk 下 将你的库文件名称放进去/build/target/product/common.mk 或者 core.mk 将apk名字放进去

4:不用管是否含有.so文件 直接在vendor/mediatek/***/artifacts/out/target/product/***/下新建data文件 data下新建app文件app文件下放你要内置的apk文件 重新编译执行就好了  data文件是与system文件平级的在同一文件下
5: 仅使用于android4.0以上版本 这种跟第三种 方法差不多 都需要编写Android.mk文件 不过不同点是 含有库文件的第三方还要给每个库文件单独拿出来编写Android.mk文件 以下就是内置步骤:(举例:第三方Map.apk,下有两个库文件 Map1.so和Map2.so) ①:在目录 /mediatek/source/operator/OP02/SPEC0200/operator_packages/ 下新建Map、Map1、Map2文件夹,分别存放Map.apk 和Android.mk、Map1.so和Android.mk、Map2.so和Android.mk文件②:编写Android.mk文件 库文件的Android.mk文件和apk的不同 下粘上代码
APK的Android.mk

ifneq (,$(filter QQIM,$(OPTR_APK)))
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)
# Module name should match apk name to be installedLOCAL_MODULE := QQIMLOCAL_MOUDLE_TAGS := userLOCAL_SRC_FILES := $(LOCAL_MODULE).apkLOCAL_MODULE_CLASS := APPSLOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)LOCAL_CERTIFICATE := platforminclude $(BUILD_PREBUILT)
endif
库文件的Android.mk  (这有两个库文件 只介绍一个以Map1.so为例 其他的以此类推)
# barrier for searching Android.mk# Android.mk in out will be enumrated in mediatek/build/android


ifneq (,$(filter Map1, $(OPTR_APK)))LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)
# your prebuilt file nameLOCAL_MODULE := Map1 .soLOCAL_MODULE_TAGS := userLOCAL_MODULE_CLASS := SHARED_LIBARARY# your prebuilt file (must be relative directory )LOCAL_SRC_FILES := $(LOCAL_MODULE)# the path your prebuilt file will be installed   $(TARGET_OUT) is the system directoryLOCAL_MODULE_PATH := $(TARGET_OUT)/libLOCAL_CERTIFICATE := platforminclude $(BUILD_PREBUILT)
endif
③:Android.mk文件编译完毕 然后注册下 让系统能找到这些文件
/build/core/user_tags.mk 内置的apk文件名字放进去 在apk名字下放库文件(注意 这时候库文件要带.so后缀名的 )  四:桌面图标添加与删除        在定制手机 在源代码编译的时候 有点的时候需要去掉桌面上乱七八糟的用不着的图标,这样既不影响功能又看起来简洁,我们可以这样去做

在Androidmanifest.xml中 可以直接把你注册的主Activity的这句代码去掉
<category android:name="android.intent.category.LAUNCHER" />就可以了,这样就可以隐藏这个app的图标 其他程序要调用的时候也会启动

添加桌面图标则相反 在你的注册的Activity里添加<category android:name="android.intent.category.LAUNCHER"/>
就好了,还要为其制定一个图标android:icon="@drawable/icon"

Android app名字过长美化处理方法
if((l=appName.length())>=6){                appName1=appName.substring(0, appName.length()/2);                appName1=appName1+"\r\n"+appName.substring(appName.length()/2);                wrapper.mTextView.setText(appName1);
}  
五:定制开关机动画及铃声原理与方法开关机动画及开关机铃声开机动画是在init.rc里起了一个服务,代码如下:[javascript] view plaincopyprint?
1.  service bootanim /system/bin/bootanimation   
2.      user graphics  
3.      group graphics  
4.      disabled  
5.  oneshot  
而bootanimation的代码是在以下路径下
/frameworks/base/cmds/bootanimation
相关动画与声音资源放在如下路径:
/frameworks/base/data/sound/
1:制作开关机动画
下面分析系统开机画面的构成文件名为bootanimation.zip 一定是这个不能修改,里面包含part1part2文件夹 和desc.txt,part 文件夹里面放的是动画拆分的图片,格式为png, desc.txt里面是播放的设置。格式是这样的
480 800 15p 1 0 part0p 0 0 part1480 800是指显示的分辨率宽 高15是一秒的帧数p后面的数字是指播放次数 0为循环,N为播放N次后面那位数字一般为0(空指令), 表示播放一遍后稍作停顿的时间part0,part1 为文件夹名一般我们只使用part0目录
XP下:图片准备好了,desc.txt里面的命令也准备好了,就可以把他们一起打包压缩成zip格式了。记住,是zip格式,而不是rar格式。另外压缩的时候注意一点,压缩的时候压缩方式要选择存储,否则开机时手机会不认的。当然不至于变砖,只是开机的时候会黑着没动画一直到进入桌面为止。
Ubuntu系统下:制作bootanimation.zip文件 创建两个目录和一个文件,然后使用软件或者是命令行大包即可zip -r -0 bootanimation.zip part0 part1desc.txt
重要的操作在于修改Android.mk,需要在里面添加$(LOCAL_PATH)/bootanimation.mp3:system/media/bootanimation.mp3\$(LOCAL_PATH)/bootanimation.zip:system/media/bootanimation.zip就会把你的bootanimation.zip,bootanimation.MP3放到system/media/下面了。

2:动画文件路径
1. uboot路径mediatek\custom\common\uboot\logo\hvga\hvga_kernel.bmpmediatek\custom\common\uboot\logo\hvga\hvga_uboot.bmp2. android上层动画路径vendor\mediatek\project\artifacts\out\target\product\project\system\media\注:android2.3 mtk源码的路径为:/frameworks/base/date/sounds/Android4.0及以上mtk源代码路径为:/mediatek/source/operator/OP02/SPEC0200/operator_packages/bootanim/①.开机动画路径
vendor/mediatek/***/artifacts/out/target/product/***/system/media/bootanimation.zip
注:Android2.3:   /frameworks/base/date/sounds/bootanimation.zip
Android4.0: /mediatek/source/operator/OP02/SPEC0200/operator_packages/bootanim/bootanimation/.../bootanimation.zip②.开机铃音路径vendor/mediatek/***/artifacts/out/target/product/***/system/media/bootaudio.mp3
注:Android2.3:/frameworks/base/date/sounds/bootaudio.mp3
Android4.0:/mediatek/source/operator/OP02/SPEC0200/operator_packages/bootanim/bootaudio/bootaudio.mp3
③. 关机动画路径
/vendor/mediatek/***/artifacts/out/target/product/***/system/media/shutanimation.zip
注:Android2.3: /frameworks/base/date/sounds/ shutanimation.zip
Android4.0:/mediatek/source/operator/OP02/SPEC0200/operator_packages/shutanim/shutanimation/shutanimation.zip
并确认frameworks/base/core/java/com/android/internal/app/ShutdownThread.java 中 283行 mShutOffAnimation 的初始值为true④. 关机铃音路径修改vendor/mediatek/***/artifacts/out/target/product/***/system/media/shutaudio.mp3
注:Android2.3:/frameworks/base/date/sounds/shutaudio.mp3
Android4.0:/mediatek/source/operator/OP02/SPEC0200/operator_packages/bootanim/shutaudio/shutaudio.mp3


3:开关机动画实现原理
Android系统在init.rc中定义了很多Servic,具体定义格式可以参考《Android Platform Developer’s Guide》中的“Android InitLanguage”。Init.rc中定义的Service将会被Init进程创建,其中已经定义的服务就包含了开机动画,但没有关机动画的定义
servicebootsound /system/bin/mplayer /system/media/bootsound
    usermedia
    groupaudio
    oneshot
//开机铃声服务 /system/media/startupsound是铃声文件
servicestartupsound /system/bin/mplayer /system/media/startupsound
    usermedia
    groupaudio
    disabled
    oneshot
//关机铃声服务 /system/media/shutdownsound是关机铃声
serviceshutdownsound /system/bin/mplayer /system/media/shutdownsound
    usermedia
    groupaudio
    disabled
    oneshot
//定义了一个bootanim的服务,对应执行/system/bin/bootanimation
//disabled 表示init进程创建只是创建它,但不立刻执行
//oneshot 表示该服务只执行一次
service bootanim /system/bin/bootanimation
    user graphics
    group graphics
    disabled
oneshot


当android系统boot时,开始加载动画和开机铃声,其代码位于
//源文件SurfaceFlinger.cpp
status_t SurfaceFlinger::readyToRun() {
   
    // start boot animation service
    property_set("ctl.start","bootanim");//注
    {
        charvalue[PROPERTY_VALUE_MAX];
        property_get("persist.sys.profile.silent",value, "0");
        if(atoi(value)== 0){
            LOGI("start:persist.sys.profile.silentis soundable");
            //start startupsound service
            property_set("ctl.start","startupsound");//注
         }else {
            LOGI("start:persist.sys.profile.silentis silent");
         }
    }
    return NO_ERROR;
}

当Android完成boot后,关闭动画和开机铃声,代码位于
//源文件SurfaceFlinger.cpp
void SurfaceFlinger::bootFinished() {
   const nsecs_t now = systemTime();
   const nsecs_t duration = now -mBootTime;
   LOGI("Boot is finished (%ldms)", long(ns2ms(duration)) );
   mBootFinished = true;
   //stop bootanim service
   property_set("ctl.stop","bootanim");
   char value[PROPERTY_VALUE_MAX];
   property_get("persist.sys.profile.silent",value, "0");
   if (atoi(value)== 0){
       LOGI("stop:persist.sys.profile.silentis soundable");
       //stopstartupsound service
       property_set("ctl.stop","startupsound");
   } else {
       LOGI("stop:persist.sys.profile.silentis silent");
   }
}

如何理解ctr.start和ctr.stop系统属性?
每一项服务必须在/init.rc中定义.Android系统启动时,init守护进程将解析init.rc和启动属性服务,属性“ ctl.start ”和“ ctl.stop ”是用来启动和停止服务的。一旦收到设置“ ctrl.start ”属性的请求,属性服务将使用该属性值作为服务名找到该服务,启动该服务。这项服务的启动结果将会放入“ init.svc.<服务名>“属性中 。客户端应用程序可以轮询那个属性值,以确定结果。想更深入了解Android property系统可以参考博文《(翻译)Android属性系统》。
property_set("ctl.start",ServiceName);就是启动ServiceName服务(在init.rc中定义);
property_set("ctl.stop",ServiceName)相对的是关闭ServiceName服务。
A启动动画服务
由于开机动画和关机动画除了播放的动画文件不同,其他的完全一致,这里重复利用/system/bin/bootanimation代码, 仿照开机动画服务,我们新定义关机动画
service shutdownanim/system/bin/bootanimation -shutdown
    usergraphics
    groupgraphics
    disabled
    oneshot
唯一要注意的是关机动画使用的/system/bin/bootanimation带了-shutdown参数,这个参数用来区分加载的动画文件为开机还是关机动画。当bootanimation服务启动时,进入/frameworks/base/cmds/bootanimation/bootanimation_main.cpp主函数main,
int main(intargc, char** argv)
{
#ifdefined(HAVE_PTHREADS)
    setpriority(PRIO_PROCESS,0, ANDROID_PRIORITY_DISPLAY);
#endif
    charvalue[PROPERTY_VALUE_MAX];
    property_get("debug.sf.nobootanimation",value, "0");
    intnoBootAnimation = atoi(value);
    LOGI_IF(noBootAnimation,  "bootanimation disabled");
    if(!noBootAnimation) {
        sp<ProcessState>proc(ProcessState::self());
        ProcessState::self()->startThreadPool();
        //create the animation object
        sp<BootAnimation>boot = new BootAnimation();
        //根据是否有参数,来设置动画对象的isShutdown属性
        if (argc > 0) {
            if(strcmp(argv[0], "-shutdown")==0) {
                boot->isShutdown(true);
            }
        }
        IPCThreadState::self()->joinThreadPool();
    }
    return0;
}
newBootAnimation();时,如果有参数-shutdown, 则boot->isShutdown(true);方法isShutdown和isShutdown使我们新加的,所以先要在frameworks/base/cmds/bootanimation/bootanimation/BootAnimation.h头文件中申明为public,如下:
classBootAnimation : public Thread, public IBinder::DeathRecipient
{
public:
                BootAnimation();
    virtual     ~BootAnimation();
    sp<SurfaceComposerClient>session() const;
    bool        mShutdown;
void        isShutdown(boolshutdown);
…………………………………………….
}
之后修改BootAnimation.cpp
//源码位于frameworks/base/cmds/bootanimation/bootanimation/BootAnimation.cpp
首先在构造函数中初始化mShutdown = false;表示默认是开机标志
BootAnimation::BootAnimation(): Thread(false)
{
    mSession= new SurfaceComposerClient();
    mShutdown= false;
}
实现isShutdown(bool shutdown);方法
voidBootAnimation::isShutdown(bool shutdown)
{
    mShutdown= shutdown;
}
修改status_tBootAnimation::readyToRun() 方法来根据mShutdown值加载动画文件,如
status_tBootAnimation::readyToRun() {
……………………………………
mAndroidAnimation = false;
if (!mShutdown) {
    status_t err =mZip.open("/data/local/bootanimation.zip");
    if (err != NO_ERROR) {
        err =mZip.open("/system/media/bootanimation.zip");
        if (err!= NO_ERROR) {
            mAndroidAnimation= true;
        }
    }
} else {
    status_t err = mZip.open("/data/local/shutdownanimation.zip");
    if (err != NO_ERROR) {
        err =mZip.open("/system/media/shutdownanimation.zip");
        if (err!= NO_ERROR) {
            mAndroidAnimation= true;
        }
    }
    mShutdown = false;
}
return NO_ERROR;
}
以上是动画定制化C代码部分的全部修改。
B启动开机铃声服务
startupsound开机铃声服务,shutdownsound关机铃声服务
init.rc定义,service startupsound /system/bin/mplayer/system/media/startupsound
相当于用/system/bin/mplayer对象播放媒体文件/system/media/startupsound,
init.rc定义,service shutdownsound /system/bin/mplayer/system/media/shutdownsound
相当于用/system/bin/mplayer对象播放媒体文件/system/media/ shutdownsound.
到这里,开机动画和开机铃声是正常的,我们还需要修改的是关机时候的执行流程,因为默认的操作时关机确认后显示进度条。
C定制Android关机过程
在Android系统中,长按Power键默认会弹出对话框让你选择“飞行模式”,“静音”,“关机”等功能。
     我的目标是长按Power键,将会关机,弹出“设备将要关机”选择对话框。如果可以选择“是”关机,和“否”返回系统。
弹出对话框的代码位于:
frameworks\policies\base\phone\com\android\internal\policy\impl\PhoneWindowManager.java
长按Power键显示对话框的代码如下:
RunnablemPowerLongPress = new Runnable() {
    publicvoid run() {
        mShouldTurnOffOnKeyUp= false;
        performHapticFeedbackLw(null,HapticFeedbackConstants.LONG_PRESS, false);
        sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
        showGlobalActionsDialog();
    }
};
调用showGlobalActionsDialog方法将会显示上面提到的显示“飞行模式”,“静音”,“关机”,选项的对话框。
      关机的代码位于:
frameworks\policies\base\phone\com\android\internal\policy\impl\GlobalActions.java
文件的createDialog方法中,有如下代码:
mItems =Lists.newArrayList(
    //silent mode
    mSilentModeToggle,
    //next: airplane mode
    mAirplaneModeOn,
    //last: power off
    newSinglePressAction(
           com.android.internal.R.drawable.ic_lock_power_off,
           R.string.global_action_power_off){
                public void onPress() {
                    //shutdown by making sure radio and power are handled accordingly.
                    ShutdownThread.shutdown(mContext,true);
                }
                publicboolean showDuringKeyguard() {
                    returntrue;
                }
                publicboolean showBeforeProvisioning() {
                    returntrue
                }
            });
从代码中我们可以看出,如果选择上述对话框的“关机”选项之后,将会调用ShutdownThread的shutdown方法来关机。shutdown方法的第二个参数标识是否弹出询问对话框。

ShutdownThread代码位于
frameworks/base/core/java/com/android/internal/app/ShutdownThread.java
shutdown方法中有如下代码
public staticvoid shutdown(final Context context, boolean confirm) {
    //ensure that only one thread is trying to power down.
    //any additional calls are just returned
    synchronized(sIsStartedGuard){
        if(sIsStarted) {
            Log.d(TAG,"Request to shutdown already running, returning.");
            return;
        }
    }
    Log.d(TAG,"Notifying thread to start radio shutdown");
    if(confirm) {
        finalAlertDialog dialog = new AlertDialog.Builder(context)
               .setIcon(android.R.drawable.ic_dialog_alert)
               .setTitle(com.android.internal.R.string.power_off)
               .setMessage(com.android.internal.R.string.shutdown_confirm)
               .setPositiveButton(com.android.internal.R.string.yes,
new DialogInterface.OnClickListener() {
                           publicvoid onClick(DialogInterface dialog, int which) {
                               beginShutdownSequence(context);
                           }
                    })
                .setNegativeButton(com.android.internal.R.string.no,null)
                .create();
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
        if(!context.getResources().getBoolean(
             com.android.internal.R.bool.config_sf_slowBlur)){
dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
        }
        dialog.show();
    }else {
        beginShutdownSequence(context);
    }
}
确认关机后开始执行beginShutdownSequence(context),这里就是我们定制关机过程的关键。

修改beginShutdownSequence(context)方法,在方法开头打印Log之后增加如下代码:
//我们判断如果有关机动画文件,即显示关机动画,否则显示默认的进度条。
boolean showShutdownAnim = newFile("/system/media/shutdownanimation.zip").exists();
    if (showShutdownAnim) {
        Log.d(TAG,"shutdownanim");
        //设置前面说的android系统属性ctr.start,即通知属性服务启动关机动画服务
        android.os.SystemProperties.set("ctl.start","shutdownanim");
    } else {
        // throwup an indeterminate system dialog to indicate radio is
        //shutting down.
        ProgressDialogpd = new ProgressDialog(context);
        pd.setTitle(context.getText(com.android.internal.R.string.power_off));
        pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
        pd.setIndeterminate(true);
        pd.setCancelable(false);
        pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
        if(!context.getResources().getBoolean(
            com.android.internal.R.bool.config_sf_slowBlur)){
            pd.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
        }
        pd.show();
    }
    boolean playShutdownSound = newFile("/system/media/shutdownsound").exists();
    android.os.SystemProperties.getBoolean("ro.config.enable_shutdownshound",false);
    if (playShutdownSound) {
        // playshutdown sound
        Log.d(TAG,"shutdownsound");
        android.os.SystemProperties.set("ctl.start","shutdownsound");
}

下面是自己修改的隐藏指令控制开关机动画的修改
隐藏指令:在拨号界面输入特定的字符 比如“*#06#” 就会弹出一个dialog 执行操作 隐藏指令管理类    /projects/packages/apps/Contacts/src/com/android/contacts/SpecialCharSequenceMgr.javaimport android.os.PowerManager;//关机管理import android.os.SystemProperties;//系统属性管理  添加要输入的隐藏指令 字符 这里 "*#06#" 是系统默认的 显示“移动通信国际识别码” “*#08#”是自我添加的 要为选择切换动画文件做准备
public class SpecialCharSequenceMgr {    private static final String TAG = "SpecialCharSequenceMgr";    private static final String MMI_IMEI_DISPLAY = "*#06#";/*B0002 zhengqingwang add specialcharsequence for exchange animation start*/    private static final String Exchange_Animation = "*#08#";    public static Context mContext;/*B0002 zhengqingwang add specialcharsequence for exchange animation end*/
下面是判断键盘字符的识别方法
public static boolean handleIMEIDisplay(Context context, String input, boolean useSystemWindow) {        if (input.equals(MMI_IMEI_DISPLAY)) {            int phoneType = ((TelephonyManager)context.getSystemService(                    Context.TELEPHONY_SERVICE)).getCurrentPhoneType();
            if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {                showIMEIPanel(context, useSystemWindow);                return true;            } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {                showMEIDPanel(context, useSystemWindow);                return true;            }        } /*B0002 zhengqingwang start*/ else if (input.equals(Exchange_Animation)){showAnimationSwitch(context);return true;}/*B0002 zhengqingwang end*/         return false;    }
以上能够看出当我在拨号界面输入"*#08#"的时候 会执行showAnimationSwitch()方法  这个方法就是处理弹出dialog、改变系统参数和执行关机重启命令
/*B0002 zhengqingwang add for add the animationswitche dialog start*/    static private void showAnimationSwitch(Context context) {final CharSequence[] items = {"Android","iphone"};        new AlertDialog.Builder(context).setTitle("切换开关机动画").setItems(items, new DialogInterface.OnClickListener() {                    public void onClick(DialogInterface dialog, int item) {Log.i("zhengqingwang00","items[item]======================="+item+"=========="+(items[item].equals("iphone"))+"======"+items.length);                        if(items[item].equals("Android")) {                          SystemProperties.set("persist.sys.boot.animation", "1"); Log.i("zhengqingwang01","items[item]=========111=============="+items[item]);                        } else if(items[item].equals("iphone")) { SystemProperties.set("persist.sys.boot.animation", "2"); Log.i("zhengqingwang02","items[item]==========222============="+items[item]);}//d.dismiss();PowerManager pManager=(PowerManager) mContext.getSystemService(Context.POWER_SERVICE);                          pManager.reboot("重启");                          System.out.println("execute cmd--> reboot\n" + "重启");                     }                }).show();//.setNegativeButton("确定", null)       }/*B0002 zhengqingwang add for add the animationswitche dialog end*/
接下来就是处理修改的系统信息,切换开关机动画类/projects/frameworks/base/cmds/bootanimation/Bootanimation.cpp
#include "cutils/properties.h"
#include "BootAnimation.h"
  /*B0002 zhengqingwang start*/    /*if(bBootOrShutDown){        status_t err = mZip.open("/data/local/bootanimation.zip");        if (err != NO_ERROR) {           err = mZip.open("/system/media/bootanimation.zip");           if (err != NO_ERROR) {               mAndroidAnimation = true;           }        }    } else {if(!bShutRotate){    status_t err = mZip.open("/data/local/shutanimation.zip");         if (err != NO_ERROR) {        err = mZip.open("/system/media/shutanimation.zip");        if (err != NO_ERROR) {                mAndroidAnimation = true;        }            }} else {    status_t err = mZip.open("/data/local/shutrotate.zip");         if (err != NO_ERROR) {                err = mZip.open("/system/media/shutrotate.zip");        if (err != NO_ERROR) {                mAndroidAnimation = true;        }        }}    }*/
char animation_type[5];property_get("persist.sys.boot.animation", animation_type, "2");    if(bBootOrShutDown){if(!(strcmp(animation_type, "2"))){LOGD("animation_type=============",animation_type);status_t err = mZip.open("/data/local/bootanimation.zip");        if (err != NO_ERROR) {               err = mZip.open("/system/media/bootanimation.zip");                    if (err != NO_ERROR) {               mAndroidAnimation = true;               }                }    }else {LOGD("animation_type=============",animation_type);               status_t err = mZip.open("/data/local/iphonebootanimation.zip");        if (err != NO_ERROR) {               err = mZip.open("/system/media/iphonebootanimation.zip");                    if (err != NO_ERROR) {               mAndroidAnimation = true;               }                }        }            } else {if(!bShutRotate){    if(!(strcmp(animation_type, "2"))){LOGD("animation_type=============",animation_type);    status_t err = mZip.open("/data/local/shutanimation.zip");         if (err != NO_ERROR) {            err = mZip.open("/system/media/shutanimation.zip");            if (err != NO_ERROR) {                mAndroidAnimation = true;            }                }    } else {LOGD("animation_type=============",animation_type);            status_t err = mZip.open("/data/local/iphoneshutanimation.zip");         if (err != NO_ERROR) {            err = mZip.open("/system/media/iphoneshutanimation.zip");            if (err != NO_ERROR) {                mAndroidAnimation = true;            }                }    }        }   }/*B0002 zhengqingwang end*/
上面的判断代码注释掉 加入自己的判断  重新编译 烧进板子 OK! 六:android 启动第三方程序的代码 方法一:        Intent intent = new Intent();          intent.setClassName(<package name>, <class name>);          startActivity(intent);方法二:        Intent i=new Intent;        ComponentName com= new ComponentName(<Package Name> , <Calss Name>);          i.setComponent(com);          startActivity(i);  
//启动媒体库
Intent i = new Intent();
ComponentName comp = new ComponentName("com.android.camera","com.android.camera.GalleryPicker");
i.setComponent(comp);
i.setAction("android.intent.action.VIEW");
startActivity(i);
//启动相机
Intent mIntent = new Intent();
ComponentName comp = new ComponentName("com.android.camera","com.android.camera.Camera");
mIntent.setComponent(comp);
mIntent.setAction("android.intent.action.VIEW");
startActivity(mIntent);
//启动htmlviewer,并打开指定的一个文件 注意TXT不能是ANSI的,否则会乱码
Intent intent = new Intent();
ComponentName cn = new ComponentName("com.android.htmlviewer", "com.android.htmlviewer.HTMLViewerActivity");
intent.setComponent(cn);
Uri uri = Uri.fromFile(new File("/sdcard/demo.txt"));
intent.setDataAndType(uri, "text/plain");
startActivity(intent);

七:添加壁纸选择列表(壁纸选择器)
在主界面按菜单键会弹出菜单,其中有一项是壁纸,当选择之后,出现一个选择器,出现一个列表,这个不是dialog ,你可以选择是一般的壁纸,还是比较炫的动态壁纸或者是从设备中寻找存在的照片设置为你的桌面壁纸。startWallpaper 方法,看一下源码
private voidstartWallpaper() {  
       closeAllApps(true);  
        final IntentpickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);  
        Intent chooser= Intent.createChooser(pickWallpaper,  
               getText(R.string.chooser_wallpaper));  
        // NOTE: Addsa configure option to the chooser if the wallpaper supports it  
        //       Removed inEclair MR1  
//        WallpaperManagerwm = (WallpaperManager)  
//                getSystemService(Context.WALLPAPER_SERVICE);
//        WallpaperInfowi = wm.getWallpaperInfo();  
//        if (wi != null&& wi.getSettingsActivity() != null) {  
//            LabeledIntentli = new LabeledIntent(getPackageName(),  
//                    R.string.configure_wallpaper,0);  
//            li.setClassName(wi.getPackageName(),wi.getSettingsActivity());  
//            chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS,new Intent[] { li });  
//        }  
       startActivityForResult(chooser, REQUEST_PICK_WALLPAPER);  
    }  
其实是根据 Intent 调用相关的 Activity。
final Intent pickWallpaper = newIntent(Intent.ACTION_SET_WALLPAPER);  
Intent chooser =Intent.createChooser(pickWallpaper,  
               getText(R.string.chooser_wallpaper));  
Intent.ACTION_SET_WALLPAPER表示的含义以及它的真实值  查看api
public static final StringACTION_SET_WALLPAPER  
Since: API Level 1  
Activity Action: Show settings forchoosing wallpaper  
Input: Nothing.  
Output: Nothing.  
Constant Value:"android.intent.action.SET_WALLPAPER"
该 Intent 常量是一个 String,表示启用设置壁纸的 Activity,也就是说只要我们的系统中有这样的 Activity(action为 android.intent.action.SET_WALLPAPER)就可以出现在选择器中。
原生的 android 系统中有三个这样的 Activity
1.WallpaperChooser.java
这是 Launcher 中的一个类,主要是选择壁纸的操作,和 Launcher.java 在一个包下面。通过 Launcher 的 Manifest.xml 文件就可以看到答案
</activity>  
<activityandroid:name="com.android.launcher2.WallpaperChooser"android:label="@string/pick_wallpaper"android:icon="@drawable/ic_launcher_wallpaper"android:screenOrientation="nosensor" android:finishOnCloseSystemDialogs="true">
<intent-filter>  
<actionandroid:name="android.intent.action.SET_WALLPAPER"/>  
<categoryandroid:name="android.intent.category.DEFAULT"/>  
</intent-filter>  
</activity>  
2..LiveWallpaperListActivity.java
位于/packages/wallpapers/LivePicker/src/com/android/wallpaper/livepicker 下面,主要是选择动态壁纸。其 Manifest.xml 文件:
<activityandroid:name="LiveWallpaperListActivity"  
           android:icon="@drawable/ic_launcher_live_wallpaper"  
           android:label="@string/live_wallpaper_picker_title"  
           android:theme="@android:style/Theme.NoTitleBar"  
           android:screenOrientation="nosensor">  
           <intent-filter>  
                <actionandroid:name="android.service.wallpaper.LIVE_WALLPAPER_CHOOSER" />
                <actionandroid:name="android.intent.action.SET_WALLPAPER" />  
                <categoryandroid:name="android.intent.category.DEFAULT" />  
           </intent-filter>  
       </activity>  
3.Photographs.java
在以前的版本中,android 使用的是Gallery,现在改变为Gallery3D,位于/packages/apps/Gallery3D/src/com/cooliris/media,对应的 Manifest.xml 文件可自行查阅。
至此就明白了壁纸选择的原理
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值