YYPOST群发软件 发表于 前天 08:10

AIWROK软件支持悬浮窗自由定位和拖拽功能

AIWROK软件支持悬浮窗自由定位和拖拽功能




//通过floatUI创建悬浮窗
//适用于ES5系统安卓 JavaScript引擎Rhino
//基于AIWROK软件安卓开发框架
//支持悬浮窗自由定位和拖拽功能
//🍎交流QQ群711841924群一,苹果内测群,528816639


if (!String.prototype.repeat) {
    String.prototype.repeat = function(count) {
      'use strict';
      if (this == null) {
            throw new TypeError('can\'t convert ' + this + ' to object');
      }
      var str = String(this);
      count = +count;
      if (count != count) {
            count = 0;
      }
      if (count < 0) {
            throw new RangeError('repeat count must be non-negative');
      }
      if (count == Infinity) {
            throw new RangeError('repeat count must be less than infinity');
      }
      count = Math.floor(count);
      if (str.length == 0 || count == 0) {
            return '';
      }
      // 确保重复的字符串不会超出字符串长度限制
      if (str.length * count >= 1 << 28) {
            throw new RangeError('repeat count must not overflow maximum string size');
      }
      var rpt = '';
      for (var i = 0; i < count; i++) {
            rpt += str;
      }
      return rpt;
    };
}

// ES5兼容的String.prototype.padStart polyfill
if (!String.prototype.padStart) {
    String.prototype.padStart = function(targetLength, padString) {
      targetLength = targetLength >> 0; // 转换为整数
      padString = String((typeof padString !== 'undefined' ? padString : ' '));
      if (this.length > targetLength) {
            return String(this);
      } else {
            targetLength = targetLength - this.length;
            if (targetLength > padString.length) {
                padString += padString.repeat(targetLength / padString.length); // 截断或重复填充字符串
            }
            return padString.slice(0, targetLength) + String(this);
      }
    };
}

/*
   安卓可移动侧栏日志吐司
   功能:
   1. 可拖拽移动的侧栏悬浮窗
   2. 支持日志信息实时显示
   3. 支持展开/收起功能
   4. 支持自定义日志颜色
*/

// 定义侧栏日志悬浮窗构造函数
function 侧栏日志() {
    this.screenHeight = 1920; // 默认屏幕高度
    this.screenWidth = 1080;// 默认屏幕宽度
    this.isExpanded = false;// 展开状态标志
    this.logs = [];         // 日志数组
    this.maxLogs = 50;      // 最大日志条数
    this.dragging = false;    // 拖拽状态标志
    this.lastX = 0;         // 上次触摸X坐标
    this.lastY = 0;         // 上次触摸Y坐标
}

// 创建侧栏日志悬浮窗
侧栏日志.prototype.create = function() {
    try {
      // 检查floatUI是否可用
      if (typeof floatUI === 'undefined') {
            printl("❌ 错误:未找到floatUI库");
            return false;
      }
      
      // 创建floatUI实例
      var fui = new floatUI();
      
      // 获取实际屏幕尺寸
      try {
            if (context && context.getResources && context.getResources().getDisplayMetrics) {
                var metrics = context.getResources().getDisplayMetrics();
                this.screenHeight = metrics.heightPixels || 1920;
                this.screenWidth = metrics.widthPixels || 1080;
                printl("✅ 获取屏幕尺寸: " + this.screenWidth + "x" + this.screenHeight);
            } else {
                printl("⚠️ 无法获取屏幕尺寸,使用默认值");
                this.screenHeight = 1920; // 默认屏幕高度
                this.screenWidth = 1080;// 默认屏幕宽度
            }
      } catch(e) {
            printl("⚠️ 获取屏幕尺寸失败,使用默认值: " + e);
            this.screenHeight = 1920;
            this.screenWidth = 1080;
      }
      
      // 定义侧边栏宽度和高度
      var sidebarWidth = 100;// 更窄的侧边栏宽度
      var sidebarMinWidth = 30; // 更窄的收起时最小宽度
      var sidebarHeight = 100; // 固定小高度,不再依赖屏幕比例
      
      // 加载XML布局
      try {
            fui.loadXML(`
                <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="${sidebarWidth}dp"
                  android:layout_height="${sidebarHeight}dp"
                  android:background="#CC000000"
                  android:orientation="vertical"
                  android:id="main_container">
                  
                  <!-- 可拖动的标题栏 -->
                  <LinearLayout
                        android:id="title_bar"
                        android:layout_width="match_parent"
                        android:layout_height="35dp"
                        android:background="#666666"
                        android:orientation="horizontal"
                        android:gravity="center_vertical">
                        
                        <!-- 拖动区域 -->
                        <View
                            android:layout_width="${sidebarMinWidth}dp"
                            android:layout_height="match_parent"
                            android:background="#444444"/>
                        
                        <!-- 标题文字(仅在展开时可见) -->
                        <TextView
                            android:id="title_text"
                            android:layout_width="0dp"
                            android:layout_height="match_parent"
                            android:layout_weight="1"
                            android:text="运行日志"
                            android:textColor="#FFFFFF"
                            android:gravity="center"
                            android:textSize="14sp"/>
                           
                        <!-- 关闭按钮(仅在展开时可见) -->
                            <Button
                              android:id="close_button"
                              android:layout_width="30dp"
                              android:layout_height="30dp"
                              android:text="✕"
                              android:textColor="#FFFFFF"
                              android:background="#FF4444"
                              android:textSize="14sp"
                              android:padding="0dp"
                              android:gravity="center"/>
                  </LinearLayout>
                  
                  <!-- 日志显示区域(仅在展开时可见) -->
                  <ScrollView
                        android:id="log_container"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:background="#111111">
                        
                        <TextView
                            android:id="log_text"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:textColor="#00FF00"
                            android:textSize="11sp"
                            android:padding="3dp"
                            android:lineSpacingExtra="1dp"/>
                  </ScrollView>
                  
                  <!-- 展开/收起按钮 -->
                  <Button
                        android:id="toggle_button"
                        android:layout_width="match_parent"
                        android:layout_height="25dp"
                        android:text="≡"
                        android:textColor="#FFFFFF"
                        android:background="#555555"
                        android:textSize="16sp"/>
                </LinearLayout>
            `);
            printl("✅ XML布局加载成功");
      } catch (xmlError) {
            printl("❌ XML布局加载失败: " + xmlError);
            return false;
      }
      
      // 保存UI实例
      this.ui = fui;
      
      // 保存宽度设置供toggleExpand方法使用
      this.sidebarWidth = sidebarWidth;
      this.sidebarMinWidth = sidebarMinWidth;
      
      // 获取UI元素
      try {
            this.titleBar = fui.findViewById("title_bar");
            this.titleText = fui.findViewById("title_text");
            this.logContainer = fui.findViewById("log_container");
            this.logText = fui.findViewById("log_text");
            this.toggleButton = fui.findViewById("toggle_button");
            this.closeButton = fui.findViewById("close_button"); // 获取关闭按钮
            this.mainContainer = fui.findViewById("main_container");
            
            // 检查关键元素是否存在
            var missingElements = [];
            if (!this.titleBar) missingElements.push("titleBar");
            if (!this.logText) missingElements.push("logText");
            if (!this.toggleButton) missingElements.push("toggleButton");
            if (!this.mainContainer) missingElements.push("mainContainer");
            
            if (missingElements.length > 0) {
                printl("⚠️ 缺失关键UI元素: " + missingElements.join(", "));
            } else {
                printl("✅ 所有UI元素获取成功");
            }
      } catch (findError) {
            printl("❌ 获取UI元素失败: " + findError);
      }
      
      // 设置初始位置(屏幕左侧)
      try {
            this.setPos(0, (this.screenHeight - 100) / 2);
            printl("✅ 初始位置设置成功");
      } catch (posError) {
            printl("❌ 设置初始位置失败: " + posError);
      }
      
      // 初始化事件
      try {
            this.initEvents();
            printl("✅ 事件初始化成功");
      } catch (eventError) {
            printl("❌ 事件初始化失败: " + eventError);
      }
      
      // 显示初始化日志
      this.log("✅ 侧栏日志已启动", "#00FF00");
      
      return true;
    } catch (e) {
      printl("❌ 创建侧栏日志失败: " + e);
      return false;
    }
};

// 初始化事件
侧栏日志.prototype.initEvents = function() {
    var self = this;
   
    // 设置拖拽事件 - 添加更完善的错误处理
    try {
      if (typeof View !== 'undefined' && typeof MotionEvent !== 'undefined' && this.titleBar && this.titleBar.setOnTouchListener) {
            this.titleBar.setOnTouchListener(new View.OnTouchListener({
                onTouch: function(view, event) {
                  try {
                        switch (event.getAction()) {
                            case MotionEvent.ACTION_DOWN:
                              self.dragging = true;
                              self.lastX = event.getRawX();
                              self.lastY = event.getRawY();
                              break;
                            case MotionEvent.ACTION_MOVE:
                              if (self.dragging) {
                                    var dx = event.getRawX() - self.lastX;
                                    var dy = event.getRawY() - self.lastY;
                                    
                                    // 获取当前位置
                                    var currentX = view.getX();
                                    var currentY = view.getY();
                                    
                                    // 计算新位置(考虑整个容器的位置)
                                    var newX = currentX + dx;
                                    var newY = currentY + dy;
                                    
                                    // 边界检查
                                    if (newX < 0) newX = 0;
                                    if (newY < 0) newY = 0;
                                    if (newX > self.screenWidth - (self.isExpanded ? self.sidebarWidth : self.sidebarMinWidth))
                                        newX = self.screenWidth - (self.isExpanded ? self.sidebarWidth : self.sidebarMinWidth);
                                    if (newY > self.screenHeight - 100)
                                        newY = self.screenHeight - 100;
                                    
                                    // 设置新位置
                                    self.setPos(newX, newY);
                                    
                                    // 更新上次触摸位置
                                    self.lastX = event.getRawX();
                                    self.lastY = event.getRawY();
                              }
                              break;
                            case MotionEvent.ACTION_UP:
                              self.dragging = false;
                              break;
                        }
                        return true;
                  } catch (touchError) {
                        // 静默处理触摸事件错误,避免崩溃
                        return false;
                  }
                }
            }));
      } else {
            printl("⚠️ 无法设置拖拽事件,缺少必要组件");
      }
    } catch (touchSetupError) {
      printl("❌ 设置拖拽事件失败: " + touchSetupError);
    }
   
    // 展开/收起按钮点击事件
    try {
      if (this.toggleButton && this.toggleButton.setOnClickListener) {
            this.toggleButton.setOnClickListener(function() {
                try {
                  self.toggleExpand();
                } catch (toggleError) {
                  printl("❌ 执行展开/收起操作失败: " + toggleError);
                }
            });
      }
    } catch (toggleSetupError) {
      printl("❌ 设置展开/收起事件失败: " + toggleSetupError);
    }
   
    // 关闭按钮点击事件
    try {
      if (this.closeButton && this.closeButton.setOnClickListener) {
            this.closeButton.setOnClickListener(function() {
                try {
                  self.close();
                } catch (closeError) {
                  printl("❌ 执行关闭操作失败: " + closeError);
                }
            });
      }
    } catch (closeSetupError) {
      printl("❌ 设置关闭事件失败: " + closeSetupError);
    }
};

// 获取当前时间用于日志
侧栏日志.prototype.getCurrentTime = function() {
    var now = new Date();
    var hours = now.getHours().toString().padStart(2, '0');
    var minutes = now.getMinutes().toString().padStart(2, '0');
    var seconds = now.getSeconds().toString().padStart(2, '0');
    return hours + ':' + minutes + ':' + seconds;
};

// 切换展开/收起状态
侧栏日志.prototype.toggleExpand = function() {
    try {
      var self = this;
      
      // 记录当前状态变更(使用printl避免递归)
      printl("[" + self.getCurrentTime() + "] " + (self.isExpanded ? "&#128317; 侧栏正在收起" : "&#128316; 侧栏正在展开"));
      // 定义要设置的目标宽度 - 修复逻辑:当前展开时应该设置为收起宽度,当前收起时应该设置为展开宽度
      var targetWidth = this.isExpanded ? this.sidebarMinWidth : this.sidebarWidth;
      
      // 切换展开状态标志
      this.isExpanded = !this.isExpanded;
      
      // 确保在主线程中执行UI操作
      var uiOperation = function() {
            self.performToggleExpand(targetWidth);
      };
      
      // 尝试多种UI线程调度方案
      var threadScheduled = false;
      
      // 方案1: 使用context.runOnUiThread
      try {
            if (context && context.runOnUiThread) {
                // 使用ES5兼容的方式创建Runnable对象
                var runnable = {
                  run: function() {
                        try {
                            uiOperation();
                        } catch (e) {
                            printl("❌ UI线程执行失败: " + e);
                        }
                  }
                };
                context.runOnUiThread(runnable);
                threadScheduled = true;
                printl("✅ 使用context.runOnUiThread调度UI线程");
            }
      } catch (e) {
            printl("❌ 方案1: context.runOnUiThread失败: " + e);
      }
      
      // 方案2: 使用View.post (如果有任何View对象可用)
      if (!threadScheduled) {
            try {
                var viewToUse = self.mainContainer || self.titleBar || self.toggleButton;
                if (viewToUse && viewToUse.post) {
                  viewToUse.post(function() {
                        try {
                            uiOperation();
                        } catch (e) {
                            printl("❌ View.post执行失败: " + e);
                        }
                  });
                  threadScheduled = true;
                  printl("✅ 使用View.post调度UI线程");
                }
            } catch (e) {
                printl("❌ 方案2: View.post失败: " + e);
            }
      }
      
      // 方案3: 尝试使用Handler (如果可用)
      if (!threadScheduled) {
            try {
                if (typeof Handler !== 'undefined' && typeof Looper !== 'undefined' && Looper.getMainLooper) {
                  var handler = new Handler(Looper.getMainLooper());
                  handler.post(function() {
                        try {
                            uiOperation();
                        } catch (e) {
                            printl("❌ Handler执行失败: " + e);
                        }
                  });
                  threadScheduled = true;
                  printl("✅ 使用Handler调度UI线程");
                }
            } catch (e) {
                printl("❌ 方案3: Handler失败: " + e);
            }
      }
      
      // 方案4: 直接执行作为最后备选 (可能会失败但提供降级方案)
      if (!threadScheduled) {
            printl("⚠️ 所有线程调度方案失败,尝试直接执行UI操作");
            try {
                uiOperation();
            } catch (directError) {
                printl("❌ 直接执行UI操作失败: " + directError);
            }
      }
    } catch (e) {
      printl("❌ 切换展开状态失败: " + e);
    }
};
// 执行UI操作的核心方法(应在主线程中调用)
侧栏日志.prototype.performToggleExpand = function(targetWidth) {
    try {
      var self = this;
      
      // 切换UI元素可见性
      if (!this.isExpanded) {
            // 收起状态
            if (this.titleText && typeof this.titleText.setVisibility === 'function') {
                try {
                  this.titleText.setVisibility(View.GONE);
                } catch (e) {
                  printl("❌ 设置titleText可见性失败: " + e);
                }
            }
            if (this.logContainer && typeof this.logContainer.setVisibility === 'function') {
                try {
                  this.logContainer.setVisibility(View.GONE);
                } catch (e) {
                  printl("❌ 设置logContainer可见性失败: " + e);
                }
            }
            if (this.closeButton && typeof this.closeButton.setVisibility === 'function') {
                try {
                  this.closeButton.setVisibility(View.GONE); // 收起时隐藏关闭按钮
                } catch (e) {
                  printl("❌ 设置closeButton可见性失败: " + e);
                }
            }
      } else {
            // 展开状态
            if (this.titleText && typeof this.titleText.setVisibility === 'function') {
                try {
                  this.titleText.setVisibility(View.VISIBLE);
                } catch (e) {
                  printl("❌ 设置titleText可见性失败: " + e);
                }
            }
            if (this.logContainer && typeof this.logContainer.setVisibility === 'function') {
                try {
                  this.logContainer.setVisibility(View.VISIBLE);
                } catch (e) {
                  printl("❌ 设置logContainer可见性失败: " + e);
                }
            }
            if (this.closeButton && typeof this.closeButton.setVisibility === 'function') {
                try {
                  this.closeButton.setVisibility(View.VISIBLE); // 展开时显示关闭按钮
                } catch (e) {
                  printl("❌ 设置closeButton可见性失败: " + e);
                }
            }
      }
      
      // 尝试多种方法来设置宽度,增加更多的备选方案
      var widthSetSuccessfully = false;
      var errorMessages = [];
      
      // 获取屏幕密度
      var getDensity = function() {
            try {
                if (context && context.getResources && context.getResources().getDisplayMetrics) {
                  return context.getResources().getDisplayMetrics().density;
                }
            } catch (e) {
                printl("⚠️ 获取屏幕密度失败: " + e);
            }
            return 3; // 默认密度
      };
      
      // 方法1: 尝试通过FloatUI对象的可能方法
      try {
            if (this.ui && typeof this.ui.setLayoutWidth === 'function') {
                this.ui.setLayoutWidth(targetWidth);
                widthSetSuccessfully = true;
                printl("方法1: 使用setLayoutWidth设置宽度成功");
            }
      } catch (e) {
            errorMessages.push("方法1: " + (e.message || String(e)));
      }
      
      // 方法2: 尝试通过LayoutParams设置宽度
      if (!widthSetSuccessfully) {
            try {
                if (this.mainContainer && typeof this.mainContainer.getLayoutParams === 'function' &&
                  typeof this.mainContainer.setLayoutParams === 'function') {
                  var params = this.mainContainer.getLayoutParams();
                  if (params) {
                        // 尝试将dp转换为像素
                        var pixelWidth = Math.round(targetWidth * getDensity());
                        
                        // 安全地设置宽度
                        try {
                            params.width = pixelWidth;
                            this.mainContainer.setLayoutParams(params);
                            widthSetSuccessfully = true;
                            printl("方法2: 使用LayoutParams设置宽度成功");
                        } catch (setParamsError) {
                            errorMessages.push("方法2: " + (setParamsError.message || String(setParamsError)));
                        }
                  }
                }
            } catch (e) {
                errorMessages.push("方法2: " + (e.message || String(e)));
            }
      }
      
      // 方法3: 尝试直接设置视图宽度
      if (!widthSetSuccessfully) {
            try {
                if (this.mainContainer && typeof this.mainContainer.setWidth === 'function') {
                  // 使用已经计算好的像素宽度
                  var pixelWidth = Math.round(targetWidth * getDensity());
                  this.mainContainer.setWidth(pixelWidth);
                  widthSetSuccessfully = true;
                  printl("方法3: 使用setWidth设置宽度成功");
                }
            } catch (e) {
                errorMessages.push("方法3: " + (e.message || String(e)));
            }
      }
      
      // 方法4: 尝试修改XML布局参数
      if (!widthSetSuccessfully) {
            try {
                if (this.ui && typeof this.ui.setLayoutParams === 'function') {
                  // 尝试获取并修改FloatUI的布局参数
                  var floatParams = (typeof this.ui.getLayoutParams === 'function') ? this.ui.getLayoutParams() : null;
                  if (floatParams) {
                        floatParams.width = Math.round(targetWidth * getDensity());
                        this.ui.setLayoutParams(floatParams);
                        widthSetSuccessfully = true;
                        printl("方法4: 使用FloatUI.setLayoutParams设置宽度成功");
                  }
                }
            } catch (e) {
                errorMessages.push("方法4: " + (e.message || String(e)));
            }
      }
      
      // 方法5: 尝试使用layout方法直接设置位置和大小
      if (!widthSetSuccessfully) {
            try {
                if (this.mainContainer && typeof this.mainContainer.layout === 'function') {
                  var left = 0;
                  var top = 0;
                  try {
                        left = this.mainContainer.getLeft();
                        top = this.mainContainer.getTop();
                  } catch (positionError) {
                        // 使用默认位置
                  }
                  var pixelWidth = Math.round(targetWidth * getDensity());
                  var height = 0;
                  try {
                        height = this.mainContainer.getHeight();
                  } catch (heightError) {
                        height = 100; // 默认高度
                  }
                  this.mainContainer.layout(left, top, left + pixelWidth, top + height);
                  widthSetSuccessfully = true;
                  printl("方法5: 使用layout方法设置宽度成功");
                }
            } catch (e) {
                errorMessages.push("方法5: " + (e.message || String(e)));
            }
      }
      
      // 尝试UI刷新方法
      if (widthSetSuccessfully) {
            try {
                if (this.ui && typeof this.ui.updateLayout === 'function') {
                  this.ui.updateLayout();
                  printl("UI布局已更新");
                } else if (this.mainContainer && typeof this.mainContainer.requestLayout === 'function') {
                  this.mainContainer.requestLayout();
                  printl("请求重新布局");
                } else if (this.mainContainer && typeof this.mainContainer.invalidate === 'function') {
                  this.mainContainer.invalidate();
                  printl("视图已刷新");
                }
            } catch (e) {
                printl("刷新布局失败: " + e);
            }
      }
      
      // 设置按钮文本
      if (this.toggleButton && typeof this.toggleButton.setText === 'function') {
            try {
                this.toggleButton.setText("≡");
            } catch (e) {
                printl("❌ 设置按钮文本失败: " + e);
            }
      }
      
      // 延迟100ms后记录状态更新,确保UI已更新
      setTimeout(function() {
            try {
                if (widthSetSuccessfully) {
                  printl("✅ " + (self.isExpanded ? "侧栏已展开" : "侧栏已收起"));
                } else {
                  // 只记录第一个错误信息,避免日志过多
                  var mainError = errorMessages.length > 0 ? errorMessages : "未知错误";
                  printl(mainError);
                  printl("⚠️ 侧栏" + (self.isExpanded ? "展开" : "收起") + "但宽度调整失败");
                }
            } catch (e) {
                // 静默处理日志错误
            }
      }, 100);
      
      return widthSetSuccessfully;
    } catch (e) {
      printl("❌ 执行切换展开/收起操作失败: " + e);
      return false;
    }
};

// 添加日志
侧栏日志.prototype.log = function(message, color) {
    try {
      // 生成时间戳
      var now = new Date();
      var timeStr = now.getHours().toString().padStart(2, '0') + ":" +
                      now.getMinutes().toString().padStart(2, '0') + ":" +
                      now.getSeconds().toString().padStart(2, '0');
      
      // 格式化日志条目
      var logEntry = "[" + timeStr + "] " + message;
      
      // 添加到日志数组
      this.logs.push({text: logEntry, color: color || "#00FF00"});
      
      // 限制日志数量
      if (this.logs.length > this.maxLogs) {
            this.logs.shift(); // 移除最早的日志
      }
      
      // 更新显示
      this.updateLogDisplay();
      
      // 同时打印到控制台
      printl(logEntry);
    } catch (e) {
      printl("❌ 添加日志失败: " + e);
    }
};

// 更新日志显示
侧栏日志.prototype.updateLogDisplay = function() {
    try {
      var self = this;
      var uiOperation = function() {
            self.performUpdateLogDisplay();
      };
      
      // 尝试多种UI线程调度方案
      var threadScheduled = false;
      
      // 方案1: 使用context.runOnUiThread
      try {
            if (context && context.runOnUiThread) {
                var runnable = {
                  run: function() {
                        try {
                            uiOperation();
                        } catch (e) {
                            printl("❌ UI线程执行日志更新失败: " + e);
                        }
                  }
                };
                context.runOnUiThread(runnable);
                threadScheduled = true;
            }
      } catch (e) {
            printl("❌ 方案1: context.runOnUiThread调度日志更新失败: " + e);
      }
      
      // 方案2: 使用View.post
      if (!threadScheduled) {
            try {
                var viewToUse = self.logText || self.logContainer || self.mainContainer;
                if (viewToUse && viewToUse.post) {
                  viewToUse.post(function() {
                        try {
                            uiOperation();
                        } catch (e) {
                            printl("❌ View.post执行日志更新失败: " + e);
                        }
                  });
                  threadScheduled = true;
                }
            } catch (e) {
                printl("❌ 方案2: View.post调度日志更新失败: " + e);
            }
      }
      
      // 方案3: 尝试使用Handler
      if (!threadScheduled) {
            try {
                if (typeof Handler !== 'undefined' && typeof Looper !== 'undefined' && Looper.getMainLooper) {
                  var handler = new Handler(Looper.getMainLooper());
                  handler.post(function() {
                        try {
                            uiOperation();
                        } catch (e) {
                            printl("❌ Handler执行日志更新失败: " + e);
                        }
                  });
                  threadScheduled = true;
                }
            } catch (e) {
                printl("❌ 方案3: Handler调度日志更新失败: " + e);
            }
      }
      
      // 方案4: 直接执行作为最后备选
      if (!threadScheduled) {
            try {
                uiOperation();
            } catch (directError) {
                printl("❌ 直接执行日志更新失败: " + directError);
            }
      }
    } catch (e) {
      printl("❌ 更新日志显示失败: " + e);
    }
};

// 执行日志显示更新的核心方法(应在主线程中调用)
侧栏日志.prototype.performUpdateLogDisplay = function() {
    try {
      // 检查logText是否存在
      if (!this.logText || typeof this.logText.setText !== 'function') {
            printl("⚠️ 日志显示组件不可用");
            return;
      }
      
      // 构建日志文本
      var logText = "";
      var useHtml = false;
      
      // 尝试HTML格式
      try {
            if (typeof android.text.Html !== 'undefined' && typeof android.text.Html.fromHtml === 'function') {
                var htmlText = "";
                for (var i = 0; i < this.logs.length; i++) {
                  var log = this.logs;
                  var color = log.color || "#00FF00";
                  htmlText += "<font color=\"" + color + "\">" + log.text + "</font><br/>";
                }
               
                try {
                  var spanned = android.text.Html.fromHtml(htmlText);
                  this.logText.setText(spanned);
                  useHtml = true;
                  printl("✅ 日志使用HTML格式显示");
                } catch (htmlError) {
                  printl("⚠️ HTML格式化失败,回退到纯文本: " + htmlError);
                }
            }
      } catch (e) {
            printl("⚠️ HTML支持不可用: " + e);
      }
      
      // 如果HTML格式失败,使用纯文本格式
      if (!useHtml) {
            for (var i = 0; i < this.logs.length; i++) {
                logText += this.logs.text + "\n";
            }
            
            try {
                this.logText.setText(logText);
                printl("✅ 日志使用纯文本格式显示");
            } catch (textError) {
                printl("❌ 设置日志文本失败: " + textError);
            }
      }
      
      // 尝试滚动到底部
      var self = this;
      try {
            if (this.logContainer && typeof this.logContainer.post === 'function') {
                this.logContainer.post(function() {
                  try {
                        if (self.logContainer && typeof self.logContainer.fullScroll === 'function') {
                            self.logContainer.fullScroll(android.widget.ScrollView.FOCUS_DOWN);
                        }
                  } catch (scrollError) {
                        // 静默处理滚动错误
                  }
                });
            } else if (this.logContainer && typeof this.logContainer.fullScroll === 'function') {
                this.logContainer.fullScroll(android.widget.ScrollView.FOCUS_DOWN);
            }
      } catch (e) {
            // 静默处理滚动错误
      }
    } catch (e) {
      printl("❌ 执行日志显示更新失败: " + e);
    }
};

// 设置悬浮窗位置
侧栏日志.prototype.setPos = function(x, y) {
    try {
      var self = this;
      
      // 参数验证
      if (typeof x !== 'number' || typeof y !== 'number') {
            printl("❌ setPos参数错误: x和y必须是数字");
            return false;
      }
      
      // 边界检查
      var currentWidth = this.isExpanded ? this.sidebarWidth : this.sidebarMinWidth;
      try {
            if (context && context.getResources && context.getResources().getDisplayMetrics) {
                var density = context.getResources().getDisplayMetrics().density;
                currentWidth *= density;
            }
      } catch (e) {
            currentWidth *= 3; // 使用默认密度倍数
      }
      
      if (x < 0) x = 0;
      if (y < 0) y = 0;
      if (x > this.screenWidth - currentWidth) x = this.screenWidth - currentWidth;
      if (y > this.screenHeight - 100) y = this.screenHeight - 100;
      
      // 使用printl避免递归调用
      printl("&#128260; 设置悬浮窗位置: x=" + x + ", y=" + y);
      
      // 定义UI操作函数
      var uiOperation = function() {
            self.performSetPos(x, y);
      };
      
      // 尝试多种UI线程调度方案
      var threadScheduled = false;
      
      // 方案1: 使用context.runOnUiThread
      try {
            if (context && context.runOnUiThread) {
                var runnable = {
                  run: function() {
                        try {
                            uiOperation();
                        } catch (e) {
                            printl("❌ UI线程执行位置设置失败: " + e);
                        }
                  }
                };
                context.runOnUiThread(runnable);
                threadScheduled = true;
                printl("✅ 使用context.runOnUiThread调度位置设置");
            }
      } catch (e) {
            printl("❌ 方案1: context.runOnUiThread调度位置设置失败: " + e);
      }
      
      // 方案2: 使用View.post
      if (!threadScheduled) {
            try {
                var viewToUse = self.mainContainer || self.titleBar || self.toggleButton;
                if (viewToUse && typeof viewToUse.post === 'function') {
                  viewToUse.post(function() {
                        try {
                            uiOperation();
                        } catch (e) {
                            printl("❌ View.post执行位置设置失败: " + e);
                        }
                  });
                  threadScheduled = true;
                  printl("✅ 使用View.post调度位置设置");
                }
            } catch (e) {
                printl("❌ 方案2: View.post调度位置设置失败: " + e);
            }
      }
      
      // 方案3: 尝试使用Handler
      if (!threadScheduled) {
            try {
                if (typeof Handler !== 'undefined' && typeof Looper !== 'undefined' && Looper.getMainLooper) {
                  var handler = new Handler(Looper.getMainLooper());
                  handler.post(function() {
                        try {
                            uiOperation();
                        } catch (e) {
                            printl("❌ Handler执行位置设置失败: " + e);
                        }
                  });
                  threadScheduled = true;
                  printl("✅ 使用Handler调度位置设置");
                }
            } catch (e) {
                printl("❌ 方案3: Handler调度位置设置失败: " + e);
            }
      }
      
      // 方案4: 直接执行作为最后备选
      if (!threadScheduled) {
            printl("⚠️ 所有线程调度方案失败,尝试直接执行位置设置");
            try {
                uiOperation();
            } catch (directError) {
                printl("❌ 直接执行位置设置失败: " + directError);
            }
      }
      
      return true;
    } catch (e) {
      printl("❌ 设置位置失败: " + e);
      return false;
    }
};

// 执行设置位置的核心方法(应在主线程中调用)
侧栏日志.prototype.performSetPos = function(x, y) {
    try {
      var posSetSuccess = false;
      
      // 方案1: 尝试使用floatUI的setPos方法
      try {
            if (this.ui && this.ui.setPos) {
                this.ui.setPos(x, y);
                posSetSuccess = true;
                printl("✅ 方案1: 使用floatUI.setPos设置位置成功");
            }
      } catch (e) {
            printl("❌ 方案1: floatUI.setPos失败: " + e);
      }
      
      // 方案2: 尝试使用floatUI的setPosition方法
      if (!posSetSuccess) {
            try {
                if (this.ui && this.ui.setPosition) {
                  this.ui.setPosition(x, y);
                  posSetSuccess = true;
                  printl("✅ 方案2: 使用floatUI.setPosition设置位置成功");
                }
            } catch (e) {
                printl("❌ 方案2: floatUI.setPosition失败: " + e);
            }
      }
      
      // 方案3: 尝试使用setX和setY方法(如果可用)
      if (!posSetSuccess) {
            try {
                if (this.ui && typeof this.ui.setX === 'function' && typeof this.ui.setY === 'function') {
                  this.ui.setX(x);
                  this.ui.setY(y);
                  posSetSuccess = true;
                  printl("✅ 方案3: 使用ui.setX/setY设置位置成功");
                }
            } catch (e) {
                printl("❌ 方案3: ui.setX/setY失败: " + e);
            }
      }
      
      // 方案4: 尝试通过mainContainer设置位置
      if (!posSetSuccess) {
            try {
                if (this.mainContainer && typeof this.mainContainer.setX === 'function' && typeof this.mainContainer.setY === 'function') {
                  this.mainContainer.setX(x);
                  this.mainContainer.setY(y);
                  posSetSuccess = true;
                  printl("✅ 方案4: 使用mainContainer.setX/setY设置位置成功");
                }
            } catch (e) {
                printl("❌ 方案4: mainContainer.setX/setY失败: " + e);
            }
      }
      
      // 方案5: 尝试通过直接访问mainContainer设置位置
      if (!posSetSuccess) {
            try {
                if (this.mainContainer && typeof this.mainContainer.layout === 'function' && typeof this.mainContainer.getWidth === 'function' && typeof this.mainContainer.getHeight === 'function') {
                  this.mainContainer.layout(x, y, x + this.mainContainer.getWidth(), y + this.mainContainer.getHeight());
                  posSetSuccess = true;
                  printl("✅ 方案5: 使用layout方法设置位置成功");
                }
            } catch (e) {
                printl("❌ 方案5: layout方法失败: " + e);
            }
      }
      
      // 刷新UI确保位置更新生效
      if (posSetSuccess) {
            try {
                // 尝试多种刷新方法
                if (this.mainContainer) {
                  if (typeof this.mainContainer.invalidate === 'function') {
                        this.mainContainer.invalidate();
                  }
                  if (typeof this.mainContainer.requestLayout === 'function') {
                        this.mainContainer.requestLayout();
                  }
                }
                printl("✅ 位置设置刷新完成");
            } catch (refreshError) {
                printl("⚠️ 刷新位置时出错: " + refreshError);
            }
      } else {
            printl("⚠️ 位置设置完成但可能未生效");
      }
      
      return posSetSuccess;
    } catch (e) {
      printl("❌ 执行位置设置失败: " + e);
      return false;
    }
};

// 清空日志
侧栏日志.prototype.clearLogs = function() {
    try {
      // 清空日志数组
      this.logs = [];
      
      // 清空日志显示
      if (this.logText && this.logText.setText) {
            try {
                this.logText.setText("");
            } catch (setTextError) {
                printl("⚠️ 清空日志显示失败: " + setTextError);
            }
      }
      
      // 记录清空操作
      this.log("&#128465;️ 日志已清空", "#FF0000");
      return true;
    } catch (e) {
      printl("❌ 清空日志失败: " + e);
      return false;
    }
};

// 关闭悬浮窗
侧栏日志.prototype.close = function() {
    try {
      var self = this;
      
      // 使用printl避免递归调用
      printl("&#128260; 正在关闭侧栏日志悬浮窗...");
      
      // 定义UI操作函数
      var uiOperation = function() {
            self.performClose();
      };
      
      // 尝试多种UI线程调度方案
      var threadScheduled = false;
      
      // 方案1: 使用context.runOnUiThread
      try {
            if (context && context.runOnUiThread) {
                var runnable = {
                  run: function() {
                        try {
                            uiOperation();
                        } catch (e) {
                            printl("❌ UI线程执行关闭操作失败: " + e);
                        }
                  }
                };
                context.runOnUiThread(runnable);
                threadScheduled = true;
                printl("✅ 使用context.runOnUiThread调度关闭操作");
            }
      } catch (e) {
            printl("❌ 方案1: context.runOnUiThread调度关闭操作失败: " + e);
      }
      
      // 方案2: 使用View.post
      if (!threadScheduled) {
            try {
                var viewToUse = self.mainContainer || self.titleBar || self.toggleButton;
                if (viewToUse && typeof viewToUse.post === 'function') {
                  viewToUse.post(function() {
                        try {
                            uiOperation();
                        } catch (e) {
                            printl("❌ View.post执行关闭操作失败: " + e);
                        }
                  });
                  threadScheduled = true;
                  printl("✅ 使用View.post调度关闭操作");
                }
            } catch (e) {
                printl("❌ 方案2: View.post调度关闭操作失败: " + e);
            }
      }
      
      // 方案3: 尝试使用Handler
      if (!threadScheduled) {
            try {
                if (typeof Handler !== 'undefined' && typeof Looper !== 'undefined' && Looper.getMainLooper) {
                  var handler = new Handler(Looper.getMainLooper());
                  handler.post(function() {
                        try {
                            uiOperation();
                        } catch (e) {
                            printl("❌ Handler执行关闭操作失败: " + e);
                        }
                  });
                  threadScheduled = true;
                  printl("✅ 使用Handler调度关闭操作");
                }
            } catch (e) {
                printl("❌ 方案3: Handler调度关闭操作失败: " + e);
            }
      }
      
      // 方案4: 直接执行作为最后备选
      if (!threadScheduled) {
            printl("⚠️ 所有线程调度方案失败,尝试直接执行关闭操作");
            try {
                uiOperation();
            } catch (directError) {
                printl("❌ 直接执行关闭操作失败: " + directError);
            }
      }
    } catch (e) {
      printl("❌ 关闭侧栏日志悬浮窗失败: " + e);
    }
};

// 执行关闭操作的核心方法(应在主线程中调用)
侧栏日志.prototype.performClose = function() {
    try {
      printl("&#128260; 执行悬浮窗关闭操作...");
      
      // 尝试多种关闭方案
      var closeSuccess = false;
      
      // 方案1: 尝试使用close方法
      try {
            if (this.ui && typeof this.ui.close === 'function') {
                this.ui.close();
                closeSuccess = true;
                printl("✅ 方案1: 使用ui.close()成功关闭");
            }
      } catch (e) {
            printl("❌ 方案1: 使用ui.close()关闭失败: " + e);
      }
      
      // 方案2: 尝试使用destroy方法
      if (!closeSuccess) {
            try {
                if (this.ui && typeof this.ui.destroy === 'function') {
                  this.ui.destroy();
                  closeSuccess = true;
                  printl("✅ 方案2: 使用ui.destroy()成功关闭");
                }
            } catch (e) {
                printl("❌ 方案2: 使用ui.destroy()关闭失败: " + e);
            }
      }
      
      // 方案3: 尝试从父容器移除
      if (!closeSuccess) {
            try {
                if (this.mainContainer && typeof this.mainContainer.getParent === 'function') {
                  var parent = this.mainContainer.getParent();
                  if (parent && typeof parent.removeView === 'function') {
                        parent.removeView(this.mainContainer);
                        closeSuccess = true;
                        printl("✅ 方案3: 从父容器移除成功");
                  }
                }
            } catch (e) {
                printl("❌ 方案3: 从父容器移除失败: " + e);
            }
      }
      
      // 方案4: 尝试隐藏视图
      if (!closeSuccess) {
            try {
                if (this.mainContainer && typeof this.mainContainer.setVisibility === 'function') {
                  this.mainContainer.setVisibility(View.GONE);
                  closeSuccess = true;
                  printl("✅ 方案4: 隐藏视图成功");
                }
            } catch (e) {
                printl("❌ 方案4: 隐藏视图失败: " + e);
            }
      }
      
      // 清理资源
      try {
            // 清除事件监听器
            if (this.titleBar && typeof this.titleBar.setOnTouchListener === 'function') {
                this.titleBar.setOnTouchListener(null);
            }
            if (this.toggleButton && typeof this.toggleButton.setOnClickListener === 'function') {
                this.toggleButton.setOnClickListener(null);
            }
            if (this.closeButton && typeof this.closeButton.setOnClickListener === 'function') {
                this.closeButton.setOnClickListener(null);
            }
            
            // 清除引用,帮助垃圾回收
            this.ui = null;
            this.mainContainer = null;
            this.titleBar = null;
            this.toggleButton = null;
            this.closeButton = null;
            this.titleText = null;
            this.logContainer = null;
            this.logText = null;
            this.logs = null;
            
            printl("✅ 资源清理完成");
      } catch (cleanupError) {
            printl("⚠️ 资源清理时出错: " + cleanupError);
      }
      
      // 更新状态
      sidebarLogger = null;
      
      // 记录关闭结果
      if (closeSuccess) {
            printl("✅ 侧栏日志悬浮窗已成功关闭");
      } else {
            printl("⚠️ 侧栏日志悬浮窗尝试关闭,但可能未完全成功");
      }
      
      return closeSuccess;
    } catch (e) {
      printl("❌ 执行关闭操作失败: " + e);
      return false;
    }
};

// 创建并启动侧栏日志悬浮窗
var sidebarLogger = null;

// 版本信息
const SIDEBAR_LOGGER_VERSION = "1.2.0";

// 初始化悬浮窗
function initSidebarLogger(options) {
    try {
      // 防止重复初始化
      if (sidebarLogger) {
            printl("⚠️ 侧栏日志已经初始化,无需重复创建");
            return sidebarLogger;
      }
      
      // 合并默认选项和用户选项
      options = options || {};
      
      // 环境检查
      if (typeof floatUI === 'undefined') {
            printl("❌ 错误:未找到floatUI库,请确保在AIWROK环境中运行!");
            return null;
      }
      
      // 打印启动信息
      printl("====================================");
      printl("&#128260; 侧栏日志悬浮窗初始化中...");
      printl("&#128241; 版本: " + SIDEBAR_LOGGER_VERSION);
      printl("====================================");
      
      // 创建悬浮窗实例
      sidebarLogger = new 侧栏日志();
      
      // 创建悬浮窗
      if (sidebarLogger.create()) {
            printl("✅ 侧栏日志悬浮窗已创建成功!");
            
            // 添加欢迎日志
            sidebarLogger.log("&#127881; 欢迎使用侧栏日志工具", "#00FFFF");
            sidebarLogger.log("&#128241; 版本: " + SIDEBAR_LOGGER_VERSION, "#00FFFF");
            sidebarLogger.log("&#128161; 点击≡按钮展开/收起侧栏", "#FFFF00");
            sidebarLogger.log("&#128260; 拖动标题栏可移动悬浮窗", "#FFFF00");
            sidebarLogger.log("&#128465;️ 右上角关闭按钮可关闭悬浮窗", "#FFFF00");
            sidebarLogger.log("&#128161; 可使用sidebarLogger.log()添加自定义日志", "#00FF00");
            
            // 自动展开悬浮窗,让用户看到关闭按钮
            try {
                setTimeout(function() {
                  if (sidebarLogger && typeof sidebarLogger.toggleExpand === 'function') {
                        sidebarLogger.toggleExpand();
                  }
                }, 500);
            } catch (autoExpandError) {
                printl("⚠️ 自动展开失败: " + autoExpandError);
            }
            
            return sidebarLogger;
      } else {
            printl("❌ 侧栏日志悬浮窗创建失败!");
            sidebarLogger = null;
            return null;
      }
    } catch (e) {
      printl("❌ 初始化侧栏日志失败: " + e);
      sidebarLogger = null;
      return null;
    }
}

// 安全获取侧栏日志实例
function getSidebarLogger() {
    return sidebarLogger;
}

// 安全地记录日志(即使悬浮窗未初始化也不会报错)
function safeLog(message, color) {
    if (sidebarLogger && typeof sidebarLogger.log === 'function') {
      try {
            sidebarLogger.log(message, color);
            return true;
      } catch (e) {
            printl("⚠️ 记录日志失败: " + e);
      }
    }
    // 降级到console.log
    printl(message || "");
    return false;
}

// 启动悬浮窗
try {
    // 延迟初始化,确保环境准备就绪
    setTimeout(function() {
      initSidebarLogger();
    }, 100);
} catch (startupError) {
    printl("❌ 启动悬浮窗失败: " + startupError);
    // 作为最后的备选,尝试直接初始化
    try {
      initSidebarLogger();
    } catch (finalError) {
      printl("❌ 直接初始化也失败: " + finalError);
    }
}

页: [1]
查看完整版本: AIWROK软件支持悬浮窗自由定位和拖拽功能