RK平台Android4.4 添加一个新的遥控器支持以及添加特殊按键

瑞芯微平台

SDK:Android4.4

好久没写博客了,最近工作中需要在SDK中添加一个新的遥控器支持,由于自己对java代码比较头大,过程也是一波三折,整个流程其实分析下来并不难,这里做个简单的总结。也算是学习android的一个开端。

1.  遥控器红外键值到linux层的映射

安卓4.4后linux层和红外层的键值映射是在设备树中修改的,不需要在linux中修改驱动代码,直接在相应的dts文件中修改即可,首先每个遥控器都有一个usercode,按照瑞芯微方面提供的文档:

在终端中输入命令:echo 1 > sys/module/cmcc_pwm_remotectl/parameters/code_print

其中USERCODE=0xf601的遥控器用户码,用来标识是哪一个遥控器,RMC_GETDATA=bb,这个是遥控器设备linux驱动中对应的按键上报的对应的键值。

文件目录\kernel\arch\arm\boot\dts\xxx.dts

在代码中先添加如下框架(文件里面照葫芦画瓢)(先把usercode这样加上,然后输入上面的命令才能记录相应按键DTS中对应的值):

我这上面是修改好的样子,0xbb和0xbc分别对应的是向上键和确定键。这些都是记录的键值,

<0xbc
KEY_REPLY>, 其中0xbc在DTS文件中确定键对应的宏定义 KEY_REPLY这个要在input.h文件中去找

input.h文件路径:kernel\arch\arm\boot\dts\include\dt-bindings\input\input.h

DTS文件中每一按键的键值都可以通过打印来记录,每一个键值所对应的宏可以通过linux驱动层中input.h文件中对应的宏找到。名字一定要保持一致!其中上面确定键对应的232是linux层上报android层的键值。

就这样记录所有的按键,然后在DTS文件对号入座,第一步遥控器红外层到linux层的键值映射就搞定了

2. Linux层到android层的键值映射

同样通过终端输入命令:getevent 记录Linux层到android层的键值记录

对应的映射文件就是110b0030_pwm.kl 这个是可以在相关配置文件修改确定是哪个KL文件是linux层到android层键值映射,也可以修改为自己创建的KL文件。

文件目录:盒子根文件目录下的/system/usr/keylayout/110b0030_pwm.kl文件

这里232是确定键从Linux层上报到android层的键值,其中确定键对应的宏DPAD_CENTER 这个可以在keyevent.java文件中找到

一般的遥控器常规按键做到这两步了,基本都没问题了,但是特殊按键的添加还需要继续完善!

通常Linux驱动层基本不需要修改,第一步:我们只需要修改对应的KL文件即可。

已遥控器上的搜索按键为例:

由于DTS文件中:

<0xa7
KEY_PROGRAM>  a7是记录的搜索键的键值, 后边对应的宏是input.h文件中可以找到对应的,这个加进去就好了

KL文件中:

key 362   TV_SEARCH    //362是getevent命令记录的搜索键的键值, TV_SEARCH是自定义的宏,这个名字自己可以随便定义。

第二个修改的地方是keycodes.h文件

文件目录:frameworks\native\include\android\keycodes.h

在文件中添加一个没有用到的键值

第三个修改的地方是KeycodeLables.h文件

文件目录:\frameworks\native\include\input\KeycodeLables.h

第四个修改attrs.xml文件

文件目录:\frameworks\base\core\res\res\values\arrrs.xml

第五个修改的文件:KeyEvent.java    (这个文件修改的地方有两个)

如果添加的是最后一个别忘了LAST_KEYCODE 这个要和最后一个保持一致.下面还有一个地方也要添加:

至此特殊按键搜索按键从红键值外层到android层的键值映射就完成了。搜索按键到android应用层的键值映射就是257.

特殊按键应用层特殊处理可以修改PhoneWindowManager.java文件

文件目录:\frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.java

特殊按键处理这次应用层的做法是修改PhoneWindowManager.java文件,同时在上面的目录中添加keyfunction.java文件。

package com.android.internal.policy.impl;

import java.io.IOException;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import java.io.Serializable;

import org.xml.sax.SAXException;
import android.os.Looper;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ContextWrapper;
import android.util.Log;
import android.os.Message;
import android.os.Messenger;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.UserHandle;
import android.media.AudioService;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
//import com.hisilicon.android.HiDisplayManager;
//import com.hisilicon.android.DispFmt;
import android.widget.Toast;
import android.view.KeyEvent;
import android.os.SystemProperties;
import android.content.res.Configuration;
import android.app.ActivityManagerNative;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.pm.PackageInfo;
//import android.view.VGAToast;

public class Keyfunction {
    private static Keyfunction mInstance = null;
    private static final String KEYFUNTIONXLMNAME = "/system/etc/keyfunction.xml";
    private static final int MSG_TO_SET_FORMAT = 111;
    private static Context mContext;
//    private HiDisplayManager mDisplayManager = null;
    private ToastUtil toast = null;
    private String mProduc_name = null;
    private final String TAG = "Keyfunction";

    private boolean is4Cpu = true;
    private static ArrayList<Integer> settingFormatValueList = new ArrayList<Integer>();
    private static ArrayList<String> settingFormatStringList = new ArrayList<String>();

    private File avplay;
    private int[] threeD_ValueList = {19, 20, 21};
    private String[] threeD_StringList = {"1080P 24Hz FramePacking", "720P 60Hz FramePacking", "720P 50Hz FramePacking"};
    private int[] fourK_ValueList = {0x100, 0x101, 0x102, 0x103};
    private String[] fourK_StringList = {"3840X2160 24Hz", "3840X2160 25Hz", "3840X2160 30Hz", "4096X2160 24Hz"};

    private int nCurrentFormat;
    private boolean currFmtInSets = false;
    private int nCurrentFormatIndex;
    private String CurrentFormatIndexString;

    private boolean bEventWasHandled = true;

    private final long TIME_SPACE = 3000;
    private int mScreenCount = 0;
    private Keyfunction(Context context) {
        Log.e(TAG, "-------->Keyfunction <---------");
        showStartMsg = false;
		mContext = context;
		loadKeyFuntion(mContext);
        toast = new ToastUtil();

        mProduc_name = SystemProperties.get("ro.product.device");
        is4Cpu = mProduc_name.substring(0, 5).equals("Hi379")?true:false;
    }
    public static class ToastUtil {

        private static Handler handler = new Handler(Looper.getMainLooper());

        private static Toast toast = null;

        private static Object synObj = new Object();

        public static void showMessage(final Context act, final String msg) {
            showMessage(act, msg, Toast.LENGTH_SHORT);
        }

        public static void showMessage(final Context act, final int msg) {
            showMessage(act, msg, Toast.LENGTH_SHORT);
        }

        public static void showMessage(final Context act, final String msg,
                final int len) {

            handler.post(new Runnable() {
                @Override
                public void run() {
                    synchronized (synObj) {
                        if (toast != null) {
                            // toast.cancel();
                            toast.setText(msg);
                            toast.setDuration(len);
                        } else {
                            toast = Toast.makeText(act, msg, len);
                        }
                        toast.show();
                    }
                }
            });
        }

        public static void showMessage(final Context act, final int msg,
                final int len) {

            handler.post(new Runnable() {
                @Override
                public void run() {
                    synchronized (synObj) {
                        if (toast != null) {
                            // toast.cancel();
                            toast.setText(msg);
                            toast.setDuration(len);
                        } else {
                            toast = Toast.makeText(act, msg, len);
                        }
                        toast.show();
                    }
                }
            });
        }
    }

    private static Keyfunction keyfunction;
	HashMap<String, AppInfoVO> keyFunctionMap = new HashMap<String, Keyfunction.AppInfoVO>();
	private final boolean showStartMsg;

	public static Keyfunction getInstance(Context context) {
		if (keyfunction == null) {
			keyfunction = new Keyfunction(context);
		}
		return keyfunction;
	}

	static int parseToInt(String number) throws Exception {
		int n = -1;
		if (number.startsWith("0x") || number.startsWith("0X")) {
			n = Integer.parseInt(number.substring(2), 16);
		} else {
			n = Integer.parseInt(number);
		}
		return n;
	}

	static int parseToInt(String number, int def) {
		int n = def;
		try {
			n = parseToInt(number);
		} catch (Exception e) {
			return def;
		}
		return n;
	}

	private HashMap<String, AppInfoVO> loadKeyFuntion(Context mContext) {
		File file = null;
		file = new File(KEYFUNTIONXLMNAME);
		if ((!file.exists()) || (!file.canRead())) {
			keyFunctionMap.clear();
			return keyFunctionMap;
		}
		try {
			keyFunctionMap.clear();
			DocumentBuilderFactory xmlparser = DocumentBuilderFactory.newInstance();
			DocumentBuilder xmlDOC;
			Document doc = null;
			xmlDOC = xmlparser.newDocumentBuilder();
			doc = xmlDOC.parse(file);
			if (null == doc)
				return keyFunctionMap;
			NodeList appItems = doc.getElementsByTagName("key");
			for (int i = 0; i < appItems.getLength(); i++) {
				Node appItem = appItems.item(i);
				if (!appItem.hasChildNodes())
					continue;
				String actionType = ((Element) appItem).getAttribute("actionType");

				NodeList appInfoItems = appItem.getChildNodes();
				AppInfoVO appInfo = new AppInfoVO();
				appInfo.actionType = ((actionType == null || actionType.length() == 0) ? AppInfoVO.ACTION_TYPE_ACTIVITY
						: actionType);
				for (int j = 0; j < appInfoItems.getLength(); j++) {
					Node appInfoItem = appInfoItems.item(j);
					String nodeName = appInfoItem.getNodeName();
					String nodeTextContent = appInfoItem.getTextContent();
					if (nodeName.equalsIgnoreCase("keyName")) {
						appInfo.keyName = nodeTextContent;
					} else if (nodeName.equalsIgnoreCase("keyValue")) {
						appInfo.keyValue = nodeTextContent;
					} else if (nodeName.equalsIgnoreCase("packageName")) {
						appInfo.packageName = nodeTextContent;
					} else if (nodeName.equalsIgnoreCase("activityName")) {
						appInfo.activityName = nodeTextContent;
					} else if (nodeName.equalsIgnoreCase("serviceName")) {
						appInfo.serviceName = nodeTextContent;
					} else if (nodeName.equalsIgnoreCase("action")) {
						appInfo.action = nodeTextContent;
					} else if (nodeName.equalsIgnoreCase("flags")) {
						appInfo.flags = parseToInt(nodeTextContent, Intent.FLAG_ACTIVITY_NEW_TASK);
					} else if (nodeName.equalsIgnoreCase("method")) {
						appInfo.method = parseToInt(nodeTextContent, AppInfoVO.METHOD_FOR_INTERCEPT);
					} else if (nodeName.equalsIgnoreCase("extras")) {
						if (!appInfoItem.hasChildNodes())
							continue;
						NodeList appExtraItems = appInfoItem.getChildNodes();
						String isBundle = ((Element) appInfoItem).getAttribute("isBundle");
						appInfo.isExtarsBundle = (isBundle != null && isBundle.length() > 0 && ("true"
								.equalsIgnoreCase(isBundle) || isBundle.charAt(0) == '0'));
						appInfo.extras = new HashMap<String, Object>();
						for (int k = 0; k < appExtraItems.getLength(); k++) {
							Node appExtraItem = appExtraItems.item(k);
							if (!(appExtraItem instanceof Element))
								continue;
							// Log.i(TAG,node.getNodeType());
							String type = ((Element) appExtraItem).getAttribute("type");
							String name = appExtraItem.getNodeName();
							String value = appExtraItem.getTextContent();
							parseExtra(appInfo.extras, type, name, value);
						}
					} else if (nodeName.equalsIgnoreCase("exclude")) {
						if (!appInfoItem.hasChildNodes())
							continue;
						NodeList appExtraItems = appInfoItem.getChildNodes();
						appInfo.excludePackage = new ArrayList<String>();
						appInfo.excludeActivity = new ArrayList<String>();
						for (int k = 0; k < appExtraItems.getLength(); k++) {
							Node appExtraItem = appExtraItems.item(k);
							if (!(appExtraItem instanceof Element))
								continue;
							String name = appExtraItem.getNodeName();
							String value = appExtraItem.getTextContent();
							if (name == null || name.length() == 0 || value == null
									|| value.length() == 0) {
								continue;
							}
							if ("packageName".equalsIgnoreCase(name)) {
								appInfo.excludePackage.add(value);
							} else if ("activityName".equalsIgnoreCase(name)) {
								appInfo.excludeActivity.add(value);
							}
						}
					}
				}
				if (appInfo.checkValid()) {
					appInfo.generatIntent();
					Log.i(TAG, "Got keyfunction :\n" + appInfo);
					keyFunctionMap.put(appInfo.keyValue, appInfo);
				}
			}
		} catch (Exception e) {
			Log.e(TAG, "loadKeyFuntionn fail:", e);
		}
		Log.i(TAG, "Got " + keyFunctionMap.size() + " items from the xml file");
		return keyFunctionMap;
	}

	private HashMap<String, Object> parseExtra(HashMap<String, Object> extra, String type,
			String name, String value) {
		Object v = null;
		// Log.i(TAG,"parseExtra s type:" + type + ";" + name + "=" +
		// value);
		try {
			if ("int".equalsIgnoreCase(type)) {
				v = Integer.parseInt(value);
			} else if ("long".equalsIgnoreCase(type)) {
				v = Long.parseLong(value);
			} else if ("double".equalsIgnoreCase(type)) {
				v = Double.parseDouble(value);
			} else if ("float".equalsIgnoreCase(type)) {
				v = Float.parseFloat(value);
			} else if ("boolean".equalsIgnoreCase(type)) {
				v = Boolean.parseBoolean(value);
			} else if ("string".equalsIgnoreCase(type) || "".endsWith(type)) {
				v = value;
			} else {
				Log.i(TAG, "parseExtra  unknown type:" + type);
				v = null;
			}
		} catch (Exception e) {
			Log.i(TAG, "parseExtra  data error :" + e.getMessage());
			v = null;
		}
		// Log.i(TAG,"parseExtra e type:" + type + ";" + name + "=" +
		// (v != null ? v : null));
		if (v != null)
			extra.put(name, v);
		return extra;
	}

	public AppInfoVO getKeyFunction(int keyValue) {
		return keyFunctionMap.get(String.valueOf(keyValue));
	}

	public AppInfoVO getBeforeUserKeyFunction(int keyValue) {
		AppInfoVO app = getKeyFunction(keyValue);
		if (app == null)
			return null;
		if (app.method == AppInfoVO.METHOD_FOR_INTERCEPT
				|| app.method == AppInfoVO.METHOD_FOR_UNINTERCEPT)
			return app;
		return null;
	}

	public AppInfoVO getUserUnhandledKeyFunction(int keyValue) {
		AppInfoVO app = getKeyFunction(keyValue);
		if (app == null)
			return null;
		if (app.method == AppInfoVO.METHOD_FOR_AFTER_USER_UNHANDLED)
			return app;
		return null;
	}
	public boolean isNeedExcludeOnTopComponent(AppInfoVO app, ComponentName cn) {
		boolean exclude = false;
		if (cn != null && app != null) {
			String pck = cn.getPackageName();
			if (pck != null && pck.length() > 0) {
				exclude = app.isExclucePackage(pck);
			}
			String activityName = cn.getClassName();
			if (!exclude && activityName != null && activityName.length() > 0) {
				if(activityName.equals(app.activityName)){
					exclude = true;
					Log.w(TAG, "is current app!! no need run keyfun");
				}
				if (!activityName.contains("."))
					activityName = pck + "." + activityName;
				if (!exclude)
					exclude = app.isExcluceActivity(activityName);
				if (!exclude)
					exclude = app.isExcluceActivity(pck + "." + cn.getShortClassName());
			}
			if (exclude) {
				Log.w(TAG, "no need run keyfun for:" + cn + " app id:" + app.keyValue + " name:" + app.keyName);
			}
		}
		return exclude;
	}
	/**
	 *
	 * @param app
	 * @return 是否需要拦截
	 */
	public boolean runKeyFunction(AppInfoVO app) {
		boolean needIntercept = false;
		boolean succ = false;
		if (app == null)
			return false;
		if (!keyFunctionMap.containsValue(app))
			return false;
		Log.i(TAG, "runKeyFunction..s app:" + app);
		needIntercept = app.method == AppInfoVO.METHOD_FOR_INTERCEPT;
		Log.i(TAG, "runKeyFunction..needIntercept=" + needIntercept);
		Intent intent = app.getStartIntent();
		try {
			if (intent != null) {
				// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				if (AppInfoVO.ACTION_TYPE_ACTIVITY.equalsIgnoreCase(app.actionType)) {
					if (showStartMsg)
						ToastUtil.showMessage(mContext, "startActivity for " + app.keyName + ":"
								+ app.keyValue + "\n" + intent.getComponent());
					mContext.startActivity(intent);
					succ = true;
				} else if (AppInfoVO.ACTION_TYPE_SERVICE.equalsIgnoreCase(app.actionType)) {
					if (showStartMsg)
						ToastUtil.showMessage(mContext, "startService for " + app.keyName + ":"
								+ app.keyValue + "\n" + intent.getComponent());
					ComponentName t = mContext.startService(intent);
					if (t != null)
						succ = true;
				} else if (AppInfoVO.ACTION_TYPE_BOADCAST.equalsIgnoreCase(app.actionType)) {
					if (showStartMsg)
						ToastUtil.showMessage(mContext, "sendBroadcast for " + app.keyName + ":"
								+ app.keyValue + "\n" + intent);
					mContext.sendBroadcast(intent);
					succ = true;
				} else {
					Log.e(TAG, "runKeyFunction unknow intent action");
				}
			}
		} catch (Exception e) {
			succ = false;
			Log.e(TAG, "runKeyFunction fail:", e);
		}
		Log.i(TAG, "runKeyFunction..e succ=" + succ);

		return succ && needIntercept;
	}

	class AppInfoVO {
		public AppInfoVO() {
		}

		public static final String ACTION_TYPE_ACTIVITY = "activity";
		public static final String ACTION_TYPE_SERVICE = "service";
		public static final String ACTION_TYPE_BOADCAST = "broadcast";

		public static final int METHOD_FOR_INTERCEPT = 0;
		public static final int METHOD_FOR_UNINTERCEPT = 1;
		public static final int METHOD_FOR_AFTER_USER_UNHANDLED = 2;

		public boolean checkStringValid(String s) {
			return s != null && s.length() > 0;
		}

		public boolean checkActivity() {
			return ((ACTION_TYPE_ACTIVITY.equalsIgnoreCase(actionType)) && (checkStringValid(action) || (checkStringValid(packageName) && checkStringValid(activityName))));
		}

		public boolean checkService() {
			return ((ACTION_TYPE_SERVICE.equalsIgnoreCase(actionType)) && (checkStringValid(action) || (checkStringValid(packageName) && checkStringValid(activityName))));
		}

		public boolean checkBroadcast() {
			return ((ACTION_TYPE_BOADCAST.equalsIgnoreCase(actionType)) && (checkStringValid(action)));
		}

		public boolean checkValid() {
			boolean succ = checkStringValid(keyValue);
			succ = succ && (checkActivity() || checkService() || checkBroadcast());
			return succ;
		}

		public Intent getStartIntent() {
			return intent;
		}

		public boolean isExclucePackage(String pck) {
			return excludePackage != null && excludePackage.contains(pck);
		}

		public boolean isExcluceActivity(String a) {
			return excludeActivity != null && excludeActivity.contains(a);
		}

		private void addIntentExtras(Intent intent, HashMap<String, Object> extra) {
			if (extra == null || extra.size() <= 0)
				return;
			for (String key : extra.keySet()) {
				Object value = extra.get(key);
				Log.i(TAG, "key=" + key + ";value=" + value);
				if (value != null && value instanceof Serializable) {
					Log.i(TAG, "add extra:" + key + "=" + value);
					intent.putExtra(key, (Serializable) value);
				}
			}
		}

		public Intent generatIntent() {
			if (intent != null)
				return intent;
			intent = new Intent();
			if (action != null && action.length() > 0) {
				intent.setAction(action);
			}
			intent.addFlags(flags);
			if (ACTION_TYPE_ACTIVITY.equalsIgnoreCase(actionType)) {
				if (checkStringValid(packageName) && checkStringValid(activityName))
					intent.setClassName(packageName, activityName);
			} else if (ACTION_TYPE_SERVICE.equalsIgnoreCase(actionType)) {
				if (checkStringValid(packageName) && checkStringValid(activityName))
					intent.setClassName(packageName, serviceName);
			} else if (ACTION_TYPE_BOADCAST.equalsIgnoreCase(actionType)) {
				// TODO
			}
			if (isExtarsBundle) {
				// TODO
			} else {
				addIntentExtras(intent, extras);
			}
			return intent;
		}

		@Override
		public String toString() {
			StringBuilder sb = new StringBuilder();
			sb.append("{{keyValue:" + keyValue + "};");
			sb.append("{keyName:" + keyName + "};");
			sb.append("{actionType:" + actionType + "};");
			sb.append("{flags:0x" + Integer.toHexString(flags) + "};");
			sb.append("{method:" + method + "};");
			sb.append("{action:" + action + "};");
			sb.append("{packageName:" + packageName + "};");
			sb.append("{activityName:" + activityName + "};");
			sb.append("{serviceName:" + serviceName + "};");
			sb.append("{extras:" + extras + "};");
			sb.append("{excludePackage:" + excludePackage + "};");
			sb.append("{excludeActivity:" + excludeActivity + "};");
			sb.append("{intent:" + intent + "}}");
			return sb.toString();
		}

		public String actionType = ACTION_TYPE_ACTIVITY;// TODO
		public int flags = Intent.FLAG_ACTIVITY_NEW_TASK;
		public int method = METHOD_FOR_INTERCEPT;
		public boolean isExtarsBundle = false;
		public String keyValue;
		public String keyName;
		public String packageName;
		public String action;
		public String activityName;
		public String serviceName;
		public HashMap<String, Object> extras;
		public ArrayList<String> excludePackage;
		public ArrayList<String> excludeActivity;
		public Intent intent;
	}
    public void readSwitch() {

    }

    private Handler FMThandler = new Handler() {
        public void handleMessage(Message msg) {
            int i = 0;
            switch (msg.what) {
            case MSG_TO_SET_FORMAT:
                Log.e(TAG, "receive MSG_TO_SET_FORMAT msg");
                for (i = 0; i < settingFormatValueList.size(); i++) {
                    if (settingFormatValueList.get(i) == nCurrentFormat) {
                        break;
                    }
                }
                Log.e(TAG, "nCurrentFormatIndex: "+nCurrentFormatIndex);
                Log.e(TAG, "settingFormatValueList.get(nCurrentFormatIndex): "+settingFormatValueList.get(nCurrentFormatIndex));
                if(nCurrentFormatIndex != i)
                {
//                    mDisplayManager.setFmt(settingFormatValueList.get(nCurrentFormatIndex));
//                    mDisplayManager.SaveParam();
//                    mDisplayManager.setOptimalFormatEnable(0);

                    Intent in = new Intent("com.hisilicon.intent.action.ACTION_FORMAT_CHANGED");
                    mContext.sendBroadcastAsUser(in, UserHandle.ALL);
                }
                bEventWasHandled = true;
                break;
            case 1:

            }
            super.handleMessage(msg);
        }

    };
    public void keyToResolution() {
//	mDisplayManager = new HiDisplayManager();
	FMThandler.removeMessages(1);
	Message message = new Message();
	message.what = 1;
	FMThandler.sendMessage(message);
   }
    public void keySwitchFormat() {
        FMThandler.removeMessages(MSG_TO_SET_FORMAT);

//        mDisplayManager = new HiDisplayManager();
        Message message = new Message();
//        nCurrentFormat = mDisplayManager.getFmt();
        getDisplayFormatList();
        int i;

        Log.e(TAG, "current format is: "+nCurrentFormat);
        Log.e(TAG, "bEventWasHandled is: "+bEventWasHandled);
        if(bEventWasHandled)
        {
            for (i = 0; i < settingFormatValueList.size(); i++)
            {
                if (settingFormatValueList.get(i) == nCurrentFormat)
                {
                    nCurrentFormatIndex = i;
                    currFmtInSets = true;
                    break;
                }
                else
                {
                    currFmtInSets = false;
                    nCurrentFormatIndex = 0;
                }
             }
         }
         else
         {
             currFmtInSets = true;
             nCurrentFormatIndex = (nCurrentFormatIndex + 1)%settingFormatValueList.size();
         }
         Log.e(TAG, "currFmtInSets is: "+currFmtInSets);
         Log.e(TAG, "nCurrentFormatIndex is: "+nCurrentFormatIndex);

         if(currFmtInSets)
         {
             bEventWasHandled = false;
             CurrentFormatIndexString = settingFormatStringList.get(nCurrentFormatIndex);
             toast.showMessage(mContext, CurrentFormatIndexString, Toast.LENGTH_LONG);

             message.what = MSG_TO_SET_FORMAT;
             FMThandler.sendMessageDelayed(message, TIME_SPACE);
         }
         else
         {
             //3d format case
             for (i = 0; i < threeD_ValueList.length; i++)
             {
                 if (threeD_ValueList[i] == nCurrentFormat)
                 {
                    Log.e(TAG, "3d format case");
                    toast.showMessage(mContext, threeD_StringList[i], Toast.LENGTH_SHORT);
                    avplay = new File("/proc/msp/avplay00");
                    if (!avplay.exists()) {
                        Log.e(TAG, "no active avplay");
                        //switch format
                        message.what = MSG_TO_SET_FORMAT;
                        FMThandler.sendMessageDelayed(message, TIME_SPACE);
                    }
                    return;
                 }
             }

             //4k format case
             for (i = 0; i < fourK_ValueList.length; i++)
             {
                 if (fourK_ValueList[i] == nCurrentFormat)
                 {
                    Log.e(TAG, "4k format case");
                    toast.showMessage(mContext, fourK_StringList[i], Toast.LENGTH_SHORT);
                    //switch format
                    message.what = MSG_TO_SET_FORMAT;
                    FMThandler.sendMessageDelayed(message, TIME_SPACE);
                    return;
                 }
             }

         }
    }

    public void getDisplayFormatList()
    {

    }

}

同时在盒子根目录下的/system/etc目录下添加keyfunction.xml配置文件。

<?xml version="1.0" encoding="utf-8"?>
<Applications>
<!--	<key>
		<keyName>VOD_SEARCH</keyName>
		<keyValue>84</keyValue>
		<packageName>com.ipanel.portal</packageName>
		<activityName>com.ipanel.portal.IPanel30PortalActivity</activityName>
		<action>android.intent.action.MAIN</action>
		<method>0</method>
		<flags>0x14008000</flags>
		<extras>
			<url type="string">http://vod.fjgdwl.com:80/gldb/NEW_UI/search/search_2.htm</url>
		</extras>
		<exclude>
			<packageName>com.ipanel.join.live.fj</packageName>
			<activityName>com.ipanel.portal.IPanel30PortalActivity</activityName>
		</exclude>
	</key>

	<key>
		<keyName>Huikan</keyName>
		<keyValue>67</keyValue>
		<packageName>com.ipanel.portal</packageName>
		<activityName>com.ipanel.portal.IPanel30PortalActivity</activityName>
		<action>android.intent.action.MAIN</action>
		<method>1</method>
		<flags>0x14008000</flags>
		<exclude>
			<packageName>com.ipanel.portal</packageName>
		</exclude>
		<extras>
			<url type="string">http://vod.fjgdwl.com:80/gldb/NEW_UI/lookBack/list.htm?typePos=0</url>
		</extras>
	</key>
-->

	<key>
		<keyName>>Huikan</keyName>
		<keyValue>275</keyValue>
		<packageName>com.ipanel.join.vod.fj</packageName>
        	<activityName>com.ipanel.join.vod.ui.BTVChannelListActivity</activityName>
		<action>android.intent.action.MAIN</action>
		<method>0</method>
		<flags>0x14008000 </flags>
	</key>	

	<key>
		<keyName>SEARCH</keyName>
		<keyValue>257</keyValue>
		<packageName>com.ipanel.join.vod.fj</packageName>
        	<activityName>com.ipanel.join.vod.fj.SearchActionActivity</activityName>
		<action>android.intent.action.MAIN</action>
		<method>0</method>
		<flags>0x14008000 </flags>
		<exclude>
			<packageName>com.ipanel.join.live.fj</packageName>
		</exclude>
	</key>	

	<key>
		<keyName>HD</keyName>
		<keyValue>170</keyValue>
		<packageName>com.ipanel.join.live.fj</packageName>
		<activityName>com.jiangxi.apps.nclive.LiveActivity</activityName>
		<action>android.intent.action.MAIN</action>
		<flags>0x10200000</flags>
		<extras>
  		<bouquet type="string">815</bouquet>
 			<live_show_epg type="boolean">true</live_show_epg>
		</extras>
	</key>

	<key>
		<keyName>Love</keyName>
		<keyValue>256</keyValue>
		<packageName>com.ipanel.join.live.fj</packageName>
		<activityName>com.jiangxi.apps.nclive.LiveActivity</activityName>
		<action>android.intent.action.MAIN</action>
		<flags>0x10200000</flags>
		<extras>
  		<bouquet type="string">2147483627</bouquet>
 			<live_show_epg type="boolean">true</live_show_epg>
		</extras>
	</key>

	<key>
		<keyName>Settings</keyName>
		<keyValue>176</keyValue>
		<packageName>com.ipanel.join.cq.settings</packageName>
        	<activityName>com.ipanel.join.cq.settings.SettingActivity</activityName>
		<action>android.intent.action.MAIN</action>
	</key>

	<key>
		<keyName>Email</keyName>
		<keyValue>65</keyValue>
		<packageName>com.ipanel.join.cq.settings</packageName>
        	<activityName>com.ipanel.join.cq.settings.activity.MailListActivity</activityName>
		<action>android.intent.action.MAIN</action>
	</key>

	<key>
		<keyName>HiPQSetting</keyName>
		<keyValue>1185</keyValue>
		<packageName>com.hisilicon.android.pqsetting</packageName>
		<serviceName>com.hisilicon.android.pqsetting.MainService</serviceName>
		<action>android.intent.action.MAIN</action>
	</key>

</Applications>

至此搜索按键从红外层到应用层的映射一直到安卓应用层的处理就全部完毕。这里搜索按键是跳到特殊的APP应用界面。

时间: 2024-10-19 15:32:12

RK平台Android4.4 添加一个新的遥控器支持以及添加特殊按键的相关文章

不能因为为了添加一个新功能,影响到旧的功能

涉及到后台的, 一般都是要跟数据库打交道的大型数据量的处理问题.以类 client - server 为基础的架构, 或者变形后的架构. 客户端处理用户的输入和数据, 然后大量的客户端(多个客户端的多种数据) 反馈到服务端统一处理和协调, 然后服务端对客户端发出相应的指令.其中 后台程序 代表的就是服务端的程序. 包含以下几点:1. 网络通信,  要跟远程的client打交道,只能用网络2. 并发 和 并行处理.0.. 多个客户端可能在同一时间同时需要处理同一个类型的数据, 谁先谁后,谁的有效谁

jquery如何在li元素列表的开头添加一个新li元素

jquery如何在li元素列表的开头添加一个新li元素:本章节介绍一下如何在li元素列表的开头添加一个li元素,大家最为习惯的是使用append()函数在li元素列表后面追加一个新的li元素,下面就通过代码实例介绍一下如何实现在前面添加一个新的li元素.代码如下: <!DOCTYPE html><html> <head> <meta charset=" utf-8"> <meta name="author" co

为对象添加一个新的方法

例定义一个方法,为Date对象添加一个新的成员方法,转换为形如 y-m-d<br>h:m:s Date.prototype.stringify = function(){ var s= this.getFullYear()+'-'; s+= (this.getMonth()+1)+'-'; s+= this.getDate()+' '; s+= this.getHours()+':'; s+= this.getMinutes()+':'; s+= this.getSeconds(); retu

Flink资料(6) -- 如何添加一个新的Operator

false false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-parent:""; mso-padding-alt

wince7下如何添加一个新的驱动程序

在wince7中添加一个新驱动程序的步骤:(以一个简单的led驱动为例) 1.在Solution Explorer窗口中右击platform\ZYNQ7000\src\DRIVERS目录,然后选择Add->New Sources Subproject,在弹出的Subproject Wizard对话框中选择WCE Dynamic-Link Library,并将Subproject name设置为LED.点击Next并选择An empty subproject,点击Next 并选择Add to th

Python编译器实现内幕:添加一个新语句

Python编译器实现内幕:添加一个新语句 本文尝试理解Python前端的编译实现内幕,如果仅仅是读取文档,或者查看Python的实现代码,会让人感觉迷迷糊糊的,所以我的想法是动手来做一些事情:添加一个新语句until到Python编译器实现里. 所有跟本文相关的代码,都是使用Python3.4.3版本的代码,可以从CSDN的代码托管里找到,连接如下: https://code.csdn.net/caimouse/milang/tree/master 打开上面连接下载代码,就是简单直接打包下载,

012.Adding a New Field --【添加一个新字段】

Adding a New Field 添加一个新字段 2016-10-14 3 分钟阅读时长 作者 By Rick Anderson In this section you'll use Entity Framework Code First Migrations to add a new field to the model and migrate that change to the database. 在本节,我们将用EF的Code First 增加一个新字段并变更到数据库中. When

jquery如何添加一个新的元素节点

jquery如何添加一个新的元素节点: 在原生的javascript中,可以使用creatElement()函数创建一个元素节点,下面介绍一下如何用jquery创建一个元素节点. 代码如下: <script type="text/javascript"> $(function(){ $(".wrap").append("<p>蚂蚁部落</p>"); }) </script> </head>

动态数组,数组初始化,数组内存释放,向数组中添加一个元素,向数组中添加多个元素,数组打印,顺序查找,二分查找,查找数组并返回地址,冒泡排序,改变数组中某个元素的值,删除一个数值,删除所有,查找含有

 1定义接口: Num.h #ifndef_NUM_H_ #define_NUM_H_ #include<stdio.h> #include<stdlib.h> /************************************************************************/ /*数组的结构体类型                                                    */ /*******************