Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

[[ Intents ]] Implement OnActivityResultListener #6844

Open
wants to merge 4 commits into
base: develop
Choose a base branch
Loading
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions 10 docs/lcb/notes/feature-jobjectarray.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# LiveCode Builder Standard Library

## Java Utilities

Syntax for converting between a JObjectArray and a List of JObjects have been
added to the Java utility library.

* The alias `JObjectArray` has been added to aid readability
* `ListToJObjectArray` - converts a List of JObjects to a JObjectArray
* `ListFromJObjectArray` - converts a JObjectArray to a List of JObjects
35 changes: 34 additions & 1 deletion 35 engine/src/java/com/runrev/android/LiveCodeActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import android.util.*;
import android.content.pm.PackageManager;
import android.graphics.*;
import java.util.*;

// This is the main activity exported by the application. This is
// split into two parts, a customizable sub-class that gets dynamically
Expand All @@ -37,6 +38,8 @@ public class LiveCodeActivity extends Activity
public static FrameLayout s_main_layout;
public static Engine s_main_view;

private HashMap<Integer, OnActivityResultListener> m_activity_result_listeners;

//////////

public LiveCodeActivity()
Expand Down Expand Up @@ -86,6 +89,9 @@ public void onGlobalLayout()
s_main_view.updateKeyboardVisible();
}
});

m_activity_result_listeners = new HashMap<Integer, OnActivityResultListener>();

}

@Override
Expand Down Expand Up @@ -203,11 +209,38 @@ else if (keyCode == KeyEvent.KEYCODE_SEARCH && event.getRepeatCount() == 0)

////////////////////////////////////////////////////////////////////////////////

public interface OnActivityResultListener
{
public void onActivityResult (int p_request_code, int p_result_code, Intent p_data);
}

public void setOnActivityResultListener(OnActivityResultListener p_listener, int p_request_code)
{
Integer t_request_code = Integer.valueOf(p_request_code);
m_activity_result_listeners.put(t_request_code, p_listener);
}

public void removeOnActivityResultListener(int p_request_code)
{
Integer t_request_code = Integer.valueOf(p_request_code);
m_activity_result_listeners.remove(t_request_code);
}

//
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data)
{
s_main_view.onActivityResult(requestCode, resultCode, data);
// activity resuult listeners override any engine request code handlers
Integer t_request_code = Integer.valueOf(requestCode);
OnActivityResultListener t_listener = m_activity_result_listeners.get(t_request_code);
if (t_listener != null)
{
t_listener.onActivityResult(requestCode, resultCode, data);
}
else
{
s_main_view.onActivityResult(requestCode, resultCode, data);
}
}

// Callback sent when the app requests permissions on runtime (Android API 23+)
Expand Down
148 changes: 147 additions & 1 deletion 148 extensions/modules/android-utils/android-utils.lcb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use com.livecode.java
use com.livecode.canvas
use com.livecode.library.widgetutils

metadata version is "1.0.0"
metadata version is "1.1.0"
metadata author is "LiveCode"
metadata title is "Android Utilities"
metadata os is "android"
Expand Down Expand Up @@ -90,6 +90,152 @@ public handler ApplicationContext() returns JObject
return _JNI_GetEngineContext(_JNI_GetAndroidEngine())
end handler

private variable sResultListeners as Array

public handler type OnActivityResultHandler(\
in pRequestCode as JInt, \
in pResultCode as JInt, \
in pIntent as optional JObject) returns nothing

handler _OnActivityResultListener(\
in pRequestCode as JObject, \
in pResultCode as JObject, \
in pIntent as optional JObject) returns nothing

variable tContext as JObject
put ApplicationContext() into tContext

variable tRequestCode as JInt
put _JNI_NumberIntValue(pRequestCode) into tRequestCode
variable tResultCode as JInt
put _JNI_NumberIntValue(pResultCode) into tResultCode

_JNI_LiveCodeActivityRemoveOnActivityResultListener(tContext, tResultCode)

variable tRequestCodeString as String
put tRequestCode formatted as string into tRequestCodeString

if tRequestCodeString is among the keys of sResultListeners then
variable tHandler as OnActivityResultHandler
put sResultListeners[tRequestCodeString] into tHandler
delete sResultListeners[tRequestCodeString]
tHandler(tRequestCode, tResultCode, pIntent)
end if
end handler

__safe foreign handler _JNI_LiveCodeActivityOnActivityResultListener( \
in pCallbacks as Array) returns JObject \
binds to "java:com.runrev.android.LiveCodeActivity$OnActivityResultListener>interface()"

__safe foreign handler _JNI_LiveCodeActivitySetOnActivityResultListener( \
in pEngine as JObject, \
in pListener as JObject, \
in pRequestCode as JInt) returns nothing \
binds to "java:com.runrev.android.LiveCodeActivity>setOnActivityResultListener(Lcom/runrev/android/LiveCodeActivity$OnActivityResultListener;I)V"

__safe foreign handler _JNI_LiveCodeActivityRemoveOnActivityResultListener( \
in pEngine as JObject, \
in pRequestCode as JInt) returns nothing \
binds to "java:com.runrev.android.LiveCodeActivity>removeOnActivityResultListener(I)V"

__safe foreign handler _JNI_ActivityStartActivityForResult( \
in pActivity as JObject, \
in pIntent as JObject, \
in pRequestCode as JInt) \
returns nothing \
binds to "java:android.app.Activity>startActivityForResult(Landroid/content/Intent;I)V"

__safe foreign handler _JNI_NumberIntValue(in pNumber as JObject) returns JInt \
binds to "java:java.lang.Number>intValue()I"

/**
Summary: Start an activity by Intent

Example:

constant kIntentACTION_SEND is "android.intent.action.SEND"
constant kIntentEXTRA_TEXT is "android.intent.extra.TEXT"
constant kActivityRESULT_CANCELED is 0
constant kShareStringRequestCode is 123

__safe foreign handler _JNI_IntentNew(in pAction as JString) \
returns JObject \
binds to "java:android.content.Intent>new(Ljava/lang/String;)"

__safe foreign handler _JNI_IntentSetType(in pIntent as JObject, \
in pType as JString) \
returns JObject \
binds to "java:android.content.Intent>setType(Ljava/lang/String;)Landroid/content/Intent;"

__safe foreign handler _JNI_IntentPutExtraString(in pIntent as JObject, \
in pType as JString, \
in pValue as JString) \
returns JObject \
binds to "java:android.content.Intent>putExtra(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;"

handler _ShareStringResultListener( \
in pRequestCode as JInt, \
in pResultCode as JInt, \
in pIntent as optional JObject) returns nothing

if pResultCode is kActivityRESULT_CANCELED then
post "shareStringCancelled"
else
post "shareStringComplete"
end if
end handler

public handler ShareString(in pString as String) returns nothing
variable tIntent as JObject
put _JNI_IntentNew(StringToJString(kIntentACTION_SEND)) into tIntent

_JNI_IntentSetType(tIntent, StringToJString("text/plain"))

_JNI_IntentPutExtraString(tIntent, StringToJString(kIntentEXTRA_TEXT), \
StringToJString(pString))

StartActivityForResult(tIntent, kShareStringRequestCode, _ShareStringResultListener)
end handler

Parameters:
pIntent: An Intent JObject to use to start an activity
pRequestCode: A positive integer used to identify the request when handling
`onActivityResult`.
pHandler: A handler that conforms to the `OnActivityResultHandler` type

Description:
Start an activity by Intent and receive a callback to the specified handler when
the LiveCode activity receives the result via the `onActivityResult` method.

The callback must conform to the `OnActivityResultHandler` type which returns
nothing and has parameters:

- in pRequestCode as JInt
- in pResultCode as JInt
- in pIntent as optional JObject

*/

public handler StartActivityForResult( \
in pIntent as JObject, \
in pRequestCode as JInt, \
in pHandler as OnActivityResultHandler) returns nothing

variable tContext as JObject
put ApplicationContext() into tContext

variable tListener as JObject
put _JNI_LiveCodeActivityOnActivityResultListener(\
{"onActivityResult" : _OnActivityResultListener }) into tListener

_JNI_LiveCodeActivitySetOnActivityResultListener(tContext, tListener, pRequestCode)

put pHandler into sResultListeners[pRequestCode formatted as string]

_JNI_ActivityStartActivityForResult(tContext, pIntent, pRequestCode)
end handler


private foreign handler MCAndroidCheckRuntimePermission(in pPermission as String) \
returns CBool binds to "<builtin>"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Starting Activities and Handling Results

A new handler has been added to facilitate starting activities by Intent and
handling results. The `StartActivityForResult` handler registers a listener to
handle the `onActivityResult` method of the engine activity and when handled
calls a callback handler with the request code, result code and Intent object.
5 changes: 4 additions & 1 deletion 5 libfoundation/include/foundation.h
Original file line number Diff line number Diff line change
Expand Up @@ -2008,7 +2008,10 @@ MC_DLLEXPORT bool MCJavaConvertStringRefToJString(MCStringRef p_string, MCJavaOb
MC_DLLEXPORT bool MCJavaConvertJByteArrayToDataRef(MCJavaObjectRef p_object, MCDataRef &r_data);
// Convert a Data Ref to a Java object wrapping a jByteArray
MC_DLLEXPORT bool MCJavaConvertDataRefToJByteArray(MCDataRef p_data, MCJavaObjectRef &r_object);


MC_DLLEXPORT bool MCJavaConvertProperListRefToJObjectArray(MCProperListRef p_list, MCStringRef p_class_name, MCJavaObjectRef &r_obj_array);
MC_DLLEXPORT bool MCJavaConvertJObjectArrayToProperListRef(MCJavaObjectRef p_obj_array, MCProperListRef &r_list);

////////////////////////////////////////////////////////////////////////////////
//
// BOOLEAN DEFINITIONS
Expand Down
51 changes: 51 additions & 0 deletions 51 libfoundation/src/foundation-java-private.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,46 @@ static bool __MCJavaProperListFromJObjectArray(jobjectArray p_obj_array, MCPrope
return MCProperListCopy(*t_list, r_list);
}

bool MCJavaPrivateProperListFromJObjectArray(MCJavaObjectRef p_obj_array, MCProperListRef& r_list)
{
jobjectArray t_obj_array = static_cast<jobjectArray>(MCJavaObjectGetObject(static_cast<MCJavaObjectRef>(p_obj_array)));
if (t_obj_array == nullptr)
{
return false;
}

return __MCJavaProperListFromJObjectArray(t_obj_array, r_list);
}

static jclass MCJavaPrivateFindClass(MCNameRef p_class_name);

bool MCJavaPrivateProperListToJObjectArray(MCProperListRef p_list, MCNameRef p_class_name, MCJavaObjectRef &r_obj_array)
{
MCJavaDoAttachCurrentThread();

jclass t_class = MCJavaPrivateFindClass(p_class_name);

uindex_t t_size = MCProperListGetLength(p_list);
jobjectArray t_obj_array = s_env -> NewObjectArray(t_size, t_class, nullptr);

if (t_obj_array == nullptr)
return false;

for (uint32_t i = 0; i < t_size; i++)
{
MCValueRef t_value;
t_value = MCProperListFetchElementAtIndex(p_list, i);
if (MCValueGetTypeInfo(t_value) == MCJavaGetObjectTypeInfo())
{
jobject t_object = static_cast<jobject>(MCJavaObjectGetObject(static_cast<MCJavaObjectRef>(t_value)));

s_env -> SetObjectArrayElement(t_obj_array, i, t_object);
}
}

return MCJavaObjectCreate(t_obj_array, r_obj_array);
}

void* MCJavaPrivateGlobalRef(void *p_object)
{
MCJavaDoAttachCurrentThread();
Expand Down Expand Up @@ -2044,4 +2084,15 @@ void* MCJavaPrivateGlobalRef(void *p_object)
{
return p_object;
}

bool MCJavaPrivateProperListFromJObjectArray(MCJavaObjectRef p_obj_array, MCProperListRef& r_list)
{
return false;
}

bool MCJavaPrivateProperListToJObjectArray(MCProperListRef p_list, MCNameRef p_class_name, MCJavaObjectRef &r_obj_array)
{
return false;
}

#endif
3 changes: 3 additions & 0 deletions 3 libfoundation/src/foundation-java-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ void MCJavaPrivateDestroyObject(MCJavaObjectRef p_object);
bool MCJavaPrivateCheckSignature(MCTypeInfoRef p_signature, MCStringRef p_args, MCStringRef p_return, int p_call_type);
bool MCJavaPrivateGetJObjectClassName(MCJavaObjectRef p_object, MCStringRef &r_name);

bool MCJavaPrivateProperListFromJObjectArray(MCJavaObjectRef p_obj_array, MCProperListRef& r_list);
bool MCJavaPrivateProperListToJObjectArray(MCProperListRef p_list, MCNameRef p_class_name, MCJavaObjectRef &r_obj_array);

void* MCJavaPrivateGlobalRef(void *p_object);

bool MCJavaPrivateErrorThrow(MCTypeInfoRef p_error);
Expand Down
19 changes: 19 additions & 0 deletions 19 libfoundation/src/foundation-java.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,22 @@ MC_DLLEXPORT bool MCJavaGetJObjectClassName(MCJavaObjectRef p_object, MCStringRe

return MCJavaPrivateGetJObjectClassName(p_object, r_name);
}

MC_DLLEXPORT bool MCJavaConvertProperListRefToJObjectArray(MCProperListRef p_list, MCStringRef p_class_name, MCJavaObjectRef &r_obj_array)
{
if (!s_java_initialised)
return MCJavaPrivateErrorThrow(kMCJavaJRENotSupportedErrorTypeInfo);

MCNewAutoNameRef t_class_name;
return MCNameCreate(p_class_name, &t_class_name) && \
MCJavaPrivateProperListToJObjectArray(p_list, *t_class_name, r_obj_array);
}

MC_DLLEXPORT bool MCJavaConvertJObjectArrayToProperListRef(MCJavaObjectRef p_obj_array, MCProperListRef &r_list)
{
if (!s_java_initialised)
return MCJavaPrivateErrorThrow(kMCJavaJRENotSupportedErrorTypeInfo);

return MCJavaPrivateProperListFromJObjectArray(p_obj_array, r_list);
}

Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.