Android系统设置通用接口的编写

Android系统设置通用接口的编写

       作为一个Android系统和系统级应开发工程师,我不得不吐槽每次换到一个新平台就不得花大量的时间来修改我们开发的公版Android系统设置中的代码,为什么不能开发一套所有平台都通用的公版Android系统设置呢。这其中的原因吗,主要是因为不同平台对底层硬件的操作接口不相同有关,这其中主要是对分辨率和OSD层的设置的接口不同,像对于WIFI和语言的相关设置由于Android统一了接口就不必那么的麻烦了。
      很不幸的,编写Android系统设置通用接口的任务落在了我的头上。经过几天的思考我这里想到了一个方法就是定义一套通用的服务将底层对于系统分辨率和OSD的操作封装在该服务中,上层系统应用的开发就不必关心Android底层怎么操作的了,只要调用我们注册的服务就可以了,下面就是我编写的系统设置中修改分辨率和OSD层的代码,这里并没有将底层对于分辨率和OSD层的修改编写出来,因为每个平台不同吗。同时应用开发工程师也不需要关注这些细节。
      如果对于我上树的描述还不清楚的话,用一句话总结就是在Android系统中添加一个系统级服务统一相关的接口(对分辨率和OSD层等的设置),以后应用开发人员无论是什么平台的情况下都可以调用该服务的相关方法,至于是在什么平台下面应用开发人员就不需要关心了(就将这些方法看成Android SDK相关的API就可以了)。接下来我以设置分辨率作为实例来描写。

     详细步骤如下:

1在frameworks/base/core/java/android/app/添加一个aidl的接口定义文件ICoshipManager.aidl,该文件主要是定义了设置和获取分辨率的接口
package android.app;
interface ICoshipManager {
	void	setHDMIResolution(in int index);//设置分辨率
	int		getHdmiResolution();            //获取当前系统分辨率
}

2.在frameworks/base/core/java/android/app/添加一个CoshipManager.java,该文件的作用是提供Android系统层服务接口给应用开发工程师调用用来实现Android系统设置得共功能,其代码如下所示:
package android.app;

import android.content.Context;
import android.content.res.Configuration;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.app.ICoshipManager;

import android.hardware.display.WifiDisplayStatus;
import android.hardware.display.DisplayManager;
import android.net.wifi.p2p.WifiP2pManager;
import android.view.Surface;
import android.content.Intent;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerGlobal;


/** @hide */
public class CoshipManager {
	private static final String TAG = "CoshipManager";

	private ICoshipManager mService;

	/** @hide */
	public CoshipManager() {
		mService = ICoshipManager.Stub.asInterface(ServiceManager.getService("coshipcfg"));
		if (mService != null) {
			Log.e(TAG, "get coship manager service OK");
		} else {
			Log.e(TAG, "get coship manager service NG");
		}
	}

	public void setHDMIResolution(int res) {
		if (mService != null) {
			try {
				mService.setHDMIResolution(res);
			} catch (RemoteException e) {
				Log.e(TAG, "setResolution: RemoteException", e);
			}
		}
	}

	public  int getHdmiResolution(){
		int mResolution = 0;
		if (mService != null) {
			try {
				mResolution = mService.getHdmiResolution();
			} catch (RemoteException e) {
				Log.e(TAG, "getResolution: RemoteException", e);
			}
		}
		return mResolution;
	}

	
	
}


3.在framew//base/services/java/com/android/server/下添加文件CoshipManagerService.java,该文件才是Android中真正的实现系统分辨率设置得地方,其代码如下所示:

package com.android.server;

import android.app.Activity;
import android.app.ActivityManagerNative;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.BatteryManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.Slog;
import android.util.Log;
import android.provider.Settings.SettingNotFoundException;
import android.provider.Settings;
import android.app.CoshipManager;
import android.app.ICoshipManager;
import android.view.SurfaceControl;
import android.view.SurfaceView;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.EnumMap;
import java.util.EnumSet;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Properties;
import java.util.StringTokenizer;

import com.mediatek.common.hdmi.IMtkHdmiManager;
import android.content.ContentResolver;
import android.os.UserHandle;

import android.hardware.display.DisplayManager;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.view.Surface;
import android.hardware.display.WifiDisplayStatus;



class CoshipManagerService extends ICoshipManager.Stub {

	private static final String TAG = "<CoshipManagerService>";
	private final Context mContext;
	final Object mLock = new Object();

	private static final int HDMI_RESOLUTION_AUTO = 100;
	private static final int HDMI_VIDEO_RESOLUTION_DEFAULT = 100;
	private IMtkHdmiManager mHdmiManager;
	private final ContentResolver mContentResolver;
	private int[] supportedResolutions = { HDMI_RESOLUTION_AUTO };

	public CoshipManagerService(Context context) {
		mContext = context;
		ServiceManager.addService("coshipcfg", this);

		mHdmiManager = IMtkHdmiManager.Stub.asInterface(ServiceManager.getService(Context.MTK_HDMI_SERVICE));
        if (null == mHdmiManager) {
			Slog.e(TAG, "get Hdmi Manager failure");
        }
		mContentResolver = mContext.getContentResolver();

		try {
		    supportedResolutions = mHdmiManager.getSupportedResolutions();
		} catch (RemoteException e) {
			Slog.w(TAG, "hdmi manager RemoteException: " + e.getMessage());
		}
	}

	public void init(){
	}

	public  void setHDMIResolution(int res) {
		Slog.e("wangshengjie", "setHDMIResolution " + res);

		int scaleValue = transUIHdmiIndex2System(res);
		if(scaleValue == -1 || scaleValue > supportedResolutions.length)
		{
			Slog.e(TAG, "Hdmi Resolutions error ");
			return;
		}
		Slog.e(TAG, "mHdmiManager.setVideoScale " + scaleValue);
		try {
			mHdmiManager.setVideoResolution(supportedResolutions[scaleValue]);
		} catch (RemoteException e) {
			Slog.w(TAG, "hdmi manager RemoteException: " + e.getMessage());
		}
	}

	public int getHdmiResolution() throws RemoteException {
		int mHdmiVideoResolution = -1;

		int mHdmiVideoResolutionLast = Settings.System.getIntForUser(mContentResolver,
						Settings.System.HDMI_VIDEO_RESOLUTION,
						HDMI_VIDEO_RESOLUTION_DEFAULT, UserHandle.USER_CURRENT);

		for(int i = 0; i < supportedResolutions.length; ++i) {
			if(supportedResolutions[i] == mHdmiVideoResolutionLast) {
				mHdmiVideoResolution = i;
				break;
			}
		}
		Slog.i(TAG, "getHdmiResolution " + mHdmiVideoResolution);

		int uiHdmiIndex = transSystemHdmiIndex2UI(mHdmiVideoResolution);

		Slog.i(TAG, "getHdmiResolution " + uiHdmiIndex);
		return uiHdmiIndex;
	}

	private int transUIHdmiIndex2System(int uiHdmiIndex)
	{
		int systemIndex = -1;
		if(uiHdmiIndex > 6 || uiHdmiIndex < 0)
		{
			Slog.e(TAG, "not support Hdmi Resolutions");
			return systemIndex;
		}
		switch(uiHdmiIndex)
		{
		case 0: systemIndex = 6; break;
		case 1: systemIndex = 9; break;
		case 2: systemIndex = 4; break;
		case 3: systemIndex = 5; break;
		case 4: systemIndex = 2; break;
		case 5: systemIndex = 3; break;
		case 6: systemIndex = 0; break;
		}

		return systemIndex;
	}

	private int transSystemHdmiIndex2UI(int systemHdmiIndex)
	{
		//System 1080p_60hz, 1080p_50hz, 1080i_60hz, 1080i_50hz, 720p_60hz, 720p_50hz, 480p, 576p
		//UI 480p, 576i, 720p_60hz, 720p_50hz, 1080i_60hz, 1080i_50hz, 1080p_60hz
		int uiHdmiIndex = -1;
		//Slog.i(TAG, "supportedResolutions " + supportedResolutions);
		if(systemHdmiIndex > 7 || systemHdmiIndex < 0)
		{
			Slog.e(TAG, "not support Hdmi Resolutions");
			return uiHdmiIndex;
		}

		switch(systemHdmiIndex)
		{
		case 6: uiHdmiIndex = 0; break;
		case 9: uiHdmiIndex = 1; break;
		case 4: uiHdmiIndex = 2; break;
		case 5: uiHdmiIndex = 3; break;
		case 2: uiHdmiIndex = 4; break;
		case 3: uiHdmiIndex = 5; break;
		case 0: uiHdmiIndex = 6; break;
		}

		return uiHdmiIndex;
	}


	void systemReady() {
		synchronized (mLock) {

		}
	}


}

      总结:

        上述的代码只是以设置分辨率举例,至于其它的相关通用的系统设置得接口也可以按照相同的方式来定义,这样以后应用开发的工程师就不必关心不同平台的相关情况了,这样就能做到一套系统设置能适应多个平台了。以后应用开发工程师就只需像使用普通的API一样调用相关的函数来进行系统相关设置了。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值