着手改造之前,有兴趣可以阅读下官方文档:http://help.adobe.com/zh_CN/air/extensions/index.html

新建工程 NavService 并创建包 nav.wenbo.service, 这些都可以自定义,但要记住你的包名。

注意最下方那个jar包,这个是必需的,打开项目的构建目录(buildPath),引用外部jar包, 目录在你在Flex sdk目录下

%FlexSDK%\4.x.x\lib\android\FlashRuntimeExtensions.jar

我的本地目录是:F:\Program Files\Adobe\Adobe Flash Builder 4.7\sdks\4.6.0\lib\android\FlashRuntimeExtensions.jar

首先创建air调用的入口类 ServiceExtension 这个类必需在ane包里面的extension.xml里指定(后面会介绍)

package nav.wenbo.service;

import android.content.Context;
import android.content.Intent;
import android.util.Log; import com.adobe.fre.FREContext;
import com.adobe.fre.FREExtension; public class ServiceExtension implements FREExtension {
public static final String TAG = "ServiceExtension";
public static Context appContext;
public static FREContext extensionContext;
public static String Msg = "none"; @Override
public FREContext createContext(String contextType) {
// TODO Auto-generated method stub
return new ServiceExtensionContext();
} @Override
public void dispose() {
// TODO Auto-generated method stub
Log.d(TAG, "Extension disposed.");
} @Override
public void initialize() {
// TODO Auto-generated method stub
Log.d(TAG, "Extension initialized.");
} }

ServiceExtension中关键是 createContext 方法,这个方法返回一个可连通air及本地Java代码的上下文。并在该上下文中定义可供air调用的方法

下面是ServiceExtensionContext类

package nav.wenbo.service;

import java.util.HashMap;
import java.util.Map; import nav.wenbo.service.functions.InitFunction;
import nav.wenbo.service.functions.SendFunction;
import nav.wenbo.service.functions.StartFunction; import android.util.Log; import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction; public class ServiceExtensionContext extends FREContext {
public static final String TAG = "ServiceExtensionContext";
@Override
public void dispose() {
// TODO Auto-generated method stub
Log.d(TAG,"Context disposed.");
} @Override
public Map<String, FREFunction> getFunctions() {
Map<String, FREFunction> functions = new HashMap<String, FREFunction>();
functions.put("init", new InitFunction());
functions.put("service", new StartFunction());
functions.put("send", new SendFunction()); return functions;
} }

functions.put相当注册调用逻辑的调用名, 这里把你所有调用方法都填上。init 用于初始化上下文,service用来启动和关闭服务, send用于发送消息。 在编写对应方法之前,

先把上一节的Backgroundservice 移植过来

package nav.wenbo.service;

import com.wenbo.navservice.R;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log; public class NotificationService extends Service {
private NotificationManager notificationMgr;
private Thread mthr;
private int mCount=0;
private Boolean mSend=true; @Override
public void onCreate() {
super.onCreate();
notificationMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
displayNotificationMessage("starting Background Service"); if(mthr == null || mSend == false)
{
mSend=true;
mthr = new Thread(null, new ServiceWorker(), "BackgroundSercie");
mthr.start();
}
if(null != ServiceExtension.extensionContext) ServiceExtension.extensionContext.dispatchStatusEventAsync("start", "1");
} @Override
public void onDestroy()
{
super.onDestroy();
mSend = false;
} @Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
} class ServiceWorker implements Runnable {
@Override
public void run() {
// do background processing here.....
// stop the service when done...
// BackgroundService.this.stopSelf()
while(mSend)
{
try{
Thread.sleep(1000);
Log.d("", "runnable" + mCount);
displayNotificationMessage(ServiceExtension.Msg);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
} private void displayNotificationMessage(String message) {
if(message == "none") return; Log.d("", message);
mCount++;
Notification notification = new Notification(R.drawable.ic_launcher, message,
System.currentTimeMillis()); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, Activity.class), 0); notification.setLatestEventInfo(this, "女神之贱", message, contentIntent); notificationMgr.notify(1000, notification);
}
}

这里改动很小,发送的消息从ServiceExtension类里面取,当message != none时显示该通知,另ServiceExtension.extensionContext.dispatchStatusEventAsync 是用来给air程序发消息, 在air中监听StatusEvent.STATUS 可以捕获这条消息并获取对应参数。在这里用处是通知服务启动成功。

下面就剩下实际调用的方法了。

首先是初始化上下文,这里主要是ServiceExtension.extensionContext 主要用于往air发消息。

package nav.wenbo.service.functions;

import nav.wenbo.service.ServiceExtension;

import android.content.Context;
import android.util.Log; import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;
import com.adobe.fre.FREObject; public class InitFunction implements FREFunction {
public static final String TAG = "InitFunction";
@Override
public FREObject call(FREContext context, FREObject[] args) {
ServiceExtension.extensionContext = context; Context appContext = context.getActivity().getApplicationContext();
ServiceExtension.appContext = appContext; Log.i(TAG, "in init"); return null;
} }

这里注意了,因为我们没有独立的Android入口文件,我们 只能从 FREContext.getActivity() 来取得我们所需的上下文,并用这上下文启动我们的服务,这是跟前一节例子最大不同的地方。

执行后通知air:context.dispatchStatusEventAsync("start", "2");

package nav.wenbo.service.functions;

import nav.wenbo.service.NotificationService;
import android.content.Context;
import android.content.Intent; import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;
import com.adobe.fre.FREObject; public class StartFunction implements FREFunction { @Override
public FREObject call(FREContext context, FREObject[] args) {
Context appContext = context.getActivity().getApplicationContext();
Boolean isStart=true;
try {
isStart = args[0].getAsBool();
} catch (Exception e) { }
if(isStart) context.getActivity().startService(new Intent(appContext, NotificationService.class));
else context.getActivity().stopService(new Intent(appContext, NotificationService.class)); context.dispatchStatusEventAsync("start", "2");
return null;
} }

最后这个最简单,仅仅设置下所要推送的消息.

package nav.wenbo.service.functions;

import nav.wenbo.service.ServiceExtension;

import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;
import com.adobe.fre.FREObject; public class SendFunction implements FREFunction { @Override
public FREObject call(FREContext context, FREObject[] args) {
// TODO Auto-generated method stub
String msg="none";
try
{
msg = args[0].getAsString();
}
catch(Exception e)
{ }
ServiceExtension.Msg = msg;
return null;
} }

做完这些,并设置好权限后,把项目导出jar包, 命名为 libAndroidServiceLib.jar

下一节我将介绍air中跟此jar包对接。

通过 ANE(Adobe Native Extension) 启动Andriod服务 推送消息(二)的更多相关文章

  1. 通过 ANE(Adobe Native Extension) 启动Andriod服务 推送消息(一)

    项目组用air来开发手游, 但有些在原生应用里很容易实现的功能没有办法在air中直接调用,比如说震动,服务等等.但Adobe 提供了一种方法让air间接调用本地代码(java,object-c...) ...

  2. 通过 ANE(Adobe Native Extension) 启动Andriod服务 推送消息(三)

    jar包完成后,剩下就是要构建ANE包来供实际程序调用. 首先要建两个Flex库项目, default那个是官方建议加上的,仅用于不在真实环境下编译调试的时候有个默认接口不至于调用不成功报错,项目结构 ...

  3. 通过 ANE(Adobe Native Extension) 启动Andriod服务 推送消息(四)

    这一节,是要把AS库和Android的jar包及相关配置文件打成一个ane包. 首先先建一个build目录,里面文件目录结构如下: 然后用打开压缩包的方式打开ServiceLib.swc, 把其中的l ...

  4. 通过 ANE(Adobe Native Extension) 启动Andriod服务 推送消息(五)

    这一节,用个简单的例子来调用下之前生成的service.ane 首先建一个flex手机项目 然后在构建路径中把ane引进来 可以看到此ane支持Android平台. serviceMobile.mxm ...

  5. 用JPUSH极光推送实现服务端向安装了APP应用的手机推送消息(C#服务端接口)

    这次公司要我们做一个功能,就是当用户成功注册以后,他登录以后要收到消息,当然这个消息是安装了我们的手机APP应用的手机咯. 极光推送的网站的网址是:https://www.jpush.cn/ 极光推送 ...

  6. APNS 服务推送通知

    1. 将app注册notification里面, 并从APNS上获取测试机的deviceToken. - (BOOL)application:(UIApplication *)application ...

  7. 模拟websocket推送消息服务mock工具二

    模拟websocket推送消息服务mock工具二 在上一篇博文中有提到<使用electron开发一个h5的客户端应用创建http服务模拟后端接口mock>使用electron创建一个模拟后 ...

  8. Spring Boot 集成 WebSocket 实现服务端推送消息到客户端

    假设有这样一个场景:服务端的资源经常在更新,客户端需要尽量及时地了解到这些更新发生后展示给用户,如果是 HTTP 1.1,通常会开启 ajax 请求询问服务端是否有更新,通过定时器反复轮询服务端响应的 ...

  9. 使用极光推送(www.jpush.cn)向安卓手机推送消息【服务端向客户端主送推送】C#语言

    在VisualStudio2010中新建网站JPushAndroid.添加引用json帮助类库Newtonsoft.Json.dll. 在web.config增加appkey和mastersecret ...

随机推荐

  1. 【转】MyEclipse8.5集成Tomcat7时的启动错误:Exception in thread “main” java.lang.NoClassDefFoundError org/apache/commons/logging/LogFactory

    http://www.cnblogs.com/newsouls/p/4021198.html 今天,安装Tomcat7.0.21后,单独用D:\apache-tomcat-7.0.21\bin\sta ...

  2. 理解shared_ptr<T> ---2

    1.引用计数字段不能放在资源管理类中.我们的解决办法是,把引用计数和资源绑在一起,进行二次封装.但是这样存在一个大问题,不同类型的资源管理类不能兼容.也就是说,shared_ptr<Dog> ...

  3. sleep() wait() yield() join()用法与区别

    1.sleep()方法 在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”.不推荐使用. sleep()使当前线程进入阻塞状态,在指定时间内不会执行. 2.wait()方法 在其他线程调用 ...

  4. A+B Problem III

    描述 求A+B是否与C相等. 输入 T组测试数据. 每组数据中有三个实数A,B,C(-10000.0<=A,B<=10000.0,-20000.0<=C<=20000.0) 数 ...

  5. javascript笔记03:易犯错的比较运算

    1.比较两个值是否相等的常见运算: " //false == "" //true == " //true false == "false" ...

  6. Android之利用HTTP网络通信实现与PHP的交互(三)

    Android与PHP的交互是通过Http网络编程来实现的,利用php访问数据库,并且操作数据库中的数据,利用php作为接口,使Android连接数据库. 一般情况下,我们使用Json格式进行传输,利 ...

  7. Swift基础学习01

    相关网站:http://www.cnblogs.com/tt_mc/p/3871295.html   相关辅助操作: 可以在右边直接查看输出值   可能出现的常见问题: 1.凡是=注意左右间距一样 2 ...

  8. c++与c不太相同的一些地方1

    1.c++区别与java的一个地方:C++更多的是一种规范,不同时期的不同标准,提供了不同的语法要求.所以各个厂商在对C++的支持上也做得不尽相同,比如有些语法vs就支持gcc 就支持的差一些,而某些 ...

  9. SQL的几道题目

    1.构造数据插入方案表t_project_finish表 a)将addtime更新为当前时间的前一天 首先想到的是addtime=addtime-1,然后就开始验证这个想法. 插入一行数据,包括主键和 ...

  10. CyclicBarrier 使用说明

    字面意思回环栅栏,通过它可以实现让一组线程等待至某个状态之后再全部同时执行.叫做回环是因为当所有等待线程都被释放以后,CyclicBarrier可以被重用.   主要方法:      public i ...