博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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

 查了下资料,早在2011年11月 Adobe 官方就发一篇介绍ANE的文章附一个简单的例子, 在去年八月份Adobe 开发者中心 开始发一系列较为详尽的文章, 有兴趣可以阅读下:

http://www.adobe.com/cn/devnet/air/articles/developing-native-extensions-air.html

http://www.adobe.com/cn/devnet/air/air_for_android.html

 

我先照着官方例子,做了一个调节多好媒体音量的扩展,并在测试机器正常运转。于是我开始着手准备项目需求 -- 利用Andriod 服务来推送应用消息, 于是也有了这系列文章的由来,接下来我将介绍我做的一些工作。

一、 HellAndriod Service

  由于我这前没有做过Andriod 开发,对java也不是很熟悉,唯一的Java编程经历是在大学时参与过的J2EE的项目,所以我先做了一个Andriod 服务的本地应用练练手. 这样的例子在网上很多,略作修改,代码如下:

package com.wenbo.helloandriod;

import android.app.Notification;

public class BackgroundService 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(), "Background Service");
            mthr.start();
        }
        
    }
    
    @Override
    public void onDestroy()
    {
        super.onDestroy();
        mSend = false;
    }

    @Override
    public IBinder onBind(Intent arg0) {
        // 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("runnable" + mCount);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }

    private void displayNotificationMessage(String message) {
        Log.d("", message);
        mCount++;
        @SuppressWarnings("deprecation")
        Notification notification = new Notification(R.drawable.ic_launcher, message,
                System.currentTimeMillis());
        
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
        
        notification.setLatestEventInfo(this, "女神之贱", message, contentIntent);
        
        notificationMgr.notify(R.id.app_notification_id, notification);
    }
}

在服务里开个线程,每隔一秒发一个后台通知。 然后我们建立一个入口启动它。

package com.wenbo.helloandriod;

import android.os.Bundle;

public class MainActivity extends Activity {
    private static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Log.d(TAG, "starting service");
        
        Button bindBtn = (Button) findViewById(R.id.start);
        bindBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                startService(new Intent(MainActivity.this,
                        BackgroundService.class)); 
            }
        });
        
        Button unbindBtn = (Button) findViewById(R.id.stop);
        unbindBtn.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                stopService(new Intent(MainActivity.this, BackgroundService.class));
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

做完这些,别忘了配置权限, 在AndroidManifest.xml的<activity></activity>后面添加

<service android:name="BackgroundService"/> 

安装到模拟器上或真实机器上 打开程序启动后就可以看到每隔一秒后台消息便会更新一次。按下stop后停止更新。

好了,下一节我将要按照ANE的要求改造它。

由于不能上传附件,我将另两个关键文件也贴出来。

一个是res/layout/activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <Button
        android:id="@+id/start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1" 
        android:layout_below="@+id/textView1"
        android:text="start" />

    <Button
        android:id="@+id/stop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/start"
        android:layout_below="@+id/start"
        android:layout_marginTop="15dp"
        android:text="stop" />

</RelativeLayout>

另一个是AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.wenbo.helloandriod"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.wenbo.helloandriod.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="BackgroundService"/> 
    </application>

</manifest>