【问题标题】:Android app - save sensor data to local fileAndroid 应用程序 - 将传感器数据保存到本地文件
【发布时间】:2021-01-31 15:41:58
【问题描述】:

我正在做一个项目来记录来自加速度传感器 (xyz) 的数据并将其保存到手机上的文件中。我找到了一个代码 sn-p,它从连接的传感器中检索数据,但没有将其保存在找到的传感器上。不幸的是,我根本不了解 Java,所以我希望这里有人提示要添加什么以实现节省部分。我假设我需要不断地将 onSensorChanged 中的变量(变量 accx、accy、acz)附加到一个对象,然后在我停止录制时保存它。

编辑: 我声明了以下数组列表。 3个用于我的传感器数据,1个用于写入相应的时间戳。

final ArrayList<Integer> arrlist_ts = new ArrayList<Integer>(5);
final ArrayList<Integer> arrlist_x = new ArrayList<Integer>(5);
final ArrayList<Integer> arrlist_y = new ArrayList<Integer>(5);
final ArrayList<Integer> arrlist_z = new ArrayList<Integer>(5);

我将添加到数组的命令放在 run() 函数中,就在变量 String out_text 之后。

然后,我将字符串连接放在 if (timer1 != null) 条件下的函数 stopRecording() 中。那有意义吗? 然后我会将代码保存到同一位置的文件中。

这里是代码

package pervasive_recorder;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.ArrayList;

import android.os.Handler;
import android.os.Message;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Binder;
import android.os.IBinder;
import android.support.v4.app.TaskStackBuilder;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;


public class ARFFRecorderService extends Service implements SensorEventListener {

    private int NOTIFICATION = R.string.recording;

    private final IBinder mBinder = new LocalBinder();
    private NotificationManager mNM;
    private boolean recording = false;
    private SensorManager mSensorManager;
    private Sensor mAccelerometer;
    private ARFFRecorderActivity clientActivity = null;
    private int ts, accx, accy, accz;
    static Timer timer1 = null;

    final ArrayList<Integer> arrlist_ts = new ArrayList<Integer>(5);
    final ArrayList<Integer> arrlist_x = new ArrayList<Integer>(5);
    final ArrayList<Integer> arrlist_y = new ArrayList<Integer>(5);
    final ArrayList<Integer> arrlist_z = new ArrayList<Integer>(5);

    public class LocalBinder extends Binder {
        ARFFRecorderService getService() {
            return ARFFRecorderService.this;
        }
    }

    @Override
    public void onCreate() {
        mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    }

    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            if (clientActivity != null) clientActivity.updateAccStatus("Callback handler");
            return true;
        }
    });

    public void setClientActivity(ARFFRecorderActivity clientActivity) {
        this.clientActivity = clientActivity;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (clientActivity.disp_rate > 0) {
            timer1 = new Timer();
            timer1.schedule(new TimerTask() {
                @Override
                public void run() {
                    String out_text = "acc  x = " + accx + "  y = " + accy  + "  z = " + accz;
                    arrlist_ts.add(ts);
                    arrlist_x.add(accx);
                    arrlist_y.add(accy);
                    arrlist_z.add(accz);
                    if (clientActivity != null) clientActivity.updateAccStatus(out_text);
                }
            }, 1000, (int) (1000 / clientActivity.disp_rate));
        }

        if (!recording) {
            recording = true;
            NotificationCompat.Builder mBuilder =
                    new NotificationCompat.Builder(this)
                            .setSmallIcon(R.mipmap.ic_launcher)
                            .setContentTitle(getText(R.string.app_name))
                            .setContentText(getText(R.string.recording));
            Intent resultIntent = new Intent(this, ARFFRecorderActivity.class);
            TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
            stackBuilder.addParentStack(ARFFRecorderActivity.class);
            stackBuilder.addNextIntent(resultIntent);
            PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
            mBuilder.setContentIntent(resultPendingIntent);
            mNM.notify(NOTIFICATION, mBuilder.build());

            mSensorManager.registerListener(this, mAccelerometer, clientActivity.samp_rate);
            if (clientActivity != null) clientActivity.updateAccStatus("acc started");
        }
        return START_STICKY;
    }

    public void onSensorChanged(SensorEvent e) {
        ts = (int) (new Date().getTime()/1000);
        accx = (int) (100000 * e.values[0]);
        accy = (int) (100000 * e.values[1]);
        accz = (int) (100000 * e.values[2]);
    }

    private void showMessage(String text) {
        Toast toast = Toast.makeText(this, text, Toast.LENGTH_LONG);
        toast.show();
    }

    @Override
    public void onDestroy() {
        stopRecording();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

    public boolean isRecording() {
        return recording;
    }

    public void stopRecording() {
        if (recording) {
            mSensorManager.unregisterListener(this);
            mNM.cancel(NOTIFICATION);
            recording = false;
            if (timer1 != null) {
                String s_ts = "";
                String s_x = "";
                String s_y = "";
                String s_z = "";
                StringBuilder sb_ts = new StringBuilder();
                for (int i = 0; i < arrlist_ts.size(); i++) {
                    sb_ts.append(arrlist_ts.get(i));
                }
                StringBuilder sb_x = new StringBuilder();
                for (int i = 0; i < arrlist_x.size(); i++) {
                    sb_x.append(arrlist_x.get(i));
                }
                StringBuilder sb_y = new StringBuilder();
                for (int i = 0; i < arrlist_ts.size(); i++) {
                    sb_y.append(arrlist_y.get(i));
                }
                StringBuilder sb_z = new StringBuilder();
                for (int i = 0; i < arrlist_ts.size(); i++) {
                    sb_z.append(arrlist_z.get(i));
                }
                s_ts = sb_ts.toString();
                s_x = sb_x.toString();
                s_y = sb_y.toString();
                s_z = sb_z.toString();
                timer1.cancel();
            }
            if (clientActivity != null) clientActivity.updateAccStatus("acc stopped");
            stopSelf();
        }
    }

}

【问题讨论】:

    标签: java android


    【解决方案1】:

    这里有一些 DOC 以及用于存储数据的所有选项,也许 SharedPreferences 会更好/更容易实现?

    如果您真的需要存储/sd 卡上的文件,请查看THIS SO question and answers,还有一个官方的DOC 部分关于这种方式

    【讨论】:

    • 您好,感谢您提供的链接。问题是我对 java 的了解为零,所以即使有文档 sn-ps,我也会感谢一些指向特定用例的指针
    • 所以 Stack Overflow 不适合您,因为我们在这里帮助解决问题,而不是为用户提供完整的解决方案,甚至没有尝试自行解决问题
    • 对不起,我的意思不是一个完整的解决方案。对我来说,问题是我什至不确定包含传感器数据的正确变量是什么。我的假设是数据流式传输到变量 accx = (int) (100000 * e.values[0]); accy = (int) (100000 * e.values[1]); accz = (int) (100000 * e.values[2]);我想我需要不断地将这些变量附加到某种列表中,并在收集数据结束时将此列表保存到文件中。我不确定这是否是正确的方法,这就是我所说的指向特定用例的意思。
    • accxaccyaccz 添加到一些ArrayLists(每个轴一个)。当您停止记录数据时,将这些数组中的所有值转换为例如String 用分号; 分隔它们(例如String accxAsString = accxArray.get(0)+";"+accxArray.get(1)+";"+... - 在for 循环中进行此操作)。 String 可以很容易地存储为文本文件,在我的答案中查看链接
    • 感谢您的帮助,我相应地调整了我的代码。我编辑了我的原始帖子以检查天气我的更改是否有意义。我认为将 array.add() 命令放在 run 函数中以获取最新的传感器输入是有意义的,并且还向 onSensorChanged 添加了一个时间戳,以便为收集的每个传感器数据点设置一个时间戳
    猜你喜欢
    • 2013-02-03
    • 2019-10-14
    • 2023-03-26
    • 1970-01-01
    • 2017-12-12
    • 1970-01-01
    • 2018-05-14
    • 1970-01-01
    • 2014-08-13
    相关资源
    最近更新 更多