需求:android下写的 native C 发送消息。
android service 程序接受消息,并根据消息的类别模拟鼠标事件。
需求限制:native C 是个独立的程序。
andriod 服务也是个独立的服务。
思路:在 native C 程序和android服务之间建立socket链接,使用socket 链接进行通信。
-----------------------------------------------------------------------------------网上的资源,在此备份-------------------------------------------------------------------------------------------------
<pre name="code" class="html">方式一:java做服务器端,native做client端 1. 建立java应用程序,建立Server 类 <pre name="code" class="html">/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.hellojni; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.net.LocalServerSocket; import android.net.LocalSocket; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; public class HelloJni extends Activity { public static final String SOCKET_NAME = "server_test"; private static final String TAG = "SocketService"; private LocalServerSocket mServerSocket = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.v(TAG, "onCreate"); try { mServerSocket = new LocalServerSocket(SOCKET_NAME); } catch (IOException e) { Log.v(TAG, "in onCreate, making server socket: " + e); return; } Thread t = new Thread() { @Override public void run() { LocalSocket socket = null; while (true) { try { Log.v(TAG, "Waiting for connection..."); socket = mServerSocket.accept(); Log.v(TAG, ".....Got socket: " + socket); if (socket != null) { startEchoThread(socket); } else { return; // socket shutdown? } } catch (IOException e) { Log.v(TAG, "in accept: " + e); } } } }; t.start(); } private void startEchoThread(final LocalSocket socket) { Thread t = new Thread() { @Override public void run() { try { InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); InputStreamReader isr = new InputStreamReader(is); while (true) { char[] data = new char[128]; int ret = isr.read(data); for(int i=0;i<ret;i++){ Log.d(TAG, "data["+i+"]="+data[i]); } byte[] values = TypeUtils.float2Byte(-1234567.122f); float fd = -1234567.122f; Log.d(TAG, " fd="+fd); for(int i=0;i<values.length;i++){ Log.d(TAG, "values["+i+"]="+values[i]); } os.write(values); os.flush(); Log.v(TAG, "after write: "); } } catch (IOException e) { Log.v(TAG, "in echo thread loop: " + e.getMessage()); } } }; t.start(); } }
2.将float转换成byte[]数组的工具类
import java.nio.ByteBuffer; import java.nio.FloatBuffer; public class TypeUtils { public static byte[] floatToByte(float v) { ByteBuffer bb = ByteBuffer.allocate(4); byte[] ret = new byte[4]; FloatBuffer fb = bb.asFloatBuffer(); fb.put(v); bb.get(ret); return ret; } public static byte[] float2Byte(float f) { byte[] b = new byte[4]; int l = Float.floatToIntBits(f); for (int i = 0; i < b.length; i++) { b[i] = new Integer(l).byteValue(); l = l >> 8; } return b; } public static byte[] doubleToByte(double d) { byte[] b = new byte[8]; long l = Double.doubleToLongBits(d); for (int i = 0; i < b.length; i++) { b[i] = new Long(l).byteValue(); l = l >> 8; } return b; } public static float byteToFloat(byte[] v) { ByteBuffer bb = ByteBuffer.wrap(v); FloatBuffer fb = bb.asFloatBuffer(); return fb.get(); } public static float byte2Float(byte[] b) { int l = 0; l = b[0]; l &= 0xff; l |= ((int) b[1] << 8); l &= 0xffff; l |= ((int) b[2] << 16); l &= 0xffffff; l |= ((int) b[3] << 24); l &= 0xffffffffl; return Float.intBitsToFloat(l); } }
.在 native中建立client
#include <cutils/sockets.h> static union FloatValue{ char val[4]; float f; } mf_t; static __inline__ int qemud_fd_write(int fd, const void* buff, int len) { int len2; do { len2 = write(fd, buff, len); } while (len2 < 0 && errno == EINTR); return len2; } static __inline__ int qemud_fd_read(int fd, void* buff, int len) { int len2; do { len2 = read(fd, buff, len); } while (len2 < 0 && errno == EINTR); return len2; } int main(int argc, char **argv) { int fd; char answer[200]; char name[5]= "test!"; int namelen = 5; /* connect to qemud control socket */ fd = socket_local_client( "server_test", ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM ); if (fd < 0) { printf("no qemud control socket: %s \n", strerror(errno)); return -1; } /* send service name to connect */ if (qemud_fd_write(fd, name, namelen) != namelen) { printf("can't send service name to qemud: %s \n", strerror(errno)); close(fd); return -1; } printf(".... before qemud_fd_read \n"); /* read answer from daemon */ int res =qemud_fd_read(fd, answer, 200); printf(" .....after qemud_fd_read "); if (res) { printf("connect to service through qemud res =%d answer0 =%d ,answer1 =%d answer2 =%d ,answer3 =%d \n",res,answer[0],answer[1],answer[2],answer[3]); mf_t.val[0] = answer[0]; mf_t.val[1] = answer[1]; mf_t.val[2] = answer[2]; mf_t.val[3] = answer[3]; printf(" .....after convert f=%f \n",mf_t.f); close(fd); return -1; } return 0; }----------------------------------------------------------------------------------------------------------------------------------------------------------------------
android 中使用socket使native和framework通信
一般的native和framework的通信是通过jni,但是这一般只是framework调用native,native如果有消息要怎样通知上层呢?android中GSP模块提供一种解决思路,但是实现有些复杂,这里介绍一种使用socket通信的方法可以使native和framework自由通信,具体实现如下: