着手改造之前,有兴趣可以阅读下官方文档: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. Oracle12c功能增强 新特性之管理功能的增强

    1.    数据文件在线重命名和迁移 不想先前的版本号.在Oracle12cR1中,数据文件的迁移或重命名不再要求一系列的步骤,比如:将表空间至于仅仅读模式,然后数据文件逻辑等操作.在12cR1中.数 ...

  2. 【49】了解new_handler的行为

    1.使用operator new无法获取内存时,对于旧式编译器,会返回一个null指针.对于新式编译器,会抛出一个异常. 2.考虑下面的需求,当operator new 无法获取内存时,程序员期望获得 ...

  3. [RxJS] Subject basic

    A Subject is a type that implements both Observer and Observable types. As an Observer, it can subsc ...

  4. windows平台下php版本问题–VC6/VC9和TS/NTS

    php下载页面中提供了4个下载版本,是vc6/vc9 与 TS/NTS的组合 VC6:legacy Visual Studio 6 compiler,就是使用这个编译器编译的.        VC9: ...

  5. perl dtrace2

    http://search.cpan.org/~chrisa/Devel-DTrace-Provider-1.11/lib/Devel/DTrace/Provider.pm

  6. (function(){}).call(window) 严格模式匿名函数的this指向undefined

    上次在群里,看到有人发出 (function(){}).call(window) 这么一段代码,问这有什么意义,匿名函数中的this不是始终都指向window的么,为什么还要call,我当时也很疑惑. ...

  7. location查询字符串解析

    function getQueryStringArgs() { //取得查询字符串并去掉开头的问号 var qs = (location.search.length >0? location.s ...

  8. (源)V8 Engine 编译

    v8 engine编译 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !imp ...

  9. 创建线程(Background Thread)的N种方式

    第一.Thread类 Thread类是实例化线程的主要方法:一个Thread实例管理一个线程,即执行序列.通过简单实例化一个对象,就可以创建一个线程,然后通过Thread对象提供的方法对线程进行管理. ...

  10. debian 系统备份

    tar -zcvpf /home/full-backup.tar.gz / --exclude=/mnt/* --exclude=/proc/* --exclude=/sys/* 这个命令是把根目录下 ...