Java Question Need help with Samsung Galaxy Note SPen SDK

thedesolatesoul

Expert
Licensed User
Longtime User
I just wanted to add my humble observations to the discussion.

As far as I can see the SDK library wants to access some resources for the SettingsView. These are packaged within the library (JAR file).
When we try to build a b4a library, these resources are lost. Thus causing the NullPointerException.

In the SDK JAR, these are located in /resource/drawable-xhdpi/xxx.png

I dont know if there is a way to make these inbuilt resources available in B4A.

Copying these to Objects/res or Objects/resource does not work and the 9patch images seem to bomb out.
 

XverhelstX

Well-Known Member
Licensed User
Longtime User
OK, So after the release of 2.0, Basic4Android had support for Internal handling of library files.

I've still been trying to work on this Samsung Galaxy SPen sdk and I still have no good solutions found. Here are my findings:

B4A-code
B4X:
Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.
   Dim cv As RSCanvasView
   Dim sv As RSSettingView

End Sub

Sub Activity_Create(FirstTime As Boolean)
   cv.Initialize("RSCanvas")
   sv.Initialize("Setting")
   Activity.AddMenuItem("Register","mnuRegister")
   Activity.AddMenuItem("Show Pen","mnuPen")
   Activity.AddMenuItem("Hide","mnuHide")
   
End Sub

Sub mnuRegister_Click
   cv.RegisterSettingView(sv)
End Sub

Sub mnuPen_Click
   sv.showView(0)
End Sub

Sub mnuHide_Click
   sv.showView(1)
End Sub

Sub RSCanvas_Success (Success As Boolean)
   Msgbox("Registered","")
End Sub


Notes:
- RSCanvas_Success is never called
- ShowView doesn't work
- No error messages displayed.


Java CanvasView Code
B4X:
package com.rootsoft.spen;

import com.samsung.sdraw.CanvasView;
import com.samsung.sdraw.CanvasView.InitializeFinishListener;
import com.samsung.sdraw.SettingView;

import anywheresoftware.b4a.BA.ActivityObject;
import anywheresoftware.b4a.BA.Author;
import anywheresoftware.b4a.BA.DependsOn;
import anywheresoftware.b4a.BA.DontInheritEvents;
import anywheresoftware.b4a.BA.Events;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;
import anywheresoftware.b4a.*;
import anywheresoftware.b4a.objects.ViewWrapper;


@ShortName("RSCanvasView")
@Events(values={"Success"})
@Author("XverhelstX")
@Version(1.0f)
@ActivityObject
@DontInheritEvents
@Permissions(values={"android.permission.INTERNET", "android.permission.ACCESS_NETWORK_STATE"})
@DependsOn(values = { "libspen20" })
public class CanvasViewWrapper extends ViewWrapper<CanvasView> {
   

    /**
     *    Initializes the CanvasView
     *    EventName - Name of Subs that will handle the events.
     */
    public void Initialize(final BA ba, String EventName) {
        setObject(new CanvasView(ba.activity));
        super.Initialize(ba, EventName);
        final String eventName = EventName.toLowerCase(BA.cul);
        getObject().setInitializeFinishListener(new InitializeFinishListener() {
            
            @Override
            public void onFinish() {
                // TODO Auto-generated method stub
                ba.raiseEvent(getObject(), eventName + "_success", true);
            }
            
        });
    }

    /**
     * Register the SettingView to the CanvasView.
     */
    public void RegisterSettingView(SettingView sv) {
        getObject().setSettingView(sv);
    }

}

Java Settingview Code:

B4X:
package com.rootsoft.spen;

import com.samsung.sdraw.SettingView;

import anywheresoftware.b4a.BA.ActivityObject;
import anywheresoftware.b4a.BA.DependsOn;
import anywheresoftware.b4a.BA.DontInheritEvents;
import anywheresoftware.b4a.BA.Events;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.*;
import anywheresoftware.b4a.objects.ViewWrapper;


@ShortName("RSSettingView")
@Events(values={"Success"})
@ActivityObject
@DontInheritEvents
@Permissions(values={"android.permission.INTERNET", "android.permission.ACCESS_NETWORK_STATE"})
public class SettingViewWrapper extends ViewWrapper<SettingView> {
 
    /**
     *    Initializes the SettingView
     *    EventName - Name of Subs that will handle the events.
     */
    public void Initialize(final BA ba, String EventName) {
       setObject(new SettingView(ba.activity));
        super.Initialize(ba, EventName);
        final String eventName = EventName.toLowerCase(BA.cul);

    }
    
    
    
    /**
     * Control the pen or eraser functions.
     * @param tool
     */
    public void showView(int tool) {
        getObject().showView(tool);
    }
    
    /**
     * Close view
     * @param tool
     */
    public void closeView(int tool) {
        getObject().closeView();
    }


}


AVD Galaxy Note on Emulator:


Acer Iconia Tab a510 & Xperia PLAY:


i'd like to have some more input on this and any findings in the log as I'm currently stuck.

Sincerely,
Tomas
 

XverhelstX

Well-Known Member
Licensed User
Longtime User
Ok, thanks Erel.
After some little more trial and error, i figured out I had to call addView from an activity or panel. Now it is working fine, and I am adding more features to the library.

But recently, the SDK has been updated to 2.1 which changed some things in the constructor for registering the Settingscreen of the SCanvasView.


Now the method setSettingView is deprecated and we need to use other parameters with that function.


Unfortunately I have no idea what parameter to give in in settingViewParent ViewGroup.

Any idea?

Tomas

EDIT:

When passing a panel as the viewgroup parameter i got the following error:

java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to anywheresoftware.b4a.BALayout$LayoutParams

B4X:
 /**
     * Register the SettingView to the CanvasView.
     */
    public void RegisterSettingView(PanelWrapper pnl, SettingView sv, boolean bClearAllVisibileInEraserSetting) {
        getObject().setSettingView(pnl.getObject(), sv, bClearAllVisibileInEraserSetting);
    }


B4X:
cv.RegisterSettingView(pnlPen, sv, True)
 
Last edited:

XverhelstX

Well-Known Member
Licensed User
Longtime User
So i'd need to change the type from a BALayout to a FrameLayout from the panel? I cannot seem to find which method to use.

Tomas

EDIT:


here the full log message as i cannot seem to find how to change the layout type

Javadoc available here
 
Last edited:

warwound

Expert
Licensed User
Longtime User
I have now helped Tomas fix this.

The class cast and layout exceptions were a bit misleading.
Then Tomas got another exception:

java.lang.IllegalStateException: The specified child already has a parent.

It took a little while but we established that his library RSSettingView object which is passed to the library RegisterSettingView method must NOT already be added to the Activity when that method is called.

After that method has been called it is ok to add the RSSettingsView to the Activity - a B4A Panel in this case.

All fixed and working now but the original exception messages would never have helped debug the error!

Martin.
 

XverhelstX

Well-Known Member
Licensed User
Longtime User
After some more looking, all other methods called would raise a nullpointer.

We checked if the parent was null of the view, and it was. So we meed to try how erel suggested, but we cant find out how to cast it.

Martin (warwound) and me have already broken our head on the code. I've spend a week already trying to get this to work and as we thought we had solved it, we didn't.

Samsung has launched the smartappchallenge and we want to finish this library as soon as possible so other users can participate in this challenge too.

Martin is wondering: is the method doing something to the B4A panel so it is no longer a B4A panel but an android viewgroup. when b4a tries to access the panel as a b4a panel its layout has been changed by the library method.

But we also can't seem to find on how to change the layout type as you suggested: Seems like it expects a view with a different type of LayoutParams. You can set the panel's LayoutParams to this type.

I really have no clue how i would change the panel's layout by this and I hope you would show us the code how it is done.

I would really appreciate that.

Regards, Tomas
 

XverhelstX

Well-Known Member
Licensed User
Longtime User
Do you mean create a b4a view programmaticallt and give it as a parameter viewgroup of registersettingview?

I thought a panel because its extends viewgroup.

So i cast viewgroup to the b4a view?

Tomas

Sent from my SE Xperia Play using Tapatalk.
 

thedesolatesoul

Expert
Licensed User
Longtime User
But we also can't seem to find on how to change the layout type as you suggested: Seems like it expects a view with a different type of LayoutParams. You can set the panel's LayoutParams to this type.

Have you tried pnl.GetObject().setLayoutParams
If it is expecting a FrameLayout create one.

B4X:
pnl.GetObject().setLayoutParams  = new FrameLayout.LayoutParams (int width, int height);


Why do you use a panel at all? You can create a standard view and use it instead.
I think it will be easier.
Are you saying create a new ViewGroup inside RegisterSettingView, assign it to a parent and set the layout, and then pass that to the next function?
 

XverhelstX

Well-Known Member
Licensed User
Longtime User
I tried both these codes:

B4X:
/**
     * Register the SettingView to the CanvasView.
     */
    public void RegisterSettingView(PanelWrapper Panel, SettingView sv, boolean bClearAllVisibileInEraserSetting) {
       ViewGroup vp;
       vp = Panel.getObject();
       vp.setLayoutParams(new FrameLayout.LayoutParams (Panel.getObject().getWidth(), Panel.getObject().getHeight()));
       getObject().setSettingView(vp, sv, bClearAllVisibileInEraserSetting);
        
    }
    
    /**
     * Register the SettingView to the CanvasView.
     */
    public void RegisterSettingView2(PanelWrapper Panel, SettingView sv, boolean bClearAllVisibileInEraserSetting) {
       Panel.getObject().setLayoutParams(new FrameLayout.LayoutParams (Panel.getObject().getWidth(), Panel.getObject().getHeight()));
       getObject().setSettingView(Panel.getObject(), sv, bClearAllVisibileInEraserSetting);
        
    }

which results in a:
java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to anywheresoftware.b4a.BALayout$LayoutParams
again.

I'm gonne try the native view class now as Erel suggested.

Tomas
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…