【GNZ48-章泽婷应援会】基于Java的SNH48Group应援会机器人(三)发送消息

这一部分是我也看了好久,才决定用Java的Robot + User32来实现。Robot是java.awt下的一个类,该类用于为测试自动化、自运行演示程序和其他需要控制鼠标和键盘的应用程序生成本机系统输入事件,因此可试用该类进行模拟鼠标键盘操作。User32是JNA下的一个类,该类提供对W32 USER32库的访问,也就是说可以试用该类来进行windows的一些操作,而这里我用来选择对话窗口。

其实我这里用到的awt和JNA都是它们其中的一个小功能点而已,还有很多其他的功能可以去学习使用。下面放一下我发送消息的方法。

/**
 * @Function: SendMessageService.java
 * @Description: 向指定QQ群发送消息
 * @param: communityName 为必填的非空参数,用于发送消息。
 * @param: message 要发送的消息内容。
 * @param: communityId 为非必填参数,可为空,用于记录日志。
 * @author: JuFF_白羽
 * @date: 2018年7月15日 上午2:36:11
 */
private void sendQQMessage(String message, Long communityId, String communityName) throws AWTException {
    WinDef.HWND hwnd = User32.INSTANCE.FindWindow(null, communityName); // 第一个参数是Windows窗体的窗体类,第二个参数是窗体的标题。不熟悉windows编程的需要先找一些Windows窗体数据结构的知识来看看,还有windows消息循环处理,其他的东西不用看太多。
    if (hwnd == null) {
        LOGGER.info("找不到[{}]聊天窗口", communityId);
    } else {
        Robot robot = new Robot();
        boolean showWindow = User32.INSTANCE.ShowWindow(hwnd, 9); // SW_RESTORE
        if (showWindow) {
            boolean setForegroundWindow = User32.INSTANCE.SetForegroundWindow(hwnd);
            if (setForegroundWindow) {
                robot.delay(3000);// 等3秒
                KeyboardUtil.keyPressString(robot, message);// 输入内容
                KeyboardUtil.keyPress(robot, KeyEvent.VK_ENTER);// 按下回车
                LOGGER.info("新消息已发送到[{}]聊天窗口", communityId);
            } else {
                LOGGER.info("设置前景窗口失败");
            }
        } else {
            LOGGER.info("显示窗口失败");
        }
    }
}

从上面的代码来看,并没有什么复杂,而其实里面Robot和User32的调用过程都各有一个坑,先从调用Robot发现的问题说起好了。在JUnit Test运行时,Robot能正常实例化,然后模拟键盘按键和鼠标点击等操作,但打包成jar后部署到服务器上时,运行到实例化Robot对象时却报了 java.awt.AWTException: headless environment 这个异常。而这个异常我查了百度,发现很多都没说清楚具体原因,于是又去查了谷歌,相关解释见Java SE使用无头模式<

好的,以下是一个简单的 Android 实现示例,您可以参考: 首先,在您的 layout 目录下创建一个名为 activity_main.xml 的 XML 布局文件,包含以下代码: ```xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp" tools:context=".MainActivity"> <Button android:id="@+id/menu_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="菜单" /> <LinearLayout android:id="@+id/menu" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:visibility="gone"> <TextView android:id="@+id/menu_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="选择一个菜单项" /> <Button android:id="@+id/male_singer_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="男歌手" /> <Button android:id="@+id/female_singer_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="女歌手" /> <Button android:id="@+id/group_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="组合" /> </LinearLayout> <LinearLayout android:id="@+id/sub_menu" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:visibility="gone"> <TextView android:id="@+id/sub_menu_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="选择一个子菜单项" /> <Button android:id="@+id/tfboys_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TFBOYS" /> <Button android:id="@+id/snh48_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="SNH48" /> <Button android:id="@+id/gnz48_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="GNZ48" /> </LinearLayout> </RelativeLayout> ``` 接下来,在您的 MainActivity.java 中添加以下代码: ```java public class MainActivity extends AppCompatActivity { private Button menuBtn; private LinearLayout menuLayout; private TextView menuTitle; private Button maleSingerBtn; private Button femaleSingerBtn; private Button groupBtn; private LinearLayout subMenuLayout; private TextView subMenuTitle; private Button tfboysBtn; private Button snh48Btn; private Button gnz48Btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 获取 UI 控件 menuBtn = findViewById(R.id.menu_btn); menuLayout = findViewById(R.id.menu); menuTitle = findViewById(R.id.menu_title); maleSingerBtn = findViewById(R.id.male_singer_btn); femaleSingerBtn = findViewById(R.id.female_singer_btn); groupBtn = findViewById(R.id.group_btn); subMenuLayout = findViewById(R.id.sub_menu); subMenuTitle = findViewById(R.id.sub_menu_title); tfboysBtn = findViewById(R.id.tfboys_btn); snh48Btn = findViewById(R.id.snh48_btn); gnz48Btn = findViewById(R.id.gnz48_btn); // 点击菜单按钮时显示菜单 menuBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (menuLayout.getVisibility() == View.GONE) { menuLayout.setVisibility(View.VISIBLE); } else { menuLayout.setVisibility(View.GONE); } } }); // 点击菜单项时显示对应的子菜单 maleSingerBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { menuLayout.setVisibility(View.GONE); subMenuLayout.setVisibility(View.VISIBLE); subMenuTitle.setText("你选择的男歌手是:"); tfboysBtn.setVisibility(View.VISIBLE); snh48Btn.setVisibility(View.GONE); gnz48Btn.setVisibility(View.GONE); } }); femaleSingerBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { menuLayout.setVisibility(View.GONE); subMenuLayout.setVisibility(View.VISIBLE); subMenuTitle.setText("你选择的女歌手是:"); tfboysBtn.setVisibility(View.GONE); snh48Btn.setVisibility(View.VISIBLE); gnz48Btn.setVisibility(View.VISIBLE); } }); groupBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { menuLayout.setVisibility(View.GONE); subMenuLayout.setVisibility(View.VISIBLE); subMenuTitle.setText("你选择的组合是:"); tfboysBtn.setVisibility(View.VISIBLE); snh48Btn.setVisibility(View.VISIBLE); gnz48Btn.setVisibility(View.VISIBLE); } }); // 点击子菜单项时显示提示信息 tfboysBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "你选择的组合是TFBOYS", Toast.LENGTH_SHORT).show(); } }); snh48Btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "你选择的组合是SNH48", Toast.LENGTH_SHORT).show(); } }); gnz48Btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "你选择的组合是GNZ48", Toast.LENGTH_SHORT).show(); } }); } } ``` 这个示例实现了一个简单的 Android 应用,包含一个菜单按钮和两个菜单。当用户点击菜单按钮时,弹出包含“男歌手”、“女歌手”、“组合”的菜单。当用户选择其中一个菜单项时,弹出对应的子菜单,例如,如果用户选择“组合”,则弹出包含“TFBOYS”、“SNH48”、“GNZ48”的子菜单。当用户选择其中一个子菜单项时,弹出提示信息,告诉用户他们选择了哪个选项。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值