Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

[[ Bug 22950 ]] Starting Activities and Handling Results #7458

Open
wants to merge 2 commits into
base: develop
Choose a base branch
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
35 changes: 34 additions & 1 deletion 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 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
6 changes: 6 additions & 0 deletions extensions/modules/android-utils/notes/22950.md
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.