こんにちは。きんくまです。
久しぶりにANEを作る必要がありまして。
それで、以前作ってたときよりいろいろと変わってました。
前は、エディタがeclipse版だったのですが、いまはAndroid Studioになったので、jarファイルを作るまでの手順がいろいろと変わってました。
今回のお題としては、ふだんAndroidの開発をしない人がANE用のjarファイルを取り出すところまでのメモです。
いまどき、AIR?ANE?それ誰トクなの?状態ですが、誰かの役にたつかもしれないので、、。
Android Studioをインストール
Androidの開発は、以前はeclipseだったのですが、いまはAndroid Studioになっていました。
私はいまは、AIRの開発はIntellj IDEAでやっているので、同じJetBrainsさん製ということでちょっと親近感がわきます!
ここのインストールの手順は適当にやってくださいw
新規Androidプロジェクトつくった後に、新規モジュールでAndroid Libraryを追加
新規のAndroidプロジェクトを作った後に、新規モジュールでAndroid Libraryを追加します。
File > Project Structure
左上の + ボタンからAndroid Libraryを追加します。
1番目のキャプチャはモジュールがすでに追加済みのものです。
appモジュールの下に、すでに新規のLibraryのモジュールが追加されています。
libs フォルダにFlashRuntimeExtensions.jarを追加
さきほど作った新規モジュールのディレクトリの中のlibsフォルダにFlashRuntimeExtensions.jarを追加します。
FlashRuntimeExtensions.jarは AIR SDKの中の以下のパスの中にあります。
libs/android/FlashRuntimeExtensions.jar
これだけだと、さきほどのjarファイルを同期してくれなかったので、適当にプロジェクト設定のライブラリのところを選択して
三角ボタンを上げ下げしたら、読み込んでくれました。
もっと正式なやりかたがあると思うんだけど、今回は気にしないw
Javaコードを書く
今回は、別アプリから自分のアプリを立ち上げられたときに、URLSchemeの情報を得るANEを作ったのでそれ用のコードです。
メソッドは2つで、ファイル名を得るやつと、ファイルを特定の位置にコピーするやつです。
なんでこんなの作るのかというと、Androidは別アプリから立ち上げられると、だいたい2種類のURLスキームが送られてきます。
ファイル
file://
コンテント
content://
の2種類です。他にもあるかもしれないけど、今回は必要ないので無視。
このとき、contetの方だと、ファイル名やパスがよくわかないのです。さらにいうと、Kitkat以降はパスがうまく取得できないみたいで、しょうがないのでファイルを自分がわかる位置にコピーして、コピーしたファイルをいろいろいじろうという目的です。
AndURLSchemeUtil.java
package com.kumade.ane.andurlschemeutil; import android.util.Log; import com.adobe.fre.FREContext; import com.adobe.fre.FREExtension; /** * Created by kinkuma on 10/1/16. */ public class AndURLSchemeUtil implements FREExtension { public static final String TAG = "AndURLSchemeUtil"; @Override public FREContext createContext(String arg0) { return new AndURLSchemeUtilContext(); } @Override public void dispose() { Log.d(TAG, "Extention disposed."); } @Override public void initialize() { Log.d(TAG, "Extension initialized"); } }
AndURLSchemeUtilContext.java
package com.kumade.ane.andurlschemeutil; import android.util.Log; import com.adobe.fre.FREContext; import com.adobe.fre.FREFunction; import java.util.HashMap; import java.util.Map; /** * Created by kinkuma on 10/1/16. */ public class AndURLSchemeUtilContext extends FREContext { public static final String TAG = "AndURLSchemeUtil"; @Override public void dispose() { Log.d(TAG, "context disposed."); } @Override public Map<String, FREFunction> getFunctions() { Map<String, FREFunction> functions = new HashMap<String, FREFunction>(); functions.put("getFileNameFromURL", new getFileNameFromURLFunc()); functions.put("copyFile", new CopyFileFunc()); return functions; } }
CopyFileFunc.java
package com.kumade.ane.andurlschemeutil; import android.content.Context; import android.net.Uri; import com.adobe.fre.FREContext; import com.adobe.fre.FREFunction; import com.adobe.fre.FREObject; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; /** * Created by kinkuma on 10/1/16. */ public class CopyFileFunc implements FREFunction { @Override public FREObject call(FREContext context, FREObject[] args) { String sourceURLStr = null; String destPath = null; try{ sourceURLStr = args[0].getAsString(); destPath = args[1].getAsString(); }catch(Exception e){ e.printStackTrace(); return null; } if(sourceURLStr == null || destPath == null){ return null; } boolean copyResult = copyFile(context.getActivity(), sourceURLStr, destPath); FREObject freObj = null; try{ freObj = FREObject.newObject(copyResult); }catch(Exception e){ e.printStackTrace(); } return freObj; } public boolean copyFile(Context context, String sourceURLStr, String destPath){ Uri uri = Uri.parse(sourceURLStr); if(uri == null){ return false; } InputStream inputStream = null; OutputStream outStream = null; boolean success = true; try{ inputStream = context.getContentResolver().openInputStream(uri); outStream = new FileOutputStream(destPath); byte[] buffer = new byte[4 * 1024]; int read; while((read = inputStream.read(buffer)) != -1){ outStream.write(buffer, 0, read); } outStream.flush(); }catch(Exception e){ e.printStackTrace(); success = false; } finally { if(outStream != null){ try{ outStream.close(); }catch(Exception e){ e.printStackTrace(); success = false; } } if(inputStream != null){ try{ inputStream.close(); }catch(Exception e){ e.printStackTrace(); success = false; } } } return success; } }
getFileNameFromURLFunc.java
package com.kumade.ane.andurlschemeutil; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.provider.MediaStore; import android.util.Log; import com.adobe.fre.FREContext; import com.adobe.fre.FREFunction; import com.adobe.fre.FREObject; /** * Created by kinkuma on 10/1/16. */ public class getFileNameFromURLFunc implements FREFunction { public static final String TAG = "AndURLSchemeUtil"; @Override public FREObject call(FREContext context, FREObject[] args) { String url = null; try{ url = args[0].getAsString(); }catch(Exception e){ e.printStackTrace(); return null; } if(url == null){ return null; } Uri uri = Uri.parse(url); String fileName = getFileNameFromURL(context.getActivity(), uri); if(fileName == null){ return null; } FREObject freObj = null; try{ freObj = FREObject.newObject(fileName); }catch(Exception e){ e.printStackTrace(); } return freObj; } public String getFileNameFromURL(Context context, Uri uri){ String fileName = null; if(uri.getScheme().equalsIgnoreCase("content")){ String prop = MediaStore.MediaColumns.DISPLAY_NAME; String[] proj = { prop }; Cursor cursor = null; try { cursor = context.getContentResolver().query( uri, proj, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndexOrThrow(prop); fileName = cursor.getString(columnIndex); }catch(Exception exception){ Log.d(TAG, exception.getMessage()); }finally { if(cursor != null){ cursor.close(); cursor = null; } } }else{ fileName = uri.getLastPathSegment(); } return fileName; } }
サンプルなんで、あんましコードは気にしないでください、、。
Build Variantsをreleaseに
Build Variantsっていうウインドウというのか設定タブがあるので、それを開いてLibraryモジュールをreleaseにしておきます。
いよいよビルドじゃー(jarだけに)
ビルドします。
ここ最初よくわかってなかったんですが、nodeのgulpみたいな感じで、gradleっていうタスクランナーっていうかビルドツールみたいのが入ってました。
それで、Libaryモジュールのbuildの中から
1. clean
2. build
を選択します。
jarはどこ?
ビルドされたjarファイルはどこなの?ってことなんですが、以下のパスにあります。
2019/02/22修正 Android Studio 3.2.1
プロジェクトフォルダ/モジュール名/build/intermediates/intermediate-jars/release/classes.jar
以前のパス
プロジェクトフォルダ/モジュール名/build/intermediates/bundles/release/classes.jar
まとめ
おつかれさまでした!これでjarファイルができたので、あとはいろいろやってane作ってください。
ちなみにいうと、Androidは意外と大丈夫だったりするんですが、iOS用のANEを作ろうとしたら、Xcode8だとDevicesの中のlogがログをはかなくなってしまい、すんごくデバッグしづらかったです。
なんかクラッシュレポートと、メモリの状態しか見せてくれなくなってた、、、。これでどうやってデバッグしろと、、。
というわけでメモでしたー。
■ 自作iPhoneアプリ 好評発売中!
・フォルメモ - シンプルなフォルダつきメモ帳
・ジッピー電卓 - 消費税や割引もサクサク計算!
■ LINEスタンプ作りました!
毎日使える。とぼけたウサギ