Math

Answered

MyScript Integration is not working for fragments

What is functional: I am able to integrate myScript for activities

What is that I am trying to do: I am trying to integrate myScript in fragments ( Does Integration does not work in fragments ? )


Error I am facing:

2020-02-24 13:16:52.905 14060-14060/? E/AndroidRuntime: FATAL EXCEPTION: main

    Process: com.cnx.kneurateach.debug, PID: 14060

    java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter oldPart

        at com.cnx.kneurateach.text.inputrecogniser.mathRecogniser.MathRecogniserFrag$setEditorListener$1.partChanging(Unknown Source:7)

        at com.myscript.iink.Editor$1.accept(Editor.java:121)

        at com.myscript.iink.Editor$1.accept(Editor.java:117)

        at com.myscript.iink.ListenerList.forEach(ListenerList.java:50)

        at com.myscript.iink.Editor.partChanging(Editor.java:116)

        at com.myscript.iink.Editor.setPart(Editor.java:244)

        at com.cnx.kneurateach.text.inputrecogniser.mathRecogniser.DocumentController.setPart(DocumentController.java:122)

        at com.cnx.kneurateach.text.inputrecogniser.mathRecogniser.DocumentController.openPart(DocumentController.java:316)

        at com.cnx.kneurateach.text.inputrecogniser.mathRecogniser.MathRecogniserFrag$setdocumentController$1.run(MathRecogniserFrag.kt:108)

        at android.os.Handler.handleCallback(Handler.java:873)

        at android.os.Handler.dispatchMessage(Handler.java:99)

        at android.os.Looper.loop(Looper.java:193)

        at android.app.ActivityThread.main(ActivityThread.java:6865)

        at java.lang.reflect.Method.invoke(Native Method)

        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:504)

        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)


Best Answer

Dear Devrath,


the above code doesn't help at all.


Just set a break point line 315 of the DocumentController.java file (openPart function). This looks like a coding issue.


Best regards,


Olivier


Dear Devrath,


thank you for contacting us and your question.


Currently, it more looks like you are setting a "null part" when calling the setPart function. Can you please check this?


Also, rather than using the Demo sample, we recommend you refer to our getStarted, which is easier to implement.


Best regards,


Olivier

HI Oliver, 

I have posted the complete fragment code below 

I have Used the same code for DocumentControlle from sample (Error arises in document controller)

Can you point me out which part I might be setting wrongly  

class MathRecogniserFrag : Fragment() {

    private val TAG = MathRecogniserFrag::class.java.simpleName as String

    var toolbarView: ToolbarView? = null
    var engine: Engine? = null

    lateinit var editorView: EditorView

    var documentController: DocumentController? = null

    /** ******************** LIFE CYCLE Methods *************** **/
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initOnCreate()
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return initOnCreateView(inflater, container, savedInstanceState)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        initOnActivityCreated()
    }
    /** ******************** LIFE CYCLE Methods *************** **/


    /** ******************** INIT Methods ******************** **/
    /** Init OnCreate **/
    private fun initOnCreate() {
        activity!!.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
        //Initialize the My Script engine
        engine = KneuraTeachApp.KneuraMyScript.engine
        //Configure the recognition
        configureRecognition()
    }

    /** Init OnCreateView **/
    private fun initOnCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.math_recogniser_frag, container, false)
        //initviews(view)
        editorView = view.findViewById(R.id.editor_view)
        return view
    }

    /** Init OnActivityCreated **/
    private fun initOnActivityCreated() {
        //Load the fonts
        loadTheFonts()
        //Set the engine object
        editorView.setEngine(this.engine!!)
        //Set click listeners
        setClickListeners()
        //Set editor listener
        setEditorListener()
        //Document controller
        setdocumentController()
    }

    private fun setdocumentController() {

        documentController = DocumentController(activity, editorView)
        val fileName = documentController!!.savedFileName
        val partIndex = documentController!!.savedPartIndex

        // wait for view size initialization before setting part
        editorView.post {
            if (fileName != null)
                documentController!!.openPart(fileName, partIndex)
            else
                documentController!!.newPart()
        }
    }

    /** Load the fonts **/
    private fun loadTheFonts() {
        val assetManager = activity!!.applicationContext!!.assets
        val typefaceMap = FontUtils.loadFontsFromAssets(assetManager)
        editorView.setTypefaces(typefaceMap)
    }

    /** Set the editor listener **/
    private fun setEditorListener() {
        val editor = editorView.editor
        editor!!.addListener(object : IEditorListener {
            override fun partChanging(editor: Editor, oldPart: ContentPart, newPart: ContentPart) {
                // no-op
            }

            override fun partChanged(editor: Editor) {
                requireActivity().invalidateOptionsMenu()
                //invalidateIconButtons()
            }

            override fun contentChanged(editor: Editor, blockIds: Array<String>) {
                requireActivity().invalidateOptionsMenu()
                //invalidateIconButtons()
            }

            override fun onError(editor: Editor, blockId: String, message: String) {
                Timber.e(TAG, "Failed to edit block \"$blockId\"$message")
            }
        })

        editorView.imageLoader = ImageLoader(editor, activity!!.cacheDir)
        editorView.setInputControllerListener { x, y, contentBlock ->
            displayContextMenu(
                x,
                y,
                contentBlock
            )
        }
    }

    private fun displayContextMenu(x: Float, y: Float, contentBlock_: ContentBlock?): Boolean {
        val editor = editorView.editor

        val part = editor!!.part ?: return true

        val rootBlock = editor!!.rootBlock
        val contentBlock =
            if ((contentBlock_ != null) && contentBlock_!!.type != "Container") contentBlock_ else rootBlock

        val isRoot = contentBlock.id == rootBlock.id

        val onRawContent = part.type == "Raw Content"
        val onTextDocument = part.type == "Text Document"

        val isEmpty = editor.isEmpty(contentBlock)

        val supportedTypes = editor.supportedAddBlockTypes
        //final MimeType[] supportedExports = editor.getSupportedExportMimeTypes(onRawContent ? rootBlock : contentBlock);
        //final MimeType[] supportedImports = editor.getSupportedImportMimeTypes(contentBlock);
        val supportedStates = editor.getSupportedTargetConversionStates(contentBlock)

        val hasTypes = supportedTypes.size > 0
        //final boolean hasExports = supportedExports.length > 0;
        //final boolean hasImports = supportedImports.length > 0;
        val hasStates = supportedStates.size > 0

        val displayConvert = hasStates && !isEmpty
        val displayAddBlock = hasTypes && isRoot
        val displayAddImage = false // hasTypes && isRoot;
        val displayRemove = !isRoot
        val displayCopy = (if (onTextDocument) !isRoot else !onRawContent)
        val displayPaste = hasTypes && isRoot
        val displayImport = false // hasImports;
        val displayExport = false // hasExports;

        val items = ArrayList<String>()

        if (displayAddBlock) {
            for (blockType in supportedTypes)
                items.add("Add $blockType")
        }

        if (displayAddImage)
            items.add("Add Image")

        if (displayRemove)
            items.add("Remove")

        if (displayConvert)
            items.add("Convert")

        if (displayCopy)
            items.add("Copy")

        if (displayPaste)
            items.add("Paste")

        if (displayImport)
            items.add("Import")

        if (displayExport)
            items.add("Export")

        if (items.isEmpty())
            return true

        val dialogBuilder = AlertDialog.Builder(activity)
        dialogBuilder.setTitle(contentBlock.type + " (id: " + contentBlock.id + ")")
        dialogBuilder.setItems(
            items.toTypedArray()
        ) { dialog, which ->
            try {
                val item = items[which]

                if (item == "Convert") {
                    editor!!.convert(contentBlock, supportedStates[0])
                } else if (item == "Remove") {
                    editor!!.removeBlock(contentBlock)
                } else if (item == "Copy") {
                    editor!!.copy(contentBlock)
                } else if (item == "Paste") {
                    editor!!.paste(x, y)
                } else if (item == "Import") {
                    // TODO
                } else if (item == "Export") {
                    // TODO
                } else if (item == "Add Image") {
                    //addImage(x, y)
                } else if (item.startsWith("Add ")) {
                    val blockType = item.substring(4)
                    //addBlock(x, y, blockType)
                }
            } catch (e: Exception) {
                Toast.makeText(activity, "Operation failed : " + e.message, Toast.LENGTH_LONG)
                    .show()
            }

            dialog.dismiss()
        }
        dialogBuilder.show()
        return true
    }


    /** ******************** INIT Methods ******************** **/

    /** ******************** Custom Methods ****************** **/

    /** All the click events in screen **/
    private fun setClickListeners() {
        tvRecoClear.setOnClickListener {
            //Clear the widget
            // TODO("Clear the widget")
        }

        tvcloseTextTool.setOnClickListener {
            //Clear the widget
            saveBitMapToStorage()
            //Close the fragment
            closeFragment()
        }

        ivRecoClose.setOnClickListener {
            //Clear the widget
            saveBitMapToStorage()
            //Close the fragment
            closeFragment()
        }

        tvRecoDone.setOnClickListener {
            /*if (mathWidget.resultAsImage != null) {
                //Save bitmap to storage
                saveBitMapToStorage()

                closeFragment()
            } else {
                closeFragment()
            }*/
        }
    }

    /** Configure recognition **/
    private fun configureRecognition() {
        val conf = engine!!.configuration
        val confDir = "zip://" + activity!!.packageCodePath + "!/assets/conf"
        conf.setStringArray("configuration-manager.search-path", arrayOf(confDir))
        val tempDir = activity!!.filesDir.path + File.separator + "tmp"
        conf.setString("content-package.temp-folder", tempDir)
    }

    private fun saveBitMapToStorage() {
        clearWidget()
        // TODO("Save bitmap to storage")
    }

    /** Clear the widget **/
    private fun clearWidget() {
        // TODO("Clear the widget")
    }

    /** Close the fragment **/
    private fun closeFragment() {
        //Clear the widget
        clearWidget()
        val f = parentFragment?.childFragmentManager?.findFragmentById(R.id.frameLayoutnew)
        if (f is MathRecogniserFrag) {
            if (f.isVisible()) {
                parentFragment?.childFragmentManager!!.beginTransaction().remove(f).commit()
            }
        }
        UtilKeyboard.hideKeyboard(this!!.activity!!)

        if (toolbarView != null) {
            toolbarView!!.selectLastTool()
        }
    }
    /** ******************** Custom Methods ****************** **/


}

 

Answer

Dear Devrath,


the above code doesn't help at all.


Just set a break point line 315 of the DocumentController.java file (openPart function). This looks like a coding issue.


Best regards,


Olivier