Android Tutorial Inline Java Code

LucaMs

Expert
Licensed User
- The methods you add should be public methods.
- Methods in static code modules should be public static.
Am I wrong or you should write "must" instead of "should"? (my English is notoriously poor)

(This is my "first excellent technical comment" :D after about ten days of inactivity)
 

MarcoRome

Expert
Licensed User
Hi all i have this code:

B4X:
....
If FirstTime Then
NativeMe.InitializeContext
EndIf
Dim w AsBoolean
w = NativeMe.RunMethod("isInstalled", Null) ' <----- I thin kthat i have here ERROR
Log("Whatsapp " & w)
 
......
 
#If JAVA
import java.io.File;
import android.content.Context;
 
import java.util.ArrayList;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.util.Log;
 
private final static String WHATSSAP_APP_ID = "com.whatsapp";
private final static boolean DEBUG = false;
     
public final static int IMAGE_TYPE = 0;
public final static int AUDIO_TYPE = 1;
public final static int VIDEO_TYPE = 2;
     
    public final static boolean isInstalled(Context context){
         Boolean installed = false;
         try{
             PackageManager mPm = context.getPackageManager();
             PackageInfo info = mPm.getPackageInfo(WHATSSAP_APP_ID, 0);
             installed = info != null;
         }catch(Exception e){
             installed = false;
             if(DEBUG) Log.e("Exception", e.toString());
         }
         return installed;
     }
 
#End If
compile and when start app i have this error:

B4X:
** Activity (main) Create, isFirst = true **
 
java.lang.RuntimeException: Method: isInstalled not matched.
 
    at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:128)
    at b4a.example.main._activity_create(main.java:351)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
    at b4a.example.main.afterFirstLayout(main.java:112)
    at b4a.example.main.access$100(main.java:29)
    at b4a.example.main$WaitForLayout.run(main.java:90)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5017)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
    at dalvik.system.NativeStart.main(Native Method)
java.lang.RuntimeException: Method: isInstalled not matched.
Any idea ?
Thanks
 

mlc

Active Member
Licensed User
@mlc it is a bug in JavaObject library. It will only happen in debug mode. It is fixed for the next update.

The workaround is to call JavaObject.InitializeContext once from Activity_Create:
B4X:
If FirstTime Then
Dim jo As JavaObject
jo.InitializeContext
...
Thanks Erel
It is true in release mode works well.


DEbug rapid:

Can't use FirstTime, is a service.
But i have copied the code to the main, and I call it from the service this way:

B4X:
dim l as long
l =  Main.nativeMe.RunMethod("FreeSpace", Array(File.DirRootExternal))
Works well but, Is correct ?

Thanks
 

Philip Chatzigeorgiadis

Active Member
Licensed User
I understand how I can have more than one parameters of the same type (from previous posts):

NativeMe.Runmethod("methodName",Array("String1","String2"))

and

#If java
public void methodName(String s1,String s2){
BA.Log(s1 + " " + s2);
}#End If


But how can I have parameters of different types, e.g. a string and an int?
More important: Can I have a list or a Map as a parameter?
 

Johan Schoeman

Expert
Licensed User
I understand how I can have more than one parameters of the same type (from previous posts):

NativeMe.Runmethod("methodName",Array("String1","String2"))

and

#If java
public void methodName(String s1,String s2){
BA.Log(s1 + " " + s2);
}#End If


But how can I have parameters of different types, e.g. a string and an int?
More important: Can I have a list or a Map as a parameter?
NativeMe.Runmethod("methodname", Array(stringvariable name, integer variable name))

And then

Public void methodName(String s1, int myint){
Etc....
 

Rusty

Well-Known Member
Licensed User
I am trying to set the Google Verify Apps function OFF.
I've included inline java code to do this, but am having difficulty compiling this code:
B4X:
Sub Process_Globals
    Private NativeMe As JavaObject
End Sub

Sub Globals
End Sub

Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
           NativeMe.InitializeContext
    End If
    NativeMe.RunMethod("VerifyApp", Null)
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

#If JAVA
public String FirstMethod() {
   return "Hello World!";
}
public void VerifyApp() {
    boolean success = true;
    boolean enabled = Settings.Secure.getInt(context.getContentResolver(), "package_verifier_enable", 1) == 1;
    If (enabled) {
        success = Settings.Secure.putString(context.getContentResolver(), "package_verifier_enable", "0");
    }
}
#End If
I took the Hello world java from Erel's post and it compiles and works fine. The VerifyApp results in:
B4A version: 5.20
Parsing code. (0.00s)
Compiling code. (0.03s)
Compiling layouts code. (0.00s)
Generating R file. (0.05s)
Compiling debugger engine code. (0.74s)
Compiling generated Java code. Error
B4A line: 38
End Sub
javac 1.8.0_51
src\b4a\example\main.java:387: error: ';' expected
If (enabled) {
^
1 error
For some reason, I'm not seeing the error in the Java code. Any suggestions would be appreciated.
Thanks,
Rusty
 

Rusty

Well-Known Member
Licensed User
Thanks Siam.
I corrected that and it still doesn't work.
B4X:
#If JAVA
public void VerifyApp() {
    Settings.Secure.putString(context.getContentResolver(), "package_verifier_enable", "0");
    }
#End If
it is complaining about:
javac 1.8.0_51
src\b4a\example\main.java:1222: error: cannot find symbol
Settings.Secure.putString(context.getContentResolver(), "package_verifier_enable", "0");
^
symbol: variable context
location: class main
I am trying to set the Google Verify Apps function OFF. Is there a better way?
thanks,
Rusty
 

Informatix

Expert
Licensed User
Thanks Siam.
I corrected that and it still doesn't work.
B4X:
#If JAVA
public void VerifyApp() {
    Settings.Secure.putString(context.getContentResolver(), "package_verifier_enable", "0");
    }
#End If
it is complaining about:
javac 1.8.0_51
src\b4a\example\main.java:1222: error: cannot find symbol
Settings.Secure.putString(context.getContentResolver(), "package_verifier_enable", "0");
^
symbol: variable context
location: class main
I am trying to set the Google Verify Apps function OFF. Is there a better way?
thanks,
Rusty
Replace Settings.Secure by android.provider.Settings.Secure and context by getApplicationContext(), then set the appropriate permissions in the manifest.
 

Rusty

Well-Known Member
Licensed User
Perfect! Thanks Informatix!
I changed it to:
B4X:
#If JAVA
public void VerifyApp() {
    boolean success = true;
    boolean enabled = android.provider.Settings.Secure.getInt(getApplicationContext().getContentResolver(), "package_verifier_enable", 1) == 1;
    if (enabled) {
        success = android.provider.Settings.Secure.putString(getApplicationContext().getContentResolver(), "package_verifier_enable", "0");    }
}
#End If
With manifest change of:
B4X:
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
Compiles ...:)
Thanks,
Rusty
 

Rusty

Well-Known Member
Licensed User
I have another in-line Java question.
I would like to display the available widgets from which the user can select and drag to their home screen.

I've tried to include this:
B4X:
#If JAVA
public void widgetctl() {
    Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
    pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetID);
    startActivityForResult(pickIntent, KEY_CODE);
}
#End if
In my previous post, Informatix suggested "android.provider.Settings.Secure" changes.
I am not clear as to how to determine what changes are required to make Java actually work within the B4a environment.
Any suggestions are appreciated.
Thanks,
Rusty
 

Rusty

Well-Known Member
Licensed User
Thanks Erel!

SORRY, I HAVE MOVED THIS TO A NEW THREAD...
Inline Java intents

question on that post though, shouldn't the below sub be "Sub GetBA as JavaObject"?
B4X:
Sub GetBA As Object
   Dim jo As JavaObject
   Dim cls As String = Me
   cls = cls.SubString("class ".Length)
   jo.InitializeStatic(cls)
   Return jo.GetField("processBA")
End Sub
Also, where can I find a list of intents and when do we preface the intent with "android.intent.action.xxxxxxx"?

Regards,
Rusty
 
Last edited:

Lee Gillie CCP

Active Member
Licensed User
Probably doing some dumb nu-bee thing, here, but this keeps failing at runtime, and I can't see the problem.

I am calling from a Module named Globals

B4X:
Sub Process_Globals
    ...
    Private NativeMe As JavaObject
End Sub
B4X:
Public Sub Init
     ...
     NativeMe.InitializeContext
End Sub

#if JAVA
public static anywheresoftware.b4a.objects.collections.List GetStackTraceJava()
{
    anywheresoftware.b4a.objects.collections.List _lst = null;
    _lst = new anywheresoftware.b4a.objects.collections.List();
    _lst.Initialize();
    _lst.Add((Object)("Test 1"));
    _lst.Add((Object)("Test 2"));
    if (true) return _lst;
    return null;
}
#End If

Public Sub GetStackTrace() As List
    Return NativeMe.RunMethod("GetStackTraceJava",Null)
End Sub
and the failure I see is...

globals_getstacktrace (java line: 348)
java.lang.RuntimeException: Method: GetStackTraceJava not found in: odp.eljaydelivery.main
at anywheresoftware.b4j.object.JavaObject$MethodCache.getMethod(JavaObject.java:367)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:118)
at odp.eljaydelivery.globals._getstacktrace(globals.java:348)
at odp.eljaydelivery.globals._reporterror(globals.java:922)
at odp.eljaydelivery.main._btntest_click(main.java:513)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:171)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:78)
at android.view.View.performClick(View.java:4764)
at android.view.View$PerformClick.run(View.java:19844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5376)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
java.lang.RuntimeException: Method: GetStackTraceJava not found in: odp.eljaydelivery.main
Any clues would be greatly appreciated.
 
Top