管理人様ありがとうございます。
お陰で出来ました。
シグネチャがint型だと『I』だけなのにString型が『Ljava/lang/String;』とセミコロンを入れる必要があるため時間がかかってしまいました。
参考になったサイトです。
ttp://setohide.blogspot.com/2014/01/jni.html
以下ソースです。
//native-lib.cpp
#include "DxLib.h"
#include <string.h>
// データ取得用バッファ 8MB( 足りない場合は増やしてください )
BYTE HTTP_DataBuffer[ 8 * 1024 * 1024 ] ;
// HTTP通信を行う
// URL : 接続するパス
// Method : "GET", "POST", "PUT" の何れか
// 戻り値 : 0:成功 -1:エラー
int Android_HTTP_Connect( const char *URL, const char *Method, const char *Post );
int Android_HTTP_Connect( const char *URL, const char *Method)
{
return Android_HTTP_Connect(URL, Method, "");
}
int Android_HTTP_Connect( const char *URL, const char *Method, const char *Post )
{
JNIEnv *env ;
const ANativeActivity *NativeActivity ;
jstring jstring_URL ;
jstring jstring_Post;
int MethodType = 0 ;
// アプリの NativeActivity を取得しておく
NativeActivity = GetNativeActivity() ;
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if( NativeActivity->vm->AttachCurrentThreadAsDaemon( &env, NULL ) != JNI_OK )
{
return -1 ;
}
// URL から jstring を作成
jstring_URL = env->NewStringUTF( URL ) ;
jstring_Post = env->NewStringUTF( Post ) ;
// メソッド名からメソッドタイプの数値をセット
if( strcmpDx( "GET", Method ) == 0 )
{
MethodType = 0 ;
}
else
if( strcmpDx( "POST", Method ) == 0 )
{
MethodType = 1 ;
}
else
if( strcmpDx( "PUT", Method ) == 0 )
{
MethodType = 2 ;
}
// Java のクラス MainActivity を取得
jclass jclass_MainActivity = env->GetObjectClass( NativeActivity->clazz ) ;
// Java のクラス MainActivity のメンバー関数 HTTP_Connect の ID を取得
jmethodID jmethodID_HTTP_Connect = env->GetMethodID( jclass_MainActivity, "HTTP_Connect", "(Ljava/lang/String;ILjava/lang/String;)V" ) ;
// Java のクラス MainActivity のメンバー関数 HTTP_Connect の呼び出し
env->CallVoidMethod( NativeActivity->clazz, jmethodID_HTTP_Connect, jstring_URL, MethodType ,jstring_Post) ;
// Java の参照を削除
env->DeleteLocalRef( jclass_MainActivity ) ;
env->DeleteLocalRef( jstring_URL ) ;
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread() ;
// 正常終了
return 0 ;
}
// HTTP通信の結果を取得する
// 戻り値 : 通信の結果( 0:まだ通信中 1以上:HTTPレスポンスコード -2:IO例外発生 -3:MalformedURL例外発生 )
int Android_HTTP_GetResponseCode( void )
{
JNIEnv *env ;
const ANativeActivity *NativeActivity ;
int Result = -1 ;
// アプリの NativeActivity を取得しておく
NativeActivity = GetNativeActivity() ;
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if( NativeActivity->vm->AttachCurrentThreadAsDaemon( &env, NULL ) != JNI_OK )
{
return -1 ;
}
// Java のクラス MainActivity を取得
jclass jclass_MainActivity = env->GetObjectClass( NativeActivity->clazz ) ;
// Java のクラス MainActivity のメンバー変数の ID を取得
jfieldID jfieldID_HTTP_ResponseCode = env->GetStaticFieldID( jclass_MainActivity, "HTTP_ResponseCode", "I" ) ;
jfieldID jfieldID_HTTP_Connect_Finish = env->GetStaticFieldID( jclass_MainActivity, "HTTP_Connect_Finish", "I" ) ;
// Java のクラス MainActivity のメンバー変数の値を取得
jint jint_HTTP_ResponseCode = env->GetStaticIntField( jclass_MainActivity, jfieldID_HTTP_ResponseCode ) ;
jint jint_HTTP_Connect_Finish = env->GetStaticIntField( jclass_MainActivity, jfieldID_HTTP_Connect_Finish ) ;
// まだ通信処理が終わっていなかったら 0 を返す
if( jint_HTTP_Connect_Finish == 0 )
{
Result = 0 ;
}
else
{
// 終わっていたらレスポンスコードを返す
Result = jint_HTTP_ResponseCode ;
}
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread() ;
// 戻り値を返す
return Result ;
}
// HTTP通信の例外メッセージを所得する
// 戻り値 : 例外のメッセージ文字列のポインタ
char *Android_HTTP_GetExceptionMessage( void )
{
JNIEnv *env ;
const ANativeActivity *NativeActivity ;
static char HTTP_ExceptionMessage[ 64 * 1024 ] ;
// アプリの NativeActivity を取得しておく
NativeActivity = GetNativeActivity() ;
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if( NativeActivity->vm->AttachCurrentThreadAsDaemon( &env, NULL ) != JNI_OK )
{
return NULL ;
}
// Java のクラス MainActivity を取得
jclass jclass_MainActivity = env->GetObjectClass( NativeActivity->clazz ) ;
// Java のクラス MainActivity のメンバー変数の ID を取得
jfieldID jfieldID_HTTP_ExceptionMessage = env->GetStaticFieldID( jclass_MainActivity, "HTTP_ExceptionMessage", "Ljava/lang/String;" ) ;
// Java のクラス MainActivity のメンバー変数の値を取得
jstring jstring_HTTP_ExceptionMessage = ( jstring )env->GetStaticObjectField( jclass_MainActivity, jfieldID_HTTP_ExceptionMessage ) ;
// jstring の文字列をグローバル変数にコピー
const char *utf8_HTTP_ExceptionMessage = env->GetStringUTFChars( jstring_HTTP_ExceptionMessage, NULL ) ;
if( utf8_HTTP_ExceptionMessage != NULL )
{
strcpyDx( HTTP_ExceptionMessage, utf8_HTTP_ExceptionMessage ) ;
}
else
{
HTTP_ExceptionMessage[ 0 ] = '\0' ;
}
env->ReleaseStringUTFChars( jstring_HTTP_ExceptionMessage, utf8_HTTP_ExceptionMessage ) ;
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread() ;
// メッセージ文字列を返す
return HTTP_ExceptionMessage ;
}
// HTTP通信の結果得られたデータのバッファを取得する
// BufferBytes : バッファに格納されているデータのサイズを保存する変数のアドレス
// 戻り値 : データのバッファの先頭アドレス
void *Android_HTTP_GetBuffer( size_t *BufferBytes )
{
JNIEnv *env ;
const ANativeActivity *NativeActivity ;
void *Result = NULL ;
// アプリの NativeActivity を取得しておく
NativeActivity = GetNativeActivity() ;
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if( NativeActivity->vm->AttachCurrentThreadAsDaemon( &env, NULL ) != JNI_OK )
{
return NULL ;
}
// Java のクラス MainActivity を取得
jclass jclass_MainActivity = env->GetObjectClass( NativeActivity->clazz ) ;
// Java のクラス MainActivity のメンバー変数の ID を取得
jfieldID jfieldID_HTTP_DataBuffer = env->GetStaticFieldID( jclass_MainActivity, "HTTP_DataBuffer", "[B" ) ;
jfieldID jfieldID_HTTP_DataBufferEnableBytes = env->GetStaticFieldID( jclass_MainActivity, "HTTP_DataBufferEnableBytes", "I" ) ;
// Java のクラス MainActivity のメンバー変数の内容を取得
jint jint_HTTP_DataBufferEnableBytes = env->GetStaticIntField( jclass_MainActivity, jfieldID_HTTP_DataBufferEnableBytes ) ;
// 有効なデータが 1byte でもあれば、バッファの内容を取得する
if( jint_HTTP_DataBufferEnableBytes > 0 )
{
// Java のクラス MainActivity のメンバー変数 HTTP_DataBuffer の内容を取得
jbyteArray jbyteArray_HTTP_DataBuffer = ( jbyteArray )env->GetStaticObjectField( jclass_MainActivity, jfieldID_HTTP_DataBuffer ) ;
jbyte *jbyte_Elements = env->GetByteArrayElements( jbyteArray_HTTP_DataBuffer, NULL ) ;
memcpy( HTTP_DataBuffer, jbyte_Elements, jint_HTTP_DataBufferEnableBytes ) ;
env->ReleaseByteArrayElements( jbyteArray_HTTP_DataBuffer, jbyte_Elements, 0 ) ;
env->DeleteLocalRef( jbyteArray_HTTP_DataBuffer ) ;
Result = HTTP_DataBuffer ;
}
// バッファの有効なデータのサイズを保存
*BufferBytes = jint_HTTP_DataBufferEnableBytes ;
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread() ;
// バッファのアドレスを返す
return Result ;
}
int android_main( void )
{
// DXライブラリの初期化
if( DxLib_Init() < 0 ) return -1 ;
// 描画先を裏画面にする
SetDrawScreen( DX_SCREEN_BACK ) ;
// HTTP通信開始
//Android_HTTP_Connect( "ttps://yaki-3d.work/test.php?num1=12", "GET" ) ;
Android_HTTP_Connect( "ttps://yaki-3d.work/test_post.php", "POST" , "num1=12") ;
// メインループ
while( ProcessMessage() == 0 )
{
// 画面のクリア
ClearDrawScreen() ;
// HTTP通信の結果によって処理を分岐
int ResponseCode = Android_HTTP_GetResponseCode() ;
switch( ResponseCode )
{
case 0 :
// 通信が終了していない場合は『通信中』を表示する
DrawString( 0, 0, "通信中", GetColor( 255,255,255 ) ) ;
break ;
case -2 :
// IO例外が発生した場合はメッセージを表示する
DrawFormatString( 0, 0, GetColor( 255,255,255 ), "IO例外発生 : %s", Android_HTTP_GetExceptionMessage() ) ;
break ;
case -3 :
// MalformedURL例外が発生した場合はメッセージを表示する
DrawFormatString( 0, 0, GetColor( 255,255,255 ), "MalformedURL例外発生 : %s", Android_HTTP_GetExceptionMessage() ) ;
break ;
default :
// それ以外の場合は HTTPレスポンスコード
// データのサイズとアドレスを取得
size_t DataBytes ;
void *Buffer = Android_HTTP_GetBuffer( &DataBytes ) ;
DrawFormatString( 0, 16 * 0, GetColor( 255,255,255 ), "HTTPレスポンスコード : %d", ResponseCode ) ;
DrawFormatString( 0, 16 * 1, GetColor( 255,255,255 ), "データのサイズ : %d bytes", ( int )DataBytes ) ;
DrawFormatString( 0, 16 * 2, GetColor( 255,255,255 ), "データ : %s", Buffer != NULL ? ( char * )Buffer : "None" ) ;
break ;
}
// 裏画面の内容を表画面に反映
ScreenFlip() ;
}
// DXライブラリの後始末
DxLib_End() ;
// ソフトの終了
return 0 ;
}
//MainActivity.java
package work.yaki3d.httptest;
import android.app.NativeActivity;
import java.io.Closeable;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.io.InputStream;
import java.io.IOException;
import java.lang.Thread;
import java.nio.charset.StandardCharsets;
public class MainActivity extends NativeActivity
{
// 接続 URL 受け渡し用変数
static String HTTP_URLString ;
// 接続 POST 受け渡し用変数
static String HTTP_POSTString ;
// メソッドタイプ受け渡し用変数
static int HTTP_MethodType ;
// 通信処理の終了確認用変数
static int HTTP_Connect_Finish ;
// HTTPレスポンスコードを代入する変数
static int HTTP_ResponseCode ;
// 例外発生時のメッセージを代入する変数
static String HTTP_ExceptionMessage ;
// 通信結果のデータを格納するバッファ関連の変数
static boolean HTTP_DataBuffer_Initialize = false ;
static byte[] HTTP_DataBuffer ;
static int HTTP_DataBufferBytes = 8 * 1024 * 1024 ; // 通信結果を代入するバッファのサイズは 8MB( 足りない場合は増やしてください )
static int HTTP_DataBufferEnableBytes ;
private static void safetyClose(Closeable c) {
if (null == c) {
return;
}
try {
c.close();
} catch (Exception e) {
//log.debug("", e);
}
}
// 非同期で HTTP 通信するためのクラス
public class HTTP_ConnectTask extends Thread
{
public void run()
{
HttpURLConnection HTTPCon = null ;
URL url = null ;
try
{
// URLの作成
url = new URL( HTTP_URLString ) ;
// 接続用HttpURLConnectionオブジェクト作成
HTTPCon = ( HttpURLConnection )url.openConnection() ;
// メソッドタイプによって処理を分岐
switch( HTTP_MethodType )
{
case 0: // GET
HTTPCon.setRequestMethod( "GET" ) ;
HTTPCon.setDoOutput( false ) ;
break ;
case 1: // POST
HTTPCon.setRequestMethod( "POST" ) ;
HTTPCon.setDoOutput( true ) ;
break ;
case 2: // PUT
HTTPCon.setRequestMethod( "PUT" ) ;
HTTPCon.setDoOutput( true ) ;
break ;
}
HTTPCon.setDoInput( true ) ;
OutputStream outputStream = null;
try{
outputStream = HTTPCon.getOutputStream();
//outputStream.write("num1=12".getBytes(StandardCharsets.UTF_8));
outputStream.write(HTTP_POSTString.getBytes(StandardCharsets.UTF_8));
}finally {
safetyClose(outputStream);
}
// 接続
HTTPCon.connect() ;
// レスポンスコードの取得
HTTP_ResponseCode = HTTPCon.getResponseCode();
// 通信結果のデータを格納する配列がまだ未初期化の場合はここで初期化
if( HTTP_DataBuffer_Initialize == false )
{
HTTP_DataBuffer_Initialize = true;
HTTP_DataBuffer = new byte[ HTTP_DataBufferBytes ] ;
}
// 有効なデータのサイズを0にセット
HTTP_DataBufferEnableBytes = 0 ;
// 通信結果のデータを取得
InputStream in = HTTPCon.getInputStream() ;
int ReadSize = in.read( HTTP_DataBuffer ) ;
while( ReadSize > 0 )
{
HTTP_DataBufferEnableBytes += ReadSize ;
ReadSize = in.read( HTTP_DataBuffer, HTTP_DataBufferEnableBytes, HTTP_DataBufferBytes - HTTP_DataBufferEnableBytes ) ;
}
in.close() ;
} catch ( MalformedURLException e )
{
// MalformedURL例外が発生したらレスポンスコードを代入する変数に -3 を代入
HTTP_ResponseCode = -3 ;
// 例外のメッセージを取得する
HTTP_ExceptionMessage = e.toString() ;
} catch ( IOException e )
{
// IO例外が発生したらレスポンスコードを代入する変数に -2 を代入
HTTP_ResponseCode = -2 ;
// 例外のメッセージを取得する
HTTP_ExceptionMessage = e.toString() ;
}
// HTTP通信が完了したので 1 を代入する
HTTP_Connect_Finish = 1 ;
}
}
// HTTP通信を行う Java の関数
public void HTTP_Connect( String URLString, int Method ,String PostString)
{
// HTTP通信の完了を確認するための変数を初期化
HTTP_Connect_Finish = 0 ;
// 有効な取得データのサイズを初期化
HTTP_DataBufferEnableBytes = 0 ;
// レスポンスコードを初期化
HTTP_ResponseCode = -1 ;
// 非同期処理を行うクラスが参照できるようにグローバル変数に引数を代入
HTTP_URLString = URLString ;
HTTP_MethodType = Method ;
HTTP_POSTString = PostString;
// HTTP通信を非同期で行う為のクラスを作成・実行
HTTP_ConnectTask HTTPTask = new HTTP_ConnectTask() ;
HTTPTask.start() ;
}
}
出力結果
受信されたファイルは「12」です。array(1) { ["num1"]=> string(2) "12" }