平板关机动画显示异常

本文介绍了解决Android设备在关机过程中因界面旋转导致的画面显示不全的问题。通过修改PowerOffHandler源代码,实现不同方向下的关机动画正确显示,并禁用重力感应以避免界面翻转。

  由于平板的界面可以自由的旋转,假设默认的lcd是横屏的,旋转到竖屏时,关机动画会先切换到横屏,

然后显示动画。出现了一瞬间界面只有一半的情况,这可能是Android本身的bug。这里的解决方法是当竖

屏的时候,不要切换到横屏显示动画,直接竖屏刷图(并将横屏时的图片旋转90进行显示)。


相应的修改如下  

Index: vendor/qcom/proprietary/qrdplus/Extension/apps/PowerOffHandler/PowerOffHandler.cpp
===================================================================
--- vendor/qcom/proprietary/qrdplus/Extension/apps/PowerOffHandler/PowerOffHandler.cpp	(revision 103)
+++ vendor/qcom/proprietary/qrdplus/Extension/apps/PowerOffHandler/PowerOffHandler.cpp	(working copy)
@@ -22,7 +22,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+//http://blog.youkuaiyun.com/baidu_31872269/article/details/53229342
+//http://blog.youkuaiyun.com/beibei_hao_csdn/article/details/53259814
 #define LOG_NDEBUG 0
 #define LOG_TAG "PowerOffHandler"
 
@@ -209,6 +210,56 @@
     return NO_ERROR;
 }
 
+
+// 顺时针 90 度
+static int RotationRight90(unsigned char * src, int srcW, int srcH, int channel)
+{
+	int i = 0;
+	int j = 0;
+	int k = 0;
+	unsigned char * tempSrc = NULL;
+	int mSize = srcW * srcH  * channel;
+	tempSrc = (unsigned char *)malloc(sizeof(char) * srcW * srcH * channel);
+	memcpy(tempSrc, src, mSize);
+	for(i = 0; i <=srcH-1 ; i ++)
+	{
+		for(j = 0; j < srcW; j ++)
+		{
+			for(k = 0; k < channel; k ++)
+			{
+				src[((j) * srcH + (srcH - 1 - i)) * channel + k]=tempSrc[(i * srcW + j) * channel + k];
+			}
+		}
+	}
+	free(tempSrc);
+   	return 0;
+}
+
+
+// 逆时针90度
+int RotationLeft90(unsigned char * src, int srcW, int srcH, int channel)
+{
+	int i = 0;
+	int j = 0;
+	int k = 0;
+	unsigned char * tempSrc = NULL;
+	int mSize = srcW * srcH  * channel;
+	tempSrc = (unsigned char *)malloc(sizeof(char) * srcW * srcH * channel);
+	memcpy(tempSrc, src, mSize);
+	for(i = srcH - 1; i >= 0; i --)
+	{
+		for(j = 0; j < srcW; j ++)
+		{
+			for(k = 0; k < channel; k ++)
+			{
+				src[((srcW-1-j)*srcH + i)* channel + k] =  tempSrc[(i * srcW + j) * channel + k];
+			}
+		}
+	}
+    return 0;
+}
+
+
 status_t PowerOffHandler::initTexture(const Animation::Frame& frame) {
     SkBitmap bitmap;
     SkMemoryStream stream(frame.map->getDataPtr(), frame.map->getDataLength());
@@ -229,9 +280,20 @@
     // bitmap will go out of scope when we return from this method.
     bitmap.lockPixels();
 
-    const int w = bitmap.width();
-    const int h = bitmap.height();
+    int w = bitmap.width();
+    int h = bitmap.height();
     const void* p = bitmap.getPixels();
+    if((screenstatus==1)||(screenstatus==3))
+    {
+    	if(screenstatus==1)
+		RotationLeft90((unsigned char *)p,w,h,4);
+    	if(screenstatus==3)
+    		RotationRight90((unsigned char *)p,w,h,4);
+	int tmp;
+    	tmp=w;
+    	w=h;
+    	h=tmp;
+    }
 
     GLint crop[4] = { 0, h, w, -h };
     int tw = 1 << (31 - __builtin_clz(w));
@@ -270,7 +332,6 @@
     }
 
     glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
-
     return NO_ERROR;
 }
 
@@ -289,13 +350,18 @@
     char value[PROPERTY_VALUE_MAX];
     property_get("persist.panel.orientation", value, "0");
     int orient = atoi(value) / 90;
-    if (orient == eOrientation90 || orient == eOrientation270) {
+    //if (orient == eOrientation90 || orient == eOrientation270) {
+    if((dinfo.orientation==1)||(dinfo.orientation==3)){
         int temp = dinfo.h;
         dinfo.h = dinfo.w;
         dinfo.w = temp;
+	screenstatus=dinfo.orientation;
     }
+
     Rect destRect(dinfo.w, dinfo.h);
-    mSession->setDisplayProjection(dtoken, orient, destRect, destRect);
+    if((dinfo.orientation==0)||(dinfo.orientation==2)){
+   	 mSession->setDisplayProjection(dtoken, orient, destRect, destRect);
+    }
     // create the native surface
     sp < SurfaceControl > control = session()->createSurface(
             String8("BootAnimation"), dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
@@ -344,7 +410,6 @@
     // instead of system predefined boot animation files.
     bool encryptedAnimation = atoi(decrypt) != 0
             || !strcmp("trigger_restart_min_framework", decrypt);
-
     ZipFileRO* zipFile = NULL;
     if ((encryptedAnimation
             && (access(getShutDownAnimationFileName(IMG_ENC), R_OK) == 0)
@@ -465,8 +530,16 @@
         char pathType;
         if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) {
             // ALOGD("> w=%d, h=%d, fps=%d", width, height, fps);
-            animation.width = width;
-            animation.height = height;
+	    if((screenstatus==1)||(screenstatus==3))
+	    {
+		animation.width = height;
+            	animation.height = width;
+	    }
+	    else
+	    {
+            	animation.width = width;
+            	animation.height = height;
+	    }
             animation.fps = fps;
         } else if (sscanf(l, " %c %d %d %s #%6s", &pathType, &count, &pause,
                 path, color) >= 4) {


  另外如果关机的过程中,转动屏幕,界面也会相应的翻转过来,这里只需要不响应重力传感器的动作即可。
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
找到updateRotationUncheckedLocked方法,加上

if(SystemService.isRunning("poweroffhandler")) {
                 return false;
        }
这里的关机服务是poweroffhandler,有的是bootanim,注意修改。


<think>好的,我现在需要帮用户解决关于全志芯片设备上实现关机动画和充电动画的问题。首先,我得回忆一下全志平台的相关知识。全志的芯片常用于嵌入式设备,比如平板电脑、智能家居设备等,这些设备通常基于Linux系统,所以动画实现可能和Linux的启动流程有关。 用户提到关机动画和充电效果,这让我想到Android系统的bootanimation制。不过全志的芯片可能有自己的定制方式。根据用户提供的引用内容,引用了使用zip命令打包图片和desc.txt文件,这跟Android的bootanimation.zip结构很相似。所以可能全志的设备也是采用类似的方法来管理启动、关机和充电的动画。 接下来,我需要确认全志平台是否使用bootanimation.zip来实现这些动画。通常,Android系统的开动画是通过bootanimation.zip放在/system/media目录下,由bootanim服务控制。而关机动画可能是一个类似的流程,但需要特定的服务或脚本触发。充电动画可能在充电时由不同的进程管理,比如在低电量状态下显示。 然后,关于实现步骤,可能需要以下步骤:准备动画帧图片,编写desc.txt描述文件,打包成zip,然后替换系统原有的动画文件。不过全志可能有特定的目录结构或命名规则,比如将关机动画命名为shutdownanimation.zip,或者放在不同的路径下。需要用户检查系统目录,比如/system/media/或/vendor/etc/,查看是否存在相关文件。 另外,权限问题也很重要。替换系统文件可能需要root权限,或者在编译固件时集成自定义的动画文件。用户如果是开发者,可能需要重新编译系统镜像,将自定义的动画打包进去。 还要考虑动画的播放控制。关机时,init进程可能会触发一个服务,执行播放动画的可执行文件。全志可能有自己的工具,比如bootanimation二进制文件,或者使用其他工具如ffmpeg来播放帧图片。需要检查系统服务文件,比如.init.rc或.sh脚本,看看关机时调用了哪个程序。 充电动画的实现可能更复杂,因为涉及到电池状态的检测。系统可能在充电时启动一个服务,持续监测电池电量并显示相应的动画。这部分可能需要修改框架层的代码,或者利用现有的守护进程。 最后,用户可能需要调试动画是否正常播放。可以通过logcat查看相关日志,或者直接替换文件后重启服务来测试效果。同时,注意图片格式和分辨率的匹配,避免因资源问题导致动画无法显示。 总结来说,步骤大致是:准备资源文件、打包成指定格式、替换系统文件、设置权限、重启服务。但具体细节可能需要参考全志的文档或现有系统文件的结构。如果用户没有找到相关文档,建议他们检查设备上的现有动画文件,或者联系全志的技术支持获取更详细的指导。</think>关于全志芯片设备关机和充电动画的实现,主要涉及Linux系统层级的动画控制制。以下是关键实现步骤和技术要点: ### 一、关机动画实现 1. **资源准备** 动画由多帧PNG/JPG图片和描述文件$desc.txt$组成,目录结构示例: ``` part0/ frame_001.jpg frame_002.jpg desc.txt ``` 2. **描述文件格式** $desc.txt$控制播放参数: ```text 480 800 30 # 分辨率宽 高 帧率 p 1 0 part0 # 循环次数 暂停帧数 目录 ``` 3. **打包部署** 使用zip命令打包并推送到设备: ```bash zip -Z store shutdown_animation.zip part0/*.jpg desc.txt adb push shutdown_animation.zip /system/media/ ``` 需设置文件权限$644$并重启设备生效[^1] ### 二、充电动画实现 1. **动态响应制** 通过$sys/class/power_supply/battery/$目录实时读取: - $status$(充电状态) - $capacity$(电量百分比) 2. **动画控制脚本** ```bash while true; do bat_cap=$(cat /sys/class/power_supply/battery/capacity) if [ $bat_cap -lt 20 ]; then show_lowbat_animation elif [ $(cat /sys/class/power_supply/battery/status) = "Charging" ]; then show_charging_animation fi sleep 1 done ``` ### 三、系统集成要点 1. **服务配置** 在$init.rc$中添加: ```text service shutdown_anim /system/bin/bootanimation --shutdown class main oneshot ``` 2. **动画二进制调用** 全志平台通常使用修改后的$bootanimation$可执行文件,支持扩展参数: ```cpp // 源码中增加状态判断 if (strstr(argv[1], "--shutdown")) { loadAnimation("/system/media/shutdown_animation.zip"); } ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值