解説編4をようやくアップしました。
作りかけのまま忙しくなってしまって三ヶ月くらい空いてしまった。
全てactionscriptで動かしているとはいえ、結構内容的な意味で時間かかってしまいますね。
次回は東方キャラを使わせてもらって解説してみようかと思います。
<extension xmlns="http://ns.adobe.com/air/extension/3.5">
<id>katsuraba.ane.TugeparaExtension</id>
<versionNumber>1.0.0</versionNumber>
<name>
<text xml:lang="en_US">Hello World</text>
<text xml:lang="ja_JP">こんにちは 世界</text>
</name>
<platforms>
<platform name="iPhone-ARM">
<applicationDeployment>
<nativeLibrary>libTugeAne.a</nativeLibrary>
<initializer>ExtInitializer</initializer>
<finalizer>ExtFinalizer</finalizer>
</applicationDeployment>
</platform>
</platforms>
</extension>
<platform xmlns="http://ns.adobe.com/air/extension/3.5">
<description>An optional description.</description>
<copyright>2011 (optional)</copyright>
<sdkVersion>5.0.0</sdkVersion>
<linkerOptions>
<option>-ios_version_min 5.0</option>
<option>-framework Accelerate</option>
<option>-liconv</option>
<option>-ObjC</option>
</linkerOptions>
<packagedDependencies>
<packagedDependency>ASIHTTPRequest.framework</packagedDependency>
<packagedDependency>XCTest.framework</packagedDependency>
<packagedDependency>AdSupport.framework</packagedDependency>
<packagedDependency>CFNetwork.framework</packagedDependency>
<packagedDependency>JSONKit.framework</packagedDependency>
<packagedDependency>Foundation.framework</packagedDependency>
<packagedDependency>MobileCoreServices.framework</packagedDependency>
<packagedDependency>imobileAds.framework</packagedDependency>
<packagedDependency>SystemConfiguration.framework</packagedDependency>
</packagedDependencies>
</platform>
<iPhone>
<InfoAdditions><![CDATA[
・・・
<key>MinimumOSVersion</key>
<string>6.0</string>
・・・
]]></InfoAdditions>
<requestedDisplayResolution>high</requestedDisplayResolution>
</iPhone>
<extension xmlns="http://ns.adobe.com/air/extension/3.5">
<id>katsuraba.ane.TugeparaExtension</id>
<versionNumber>1.0.0</versionNumber>
<name>
<text xml:lang="en_US">Hello World</text>
<text xml:lang="ja_JP">こんにちは 世界</text>
</name>
<platforms>
<platform name="Android-ARM">
<applicationDeployment>
<nativeLibrary>TugeAne.jar</nativeLibrary>
<initializer>tugepara.ane.android.TugeparaExtension</initializer>
<finalizer>tugepara.ane.android.TugeparaExtension</finalizer>
</applicationDeployment>
</platform>
</platforms>
</extension>
<android>
<manifestAdditions><![CDATA[<manifest>
<uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application>
<meta-data android:name="i-mobile_Testing" android:value="false" />
<meta-data android:name="i-mobile_Publisher_ID" android:value="****" />
</application>
</manifest>]]></manifestAdditions>
</android>
package com.katsuraba
{
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.external.ExtensionContext;
public class TugeparaExtension extends EventDispatcher
{
private var context:ExtensionContext;
public function TugeparaExtension(target:IEventDispatcher=null)
{
super(target);
context= ExtensionContext.createExtensionContext("katsuraba.ane.TugeparaExtension", "type");
}
public function getHelloWorld():String
{
return context.call("GetHelloWorld") as String;
}
public function getSessionKey():String
{
return context.call("GetSessionKey") as String;
}
public function setSessionKey(sessionKey:String):void
{
context.call("SetSessionKey", sessionKey);
}
public function displayImobile():void
{
context.call("DisplayImobile");
}
public function unDisplayImobile():void
{
context.call("UnDisplayImobile");
}
public function dispose():void
{
return context.dispose();
}
}
}
#import
#import "FlashRuntimeExtensions.h"
@interface TugeAne : NSObject
@end
FREObject GetHelloWorld(
FREContext ctx,
void* funcData,
uint32_t argc,
FREObject arg[]
);
FREObject GetSessionKey(
FREContext ctx,
void* funcData,
uint32_t argc,
FREObject arg[]
);
FREObject SetSessionKey(
FREContext ctx,
void* funcData,
uint32_t argc,
FREObject arg[]
);
FREObject DisplayImobile(
FREContext ctx,
void* funcData,
uint32_t argc,
FREObject arg[]
);
FREObject UnDisplayImobile(
FREContext ctx,
void* funcData,
uint32_t argc,
FREObject arg[]
);
void ContextInitializer(
void* extData,
const uint8_t* ctxType,
FREContext ctx,
uint32_t* numFunctionsToTest,
const FRENamedFunction** functionsToSet
);
void ContextFinalizer(FREContext ctx);
void ExtInitializer(
void** extDataToSet,
FREContextInitializer* ctxInitializerToSet,
FREContextFinalizer* ctxFinalizerToSet
);
void ExtFinalizer(void* extData);
#import "TugeAne.h"
#import "TugeAneViewController.h"
#import "imobileAds/IMobileAdIconView.h"
@implementation TugeAne
@end
TugeAneViewController *tugeAneAdView;
FREObject GetHelloWorld(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) {
const char *str = "HelloWorld !";
FREObject retStr;
FRENewObjectFromUTF8(strlen(str)+1, (const uint8_t *)str, &retStr);
return retStr;
}
FREObject GetSessionKey(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) {
//NSUserDefaultsからセッションキーを取得
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSString *key = @"tugeane_session_key";
NSString *skey = [ud stringForKey:key];
if(skey==nil) skey = @"0";
const char *str = [skey UTF8String];
FREObject retStr;
FRENewObjectFromUTF8(strlen(str)+1, (const uint8_t *)str, &retStr);
return retStr;
}
FREObject SetSessionKey(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) {
//NSUserDefaultsへセッションキーを保存
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSString *key = @"tugeane_session_key";
NSString *sessionKey = @"";
uint32_t length;
const uint8_t *value;
FREGetObjectAsUTF8(argv[0], &length, &value);
[ud setObject:[NSString stringWithUTF8String: (char*) value] forKey:key];
[ud synchronize];
return NULL;
}
FREObject DisplayImobile(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) {
//AD用のviewを追加する
tugeAneAdView = [[TugeAneViewController alloc] init];
//広告の位置を決定する。サイズによって変わる。320x568の場合はサイズを大きくする
UIScreen *sc = [UIScreen mainScreen];
CGRect rect0 = sc.bounds;
int startY = rect0.size.height-50;
int size = 50;
//320x568なら広告の位置を変えます。
if(rect0.size.height == 568 || rect0.size.height == 1136) {
startY = rect0.size.height-90;
size = 70;
}
//iPadなら
if(rect0.size.height == 568 || rect0.size.height == 1136) {
//
}
CGRect rect = CGRectMake(0, startY, rect0.size.width, size);
tugeAneAdView.view.frame = rect;
tugeAneAdView.adSize = size;
tugeAneAdView.adWidth = rect0.size.width;
[tugeAneAdView showAd];
//windowに追加
id delegate = [[UIApplication sharedApplication] delegate];
UIWindow * win = [delegate window];
[win addSubview:tugeAneAdView.view];
return NULL;
}
FREObject UnDisplayImobile(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) {
tugeAneAdView = nil;
return NULL;
}
void ContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx,
uint32_t* numFunctionsToTest, const FRENamedFunction** functionsToSet) {
*numFunctionsToTest = 5;
FRENamedFunction* func = (FRENamedFunction*)malloc(sizeof(FRENamedFunction)*5);
func[0].name = (const uint8_t*)"GetHelloWorld";
func[0].functionData = NULL;
func[0].function = &GetHelloWorld;
func[1].name = (const uint8_t*)"GetSessionKey";
func[1].functionData = NULL;
func[1].function = &GetSessionKey;
func[2].name = (const uint8_t*)"SetSessionKey";
func[2].functionData = NULL;
func[2].function = &SetSessionKey;
func[3].name = (const uint8_t*)"DisplayImobile";
func[3].functionData = NULL;
func[3].function = &DisplayImobile;
func[4].name = (const uint8_t*)"UnDisplayImobile";
func[4].functionData = NULL;
func[4].function = &UnDisplayImobile;
*functionsToSet = func;
}
void ContextFinalizer(FREContext ctx) {
return;
}
void ExtInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet,
FREContextFinalizer* ctxFinalizerToSet) {
*extDataToSet = NULL;
*ctxInitializerToSet = &ContextInitializer;
*ctxFinalizerToSet = &ContextFinalizer;
}
void ExtFinalizer(void* extData) {
return;
}
#import
@interface TugeAneViewController : UIViewController
@property int adSize;
@property int adWidth;
#define YOUR_PUBLISHER_ID (int)*****
#define YOUR_MEDIA_ID (int)*****
#define YOUR_SPOT_ID (int)*****
-(void) showAd;
@end
#import "TugeAneViewController.h"
#import "FlashRuntimeExtensions.h"
#import "imobileAds/ImobileAdIconView.h"
#import "imobileAds/IMobileAdIconViewParams.h"
@interface TugeAneViewController () {
}
@end
@implementation TugeAneViewController
@synthesize adSize;
@synthesize adWidth;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void) showAd {
IMobileAdIconViewParams *params = [[IMobileAdIconViewParams alloc] init];
params.iconSize = adSize;
params.iconTitleEnable = NO;
CGRect frame = CGRectMake(0, 0, adWidth, adSize);
IMobileAdIconView *imAdIconView = [[IMobileAdIconView alloc] initWithFrame:frame
publisherId:YOUR_PUBLISHER_ID mediaId:YOUR_MEDIA_ID
spotId:YOUR_SPOT_ID
iconNumber:4
params:params
testMode:NO];
[self.view addSubview:imAdIconView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
package tugepara.ane.android;
import java.util.HashMap;
import java.util.Map;
import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;
import tugepara.ane.android.function.DisplayImobileFunction;
import tugepara.ane.android.function.GetHelloWorldFunction;
import tugepara.ane.android.function.GetSessionKeyFunction;
import tugepara.ane.android.function.SetSessionKeyFunction;
import tugepara.ane.android.function.UnDisplayImobileFunction;
public class TugeparaContext extends FREContext {
public TugeparaContext() {
}
public MapgetFunctions() {
HashMapresult = new HashMap ();
//関数の定義
result.put("GetHelloWorld", new GetHelloWorldFunction());
result.put("GetSessionKey", new GetSessionKeyFunction());
result.put("SetSessionKey", new SetSessionKeyFunction());
result.put("DisplayImobile", new DisplayImobileFunction());
result.put("UnDisplayImobile", new UnDisplayImobileFunction());
return result;
}
public void dispose() {
//コンテキストの破棄処理
}
}
package tugepara.ane.android;
import com.adobe.fre.FREContext;
import com.adobe.fre.FREExtension;
import tugepara.ane.android.TugeparaContext;
public class TugeparaExtension implements FREExtension {
public TugeparaExtension() {
}
public FREContext createContext(String arg) {
//コンテキスト作成
FREContext context = new TugeparaContext();
return context;
}
public void initialize() {
//ネイティブ拡張初期化処理
}
public void dispose() {
//ネイティブ拡張破棄処理
}
}
package tugepara.ane.android.function;
import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;
import com.adobe.fre.FREObject;
import com.adobe.fre.FREWrongThreadException;
public class GetHelloWorldFunction implements FREFunction {
public GetHelloWorldFunction() {
}
public FREObject call(FREContext arg0, FREObject arg1[]) {
try {
return FREObject.newObject("Hello tugepara 1");
} catch (FREWrongThreadException e) {
e.printStackTrace();
return null;
}
}
}
package tugepara.ane.android.function;
import android.app.Activity;
import android.content.Context;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;
import com.adobe.fre.FREObject;
public class DisplayImobileFunction implements FREFunction {
private jp.co.imobile.android.AdIconView ad;
public DisplayImobileFunction() {
}
public FREObject call(FREContext arg0, FREObject arg1[]) {
try {
int mediaId = ******;
int spotId = ******;
//アクティビティ
Activity activity = new Activity();
activity = arg0.getActivity();
DisplayMetrics metrics = new DisplayMetrics();
((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metrics);
Context con = (Context)activity;
this.ad = jp.co.imobile.android.AdIconView.create(con, mediaId, spotId, 4);
//位置設定
int wc = LinearLayout.LayoutParams.WRAP_CONTENT;
int height = (int)(75.0f * metrics.density + 0.5f);
FrameLayout.LayoutParams adParams = new FrameLayout.LayoutParams(wc, height);
adParams.gravity = Gravity.BOTTOM;
//表示
activity.addContentView(this.ad, adParams);
this.ad.start();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
※省略します。今後の課題です。
package tugepara.ane.android.function;
import android.app.Activity;
import android.content.SharedPreferences;
import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;
import com.adobe.fre.FREObject;
import com.adobe.fre.FREWrongThreadException;
public class GetSessionKeyFunction implements FREFunction {
public GetSessionKeyFunction() {
}
public FREObject call(FREContext arg0, FREObject arg1[]) {
try {
//アクティビティ
Activity activity = new Activity();
activity = arg0.getActivity();
//preferenceから取得
SharedPreferences sp = activity.getSharedPreferences("tugepara_sessionkey", Activity.MODE_PRIVATE);
String sessionKey = sp.getString("tugepara_sessionKey", "0");
return FREObject.newObject(sessionKey);
} catch (FREWrongThreadException e) {
e.printStackTrace();
return null;
}
}
}
package tugepara.ane.android.function;
import android.app.Activity;
import android.content.SharedPreferences;
import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;
import com.adobe.fre.FREInvalidObjectException;
import com.adobe.fre.FREObject;
import com.adobe.fre.FRETypeMismatchException;
import com.adobe.fre.FREWrongThreadException;
public class SetSessionKeyFunction implements FREFunction {
public SetSessionKeyFunction() {
}
public FREObject call(FREContext arg0, FREObject arg1[]) {
try {
//アクティビティ
Activity activity = new Activity();
activity = arg0.getActivity();
//データ保存
FREObject param = arg1[0];
String sessionKey = param.getAsString();
SharedPreferences sp = activity.getSharedPreferences("tugepara_sessionkey", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("tugepara_sessionkey", sessionKey);
editor.commit();
} catch (FREWrongThreadException e) {
e.printStackTrace();
} catch (FREInvalidObjectException e) {
e.printStackTrace();
} catch (FRETypeMismatchException e) {
e.printStackTrace();
}
return null;
}
}