本人想实现一个Main1Activity生成的三种不同随机数传到Main2Activity中去,并且在Main2Activity做出相关的数据显示,于是就有了本篇文章。
1.在Main1Activitity
private ArrayList<SensorData> historicalData;//定义一个中继SensorData.java——在传输数据中 起到连接的作用
private static final int MAX_HISTORY_SIZE = 10; // 最多存储10条历史数据
private Button analysisLayout;//开启数据传输
//随机值
private TextView wd,sd,gz,tf;
private Handler handler;
private Random random;
private DecimalFormat decimalFormat; // 用于格式化带一位小数的数字
// 随机值范围和更新间隔常量
private final double MIN_TEMPERATURE = 26.0;
private final double MAX_TEMPERATURE = 29.0;
private final double MIN_HUMIDITY = 75.0;
private final double MAX_HUMIDITY = 77.0;
private final int MIN_LIGHT = 15000;
private final int MAX_LIGHT = 23000;
// 新增:用于 Analysis Activity 读取的纯数值 static 变量
public static float currentTempValue = 26.0f; // 默认初始值
public static float currentHumValue = 75.0f; // 默认初始值
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_myname);
wd=findViewById(R.id.wendu);
sd=findViewById(R.id.shidu);
gz=findViewById(R.id.guangzhao);
tf=findViewById(R.id.turang);
handler=new Handler(Looper.getMainLooper());
random=new Random();
decimalFormat=new DecimalFormat("0.0");
//初始化列表
historicalData=new ArrayList<SensorData>();//初始化历史数据列表
Test();
analysisLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setSelectedTab(2);
Intent intent=new Intent(manage.this,Analysis.class);
intent.putParcelableArrayListExtra("initial_history_data", historicalData); // <--- 注意:这里参数名建议和实时广播的不同
startActivity(intent);
}
});
handler.post(fetch());
}
private void Test(){
handler.postDelayed(new Runnable() {
@Override
public void run() {
fetch();
Test();
}
},3000);
}
private Runnable fetch(){
// 生成随机温度 (26.0 - 33.0)
// random.nextDouble() 返回 [0.0, 1.0)
double tempValue=MIN_TEMPERATURE+(MAX_TEMPERATURE-MIN_TEMPERATURE)*random.nextDouble();
// 可选: 做一次边界限制确保严格在范围内 (虽然数学上一般不需要,但nextDouble的精度问题可能导致非常接近边界的值)
tempValue=Math.min(MAX_TEMPERATURE,Math.max(MIN_TEMPERATURE,tempValue));
if (wd!=null){
wd.setText("温度"+decimalFormat.format(tempValue)+"℃");
}
manage.currentTempValue=(float) tempValue;
double humValue=MIN_HUMIDITY+(MAX_HUMIDITY-MIN_HUMIDITY)*random.nextDouble();
humValue=Math.min(MAX_HUMIDITY,Math.max(MIN_HUMIDITY,humValue));
if (sd!=null){
sd.setText("湿度:"+decimalFormat.format(humValue)+"%");
}
manage.currentHumValue=(float) humValue;
int lightValue=random.nextInt(MAX_LIGHT-MIN_LIGHT+1)+MIN_LIGHT;
if (gz!=null){
gz.setText("光照:"+String.valueOf(lightValue)+"lux");
}
if (tf!=null){
tf.setText("土壤肥力等级:"+"-");
}
//将新的数据添加到历史列表中
SensorData currentData=new SensorData((float) tempValue,(float) humValue);
historicalData.add(currentData);
// 如果历史数据量超过最大限制,移除最旧的一条
if (historicalData.size()>MAX_HISTORY_SIZE){
historicalData.remove(0);//移除列表头部最旧的数据
}
Intent dataUpdateIntent = new Intent("com.example.myapplication.SENSOR_DATA_REALTIME_UPDATE"); // 定义一个唯一的动作字符串
dataUpdateIntent.putParcelableArrayListExtra("updated_history_data", historicalData); // 传递最新的整个列表
LocalBroadcastManager.getInstance(this).sendBroadcast(dataUpdateIntent); // 发送本地广播
Log.d(TAG, "Sent broadcast with " + historicalData.size() + " data points.");
return null;
}
@Override
protected void onDestroy() {
super.onDestroy();
if (handler!=null){
handler.removeCallbacksAndMessages(null);
handler=null;//防止内存泄漏
}
}
2.中继SensorData文件
import android.os.Parcel;
import android.os.Parcelable;
import com.example.myapplication.SimpleImageLoader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
public class SensorData implements Parcelable {
private float temperature;
private float humidity;
private long timestamp; // 记录数据生成的时间戳
public SensorData(float temperature, float humidity) {
this.temperature = temperature;
this.humidity = humidity;
this.timestamp = System.currentTimeMillis(); // 构造时记录当前时间
}
public float getTemperature() {
return temperature;
}
public float getHumidity() {
return humidity;
}
public long getTimestamp() {
return timestamp;
}
// 重写 toString 方法,方便显示
@Override
public String toString() {
// 格式化时间戳为可读的字符串
// HH:mm:ss 表示时:分:秒,mm/dd 表示月/日,您可以根据需要调整格式
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm", Locale.getDefault());
String timeStr = sdf.format(new Date(timestamp));
return String.format(Locale.getDefault(), "[%s] 温度: %.1f°C, 湿度: %.1f%%",
timeStr, temperature, humidity);
}
// --- Parcelable Implementation ---
// 构造函数,用于从Parcel中恢复对象
protected SensorData(Parcel in) {
temperature = in.readFloat();
humidity = in.readFloat();
timestamp = in.readLong();
}
// CREATOR 对象,用于反序列化
// 这是实现 Parcelable 接口必须有的一个静态 final 字段
public static final Creator<SensorData> CREATOR = new Creator<SensorData>() {
@Override
public SensorData createFromParcel(Parcel in) {
return new SensorData(in);
}
@Override
public SensorData[] newArray(int size) {
return new SensorData[size];
}
};
@Override
public int describeContents() {
return 0; // 大多数情况下返回0即可,除非你的Parcelable包含了FileDescriptor这样的特殊数据
}
@Override
public void writeToParcel(Parcel dest, int flags) {
// 将对象数据写入Parcel
dest.writeFloat(temperature);
dest.writeFloat(humidity);
dest.writeLong(timestamp);
}
}
3.Main2Activity
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="*"
android:background="@drawable/border_white_gray"
android:padding="8dp"
android:layout_margin="8dp">
<TextView
android:id="@+id/historyTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:textSize="18sp"
android:text="历史数据加载中..." />
private BroadcastReceiver sensorDataReceiver; // 声明一个广播接收器
private ArrayList<SensorData> currentHistoricalData=new ArrayList<>(); // 用于存储从广播接收到的最新历史数据
private static final String TAG="Analysis_log";//过滤日志
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_analysis);
handler.post(SQL_Lite());
}
private Runnable SQL_Lite() {
historyTextView = findViewById(R.id.historyTextView);
try {
// 获取初始历史数据
ArrayList<SensorData> historicalData = getIntent().getParcelableArrayListExtra("initial_history_data");
if (historicalData != null && !historicalData.isEmpty()) {
Log.d(TAG, "Received initial historicalData with size: " + historicalData.size());
currentHistoricalData.addAll(historicalData); // 存储初始数据
updateHistoryDisplay(currentHistoricalData);
}
} catch (Exception e) {
Log.e(TAG, "Error processing initial data.", e);
historyTextView.setText("加载历史数据时发生错误。");
}
// 注册广播接收器,用于实时接收数据更新
sensorDataReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if ("com.example.myapplication.SENSOR_DATA_REALTIME_UPDATE".equals(intent.getAction())) {
Log.d(TAG, "Received sensor data update broadcast.");
ArrayList<SensorData> updatedData = intent.getParcelableArrayListExtra("updated_history_data");
if (updatedData != null) {
currentHistoricalData.clear(); // 清空旧数据
currentHistoricalData.addAll(updatedData); // 添加新数据
updateHistoryDisplay(currentHistoricalData); // 更新 TextView
}
}
}
};
IntentFilter filter = new IntentFilter("com.example.myapplication.SENSOR_DATA_REALTIME_UPDATE");
LocalBroadcastManager.getInstance(this).registerReceiver(sensorDataReceiver, filter);
Log.d(TAG, "BroadcastReceiver registered.");
return null;
}
private void updateHistoryDisplay(List<SensorData> dataList) {
if (dataList == null || dataList.isEmpty()) {
historyTextView.setText("当前暂无历史数据。");
return;
}
StringBuilder historyBuilder = new StringBuilder();
historyBuilder.append("历史温湿度数据:\n\n");
for (SensorData data : dataList) {
historyBuilder.append(data.toString()).append("\n"); // 使用 SensorData 的 toString 方法
}
historyTextView.setText(historyBuilder.toString());
}