Android5.1 FrameWork添加自己的SystemService提供API给APP

   FrameWork从纵向来看主要就是添加Service并且利用JNI调用HAL层C/C++的代码来实现提供API给APP操作硬件的目的

   本文就是描述在Android5.1如何实现添加自己的System Service来实现跟HAL进行Socket通信

   一:首先先描述如何注册自己的SystemService并且实现自己的AIDL,我们这部分要实现的目标是在APP通过调用  (InfraredManager)context.getSystemService(Context.XXX)            提供API,实现InfraredManager步骤如下

      1:将Binder的"客户端"部分实现在\frameworks\base\core\java\com\android\infrared\InfraredManager.java 同时创建 \frameworks\base\core\java\com\yuekong\infrared\InfraredReceptionManager.aidl

      AIDL就是Binder调用的接口

package com.android.infrared;
import com.android.infrared.IOnInfraredReceivedListener;
import java.lang.String;
/**
 * Binder interface that clients running in application context
 * can use to interface with remote service
 */
interface InfraredReceptionManager {
    void sendStartLearnMsg();
	void sendLearnMsg();
	void sendStopLearnMsg();
	void sendInfo(in String info);
	void addInfraredReceivedListener(in IOnInfraredReceivedListener listener);
        void removeInfraredReceivedListener(in IOnInfraredReceivedListener listener);
}

 2:binder接口创建好后,实现"服务端"的service  在\frameworks\base\services\core\java\com\yuekong\infrared\InfraredManagerService

package com.android.infrared;

import android.content.Context;
import android.widget.Toast;
import android.os.IBinder;
import com.android.server.SystemService;
import com.android.infrared.IOnInfraredReceivedListener;
import android.os.RemoteCallbackList;
import android.os.Binder;
import com.android.infrared.InfraredSocketClient.OnReceivedInfraredListener;
import android.os.RemoteException;

public class InfraredManagerService extends SystemService implements OnReceivedInfraredListener {
	
	private static final String TAG = "InfraredManagerService";
	
	private final Context mContext;
	private InfraredSocketClient mClient = null;
	private RemoteCallbackList<IOnInfraredReceivedListener> mListenersList = new  RemoteCallbackList<IOnInfraredReceivedListener>();
	
	public InfraredManagerService(Context context){
		super(context);
		mContext = context;
		publishBinderService(context.INFRARED_SERVICE, mService);
	}
	
	/**
     * Implementation of AIDL service interface
     */
    private final IBinder mService = new InfraredReceptionManager.Stub() {
		@Override
        public void sendStartLearnMsg() {
			getSocketInstance().sendSocket(CommandConstant.Command_Learn_Start);
        }
		@Override
        public void sendLearnMsg() {
			getSocketInstance().sendSocket(CommandConstant.Command_Learn_Key);
        }
		@Override
        public void sendStopLearnMsg() {
			getSocketInstance().sendSocket(CommandConstant.Command_Learn_Stop);
        }
		@Override
        public void sendInfo(String info) {
			getSocketInstance().sendSocket(info);
			Xlog.w(TAG, "stop learn mode");
        }
		
		@Override
		public void addInfraredReceivedListener(IOnInfraredReceivedListener listener){
			if(listener == null){
				return;
			}
			synchronized(mListenersList){
                mListenersList.register(listener, Binder.getCallingUserHandle());
			}
		}
		@Override
        public void removeInfraredReceivedListener(IOnInfraredReceivedListener listener){
			if(listener == null){
				return;
			}
			synchronized(mListenersList){
				mListenersList.unregister(listener);
			}		
		}
		
    };

	 /**
     * Called when service is started by the main system service
     */
    @Override
    public void onStart() {
       Xlog.d(TAG, "Service start");
	   getSocketInstance().startConnection();
	   getSocketInstance().setInfraredReceivedListener(InfraredManagerService.this);
	
    }
	
	@Override
	public void onReceivedInfraredInfo(int mode,boolean success, int[] info){
		final int size = mListenersList.beginBroadcast();
        for (int i = 0; i < size; i++) {
            IOnInfraredReceivedListener listener = mListenersList.getBroadcastItem(i);
            try {
				Xlog.d(TAG, "binder listener call back" + listener.toString());
                listener.onInfraredReceived(mode,success, info);
            } catch (RemoteException re) {
                Xlog.d(TAG, "Callback failed ");
            }
	    }
		mListenersList.finishBroadcast();
	}

    private InfraredSocketClient getSocketInstance(){
		if(mClient == null){
			mClient = new InfraredSocketClient();
		}
		return mClient;
    }
	
}


  3:我们在调用SystemService的时候都会用context.getSystemService实现调用,然后我们实现自己的Manager给App调用

      

package com.android.infrared;

import com.android.infrared.InfraredReceptionManager;
import android.content.Context;
import android.os.RemoteException;
import java.util.ArrayList;
import java.util.List;

public class InfraredManager{
	private static final String TAG = "InfraredManager";
	private final Context mContext;
	
	private final InfraredReceptionManager mService;
	private List<InfraredReceiverListener> mCallBackList = new ArrayList<InfraredReceiverListener>();
	private IOnInfraredReceivedListener.Stub mInfraredReceivedListener;

	public InfraredManager(Context context,InfraredReceptionManager service ){
		this.mContext = context;
		this.mService = service;
	}
    public void sendStartLearnMsg() {
	     try{
		   if(mService != null){
			mService.sendStartLearnMsg();
		   }      
        } catch (RemoteException ex){
        }
    }
	public void sendLearnMsg(){
		try{
		   if(mService != null){
			mService.sendLearnMsg();  
		   }  
        } catch (RemoteException ex){
        }
	}
	
	public void sendStopLearnMsg() {
	    try{
		   if(mService != null){
			mService.sendStopLearnMsg();  
		   }  
        } catch (RemoteException ex){
        }
	}
	public void sendInfo(String info){
		try{
           mService.sendInfo(info);
        } catch (RemoteException ex){
        }
	}
	
	public void registerListerner(InfraredReceiverListener listener){
		synchronized(this){
			if(mCallBackList != null && listener != null && !callBackContain(mCallBackList,listener)){
				mCallBackList.add(listener);
				boolean addedFirstCallback = (mCallBackList.size() == 1);
				if(addedFirstCallback){
				  try {
                      mService.addInfraredReceivedListener(getInstance());
                    } catch (RemoteException re) {                    
					
					}

				}

			}
		}
	}

	private boolean callBackContain( List<InfraredReceiverListener> callBackList,InfraredReceiverListener listener){

		if( callBackList.size() == 0 ){
           return false;
		}
		for(int i = 0 ; i < callBackList.size(); i++ ){

			Xlog.d(TAG, "register listener has this : " +listener.toString());
			if(callBackList.get(i) == listener ){

                 return true;
			}

		}

       return false;
	}
	
	
    public void unregisterListener(InfraredReceiverListener listener) {
		 if(listener == null){
			 return;
		 }
		 synchronized (this) {
          final int size = mCallBackList.size();
          for (int i = 0; i < size; ++i) {
            if (mCallBackList.get(i) == listener) {
				Xlog.d(TAG, "unregister listener :" +listener.toString());
                mCallBackList.remove(i);
				Xlog.d(TAG, "after unregieter size :" + mCallBackList.size());
               return;
            }
           }

		  if(mCallBackList.size() == 0 && mInfraredReceivedListener != null){
		  	  try{
              mService.removeInfraredReceivedListener(mInfraredReceivedListener);
		  	  }catch(RemoteException re){

		  	  
		  	  }
			  Xlog.d(TAG, "unregister binder listener :" +mInfraredReceivedListener.toString());
			  mInfraredReceivedListener = null;
		  }
		  
        }
	}

	
	
	
	public static abstract class InfraredReceiverListener{
		abstract public void onInfraredReceived(int mode,boolean isSuccess,int[] info);
		
	}


   private IOnInfraredReceivedListener.Stub getInstance(){
     if(mInfraredReceivedListener == null){

	 	mInfraredReceivedListener =  new IOnInfraredReceivedListener.Stub() {
		@Override
		public void onInfraredReceived(int mode,boolean isSuccess,int[] info){
			  synchronized (InfraredManager.this) {
                for (UCONInfraredReceiverListener listener : mCallBackList) {
				  Xlog.d(TAG, "start call back listener " + listener.toString());
                  listener.onInfraredReceived(mode,isSuccess,info);
                }
			  }
			}
     	};
     	}
     Xlog.d(TAG, "create binder listener name is " + mInfraredReceivedListener.toString());
	 return mInfraredReceivedListener;
   	}


	
	
	
}



4:这边Binder的客户端和服务端实现结束,还要在系统的ServiceManager注册自己的SystemService   在 frameworks/base/core/java/android/app/ContextImpl.java

        //add by zhongqi.shao on 2016-08-05 start
        registerService(INFRARED_SERVICE, new ServiceFetcher() {
            public Object createService(ContextImpl ctx) {
                IBinder b = ServiceManager.getService(INFRARED_SERVICE);
                InfraredReceptionManager uconInfraredService =
                        InfraredReceptionManager.Stub.asInterface(b);
                if (InfraredService != null) {
                    return new InfraredManager(ctx,InfraredService);
                } else {
                    // not supported
                    return null;
                }
            }
        });
        //add by zhongqi.shao on 2016-08-05 end
</pre><pre code_snippet_id="1978267" snippet_file_name="blog_20161110_6_4875789" name="code" class="java">这一步就可以实现在framework添加自己的SystemService


    



   

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值