java - Cordova 3 Android 插件 - 如何在主要 Activity 中调用函数?

标签 java android plugins cordova

编辑:用户 QuickFix 的回答对我有用。代码就在这个问题的底部。

我正在尝试编写一个 Cordova 3 Android 插件来制作普通和自定义 Toast。但是,我只是一名前端开发人员,对 Cordova 和 Android 还很陌生。我仍在学习,非常感谢您能提供的任何帮助。

到目前为止,我已经成功地单独完成了这两项任务:

  1. 在主 Activity 中编写一个函数来制作普通和自定义 Toast(自定义 Toast 只是/res/layout 中的一个 RelativeLayout,它显示一个图标和一些文本)。
  2. 按照 Devgirl 的教程编写 Cordova 插件:How to Write a PhoneGap 3.0 Plugin for Android .

我现在的问题是 - 如何让插件在主 Activity 中调用 showCustomToast() 函数?正如您在下面的代码块 #2 中看到的那样,我遇到了如何获取 主要 Activity 以便调用 showCustomToast() 的问题。以下是我目前如何执行此操作的摘录:

// Problem?
HelloCordova main = (HelloCordova) cordova.getActivity();  
main.showCustomToast(toastTitle, toastText, duration);

我必须将 cordova.getActivity() 转换为 HelloCordova,否则它不会识别它具有 showCustomToast () 函数。但肯定这不是正确的方法,尽管它确实“有效”,即,我能够让自定义 Toast 显示在应用程序中。我只是忍不住觉得我完全走错了路。目前它还不是一个可重复使用的插件!

如果有人能让我走上实现这一目标的正确道路,我将不胜感激。例如,我是否应该完全放弃插件而只放弃 do this?相反?

这是我的第一个 Stackoverflow 问题,如果我需要更改或澄清任何内容,请告诉我。感谢阅读!!

这是我现有的代码:

代码块#1

这个 HelloCordova 类是在启动一个新的 Cordova 项目时自动生成的。我添加了 showCustomToast() 函数。

package io.cordova.hellocordova;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import org.apache.cordova.*;

public class HelloCordova extends CordovaActivity 
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        super.init();
        // Set by <content src="index.html" /> in config.xml
        super.loadUrl(Config.getStartUrl());
        //super.loadUrl("file:///android_asset/www/index.html")

    }
    public void showCustomToast(String toastTitleText, String toastDescText, int toastDuration) {
        Toast toast = new Toast(this);
        toast.setDuration(toastDuration);   

        LayoutInflater inflater = getLayoutInflater();
        View appearance = inflater.inflate(R.layout.toast_layout, (ViewGroup) findViewById(R.id.toastRoot));
        toast.setView(appearance);

        TextView toastTitle = (TextView) appearance.findViewById(R.id.toastTitle);
        toastTitle.setText(toastTitleText);

        TextView toastDesc = (TextView) appearance.findViewById(R.id.toastDescription);
        toastDesc.setText(toastDescText);

        toast.show();
    }
}

代码块#2

Cordova 插件的 Java 部分。

package com.example.plugins.toast;

//Problem?
import io.cordova.hellocordova.HelloCordova;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;

public class ToastPlugin extends CordovaPlugin {

    final String LOG_TAG = "ToastLog";
    public static final String ACTION_NORMAL_TOAST = "normalToast";
    public static final String ACTION_CUSTOM_TOAST = "customToast";

    @Override
    public boolean execute(String action, JSONArray args,
            CallbackContext callbackContext) throws JSONException {

        final JSONObject arg_object = args.getJSONObject(0);
        final String toastTitle = arg_object.getString("toastTitle");
        final String toastText = arg_object.getString("toastText");
        final String toastDuration = arg_object.getString("toastDuration");

        final CallbackContext ctx = callbackContext;

        try {
            if (ACTION_NORMAL_TOAST.equals(action)) {
                Log.d(LOG_TAG, "Normal toast: " + toastText);

                Runnable runnable = new Runnable() {
                    public void run() {
                        Context context = cordova.getActivity()
                                .getApplicationContext();
                        int duration = Toast.LENGTH_SHORT;
                        if (toastDuration.equals("LONG")) {
                            duration = Toast.LENGTH_LONG;
                        }
                        Toast.makeText(context, toastText, duration).show();
                    }
                };
                this.cordova.getActivity().runOnUiThread(runnable);

                callbackContext.success();
                return true;
            } else if (ACTION_CUSTOM_TOAST.equals(action)) {
                Log.d(LOG_TAG, "Custom toast: " + toastTitle + ": " + toastText);

                Runnable runnable = new Runnable() {
                    public void run() {
                        int duration = Toast.LENGTH_SHORT;
                        if (toastDuration.equals("LONG")) {
                            duration = Toast.LENGTH_LONG;
                        }
                        //Problem?
                        HelloCordova main = (HelloCordova) cordova
                                .getActivity();
                        main.showCustomToast(toastTitle, toastText, duration);
                        ctx.success();

                    }
                };
                this.cordova.getActivity().runOnUiThread(runnable);

                callbackContext.success();
                return true;
            }
            callbackContext.error("Invalid action");
            return false;
        } catch (Exception e) {
            System.err.println("Exception: " + e.getMessage());
            callbackContext.error(e.getMessage());
            return false;
        }
    }
}

编辑:这是对我有用的解决方案。正如 QuickFix 在下面的回答中提到的那样,自定义 Toast 代码现在位于插件中。

package com.example.plugins.toast;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.content.res.Resources;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class ToastPlugin extends CordovaPlugin {

    final String LOG_TAG = "ToastLog";
    public static final String ACTION_NORMAL_TOAST = "normalToast";
    public static final String ACTION_CUSTOM_TOAST = "customToast"; 

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {

        final JSONObject arg_object = args.getJSONObject(0);
        final String toastTitle = arg_object.getString("toastTitle");
        final String toastText = arg_object.getString("toastText");
        final String toastDuration = arg_object.getString("toastDuration");

        try {
            if (ACTION_NORMAL_TOAST.equals(action)) {

                Log.i(LOG_TAG, "[Normal toast] toastText: " + toastText);

                Runnable runnable = new Runnable() {
                    public void run() {
                        Context context = cordova.getActivity().getApplicationContext();
                        int duration = Toast.LENGTH_SHORT;
                        if (toastDuration.equals("LONG")) {
                            duration = Toast.LENGTH_LONG;
                        }
                        Toast.makeText(context, toastText, duration).show();
                    }
                };
                this.cordova.getActivity().runOnUiThread(runnable);
                callbackContext.success();
                return true;

            } else if (ACTION_CUSTOM_TOAST.equals(action)) {

                Log.i(LOG_TAG, "[Custom toast] toastTitle: " + toastTitle + "\n toastText: " + toastText);

                Runnable runnable = new Runnable() {
                    public void run() {
                        int duration = Toast.LENGTH_SHORT;
                        if (toastDuration.equals("LONG")) {
                            duration = Toast.LENGTH_LONG;
                        }

                        Context context = cordova.getActivity().getApplicationContext();

                        Toast toast = new Toast(context);
                        toast.setDuration(duration);    

                        LayoutInflater inflater = LayoutInflater.from(context);

                        Resources resources = context.getResources();                       
                        String packageName = context.getPackageName();

                        View appearance = inflater.inflate(resources.getIdentifier("toast_layout","layout",packageName),null);
                        toast.setView(appearance);

                        TextView toastTitleView = (TextView) appearance.findViewById(resources.getIdentifier("toastTitle","id",packageName));
                        toastTitleView.setText(toastTitle);

                        TextView toastDesc = (TextView) appearance.findViewById(resources.getIdentifier("toastDescription","id",packageName));
                        toastDesc.setText(toastText);

                        toast.show();
                    }
                };
                this.cordova.getActivity().runOnUiThread(runnable);
                callbackContext.success();
                return true;

            }
            callbackContext.error("Invalid action");
            return false;
        } catch (Exception e) {
            System.err.println("Exception: " + e.getMessage());
            callbackContext.error(e.getMessage());
            return false;
        }
    }
}

最佳答案

也许您可以将 showCustomToast 放在插件中而不是应用程序中?

在这种情况下,您必须将函数中的 R.layout.layoutnameR.id.viewname 替换为

getApplication().getResources().getIdentifier("layoutname","layout",getApplication().getPackageName());

getApplication().getResources().getIdentifier("viewname","id",getApplication().getPackageName());

关于java - Cordova 3 Android 插件 - 如何在主要 Activity 中调用函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21012964/

相关文章:

Excel 和 Capital IQ 插件

jenkins - 将 Jenkins 标签设置为构建参数的值,以实现真正动态的基于节点和标签的构建

.net - 在选项卡中打开 .NET 插件

java - 有 2 个 SetContentView

android - Android 中的表格布局 - 行大小调整

java - 在 Eclipse 控制台中包含与 System.out.print 语句对应的文件名/行号

android - 如何在多个布局中重用 ImageView

android - Firebase 大查询 - 如何从自定义事件表中检索数据

java - 使用 MongoDB 更新数组

Java Process 无法通过标准 IO 重定向读取 Factorio 的输出