Cordova 3 Android插件 - 如何在主要活动中调用一个函数?

时间:2014-01-09 06:20:42

标签: java android plugins cordova

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

我正在尝试编写一个Cordova 3 Android插件,该插件可以生成普通和自定义Toast。但是,我只是一个前端开发人员,对Cordova和Android来说是一个新手。我还在学习,并希望得到任何帮助。

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

  1. 在主活动中编写一个函数,该函数生成普通和自定义Toast(自定义Toast只是/ res / layout中的RelativeLayout,显示图标和一些文本)。
  2. 按照Devgirl的教程编写Cordova插件:How to Write a PhoneGap 3.0 Plugin for Android
  3. 我现在的问题是 - 如何让插件在主要活动中调用showCustomToast()函数?正如您在下面的代码块#2中所看到的,我遇到了如何甚至获取主要活动的问题,因此我可以调用showCustomToast()。以下是我目前这样做的摘录:

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

    我必须将cordova.getActivity()投射到HelloCordova,否则它将无法识别具有 showCustomToast()功能。但肯定这是正确的方法,虽然它确实“有效”,即我能够在应用程序中显示自定义Toast。我忍不住觉得我完全走错了路。目前它不是一个可重复使用的插件!

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

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

    这是我现有的代码:

    代码块#1

    启动新的Cordova项目时会自动生成此HelloCordova类。我添加了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;
            }
        }
    }
    

1 个答案:

答案 0 :(得分:4)

也许你可以将showCustomToast放在插件中,而不是放在app中?

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

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

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