Android应用程序 – 将传感器数据保存到本地文件

huangapple go评论60阅读模式
英文:

Android app - save sensor data to local file

问题

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();
        }
    }
}
英文:

I'm doing a project to record data from an accelerometer sensor (xyz) and save it to a file on my phone. I found a code snippet which retrieves the data from the connected sensor but doesnt save it on the found. Unfortunately I dont know Java at all so I was hoping someone here a tip what to add to achive the saving part. I assume I need to continuously append the variables from onSensorChanged (variables accx, accy, accz) to a object and then save it when I stop recording.

EDIT:
I declared the following array lists. 3 for my sensor data and one to write the corresponding timestamps.

final ArrayList&lt;Integer&gt; arrlist_ts = new ArrayList&lt;Integer&gt;(5);
final ArrayList&lt;Integer&gt; arrlist_x = new ArrayList&lt;Integer&gt;(5);
final ArrayList&lt;Integer&gt; arrlist_y = new ArrayList&lt;Integer&gt;(5);
final ArrayList&lt;Integer&gt; arrlist_z = new ArrayList&lt;Integer&gt;(5);

I placed the add-to-array commands in the run() function right after the variable String out_text.

I then put the string concatenation in the function stopRecording() in the if (timer1 != null) condition. Does that make sense?
I would then put the code to save the strings to a file at the same location.

Here is the code

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&lt;Integer&gt; arrlist_ts = new ArrayList&lt;Integer&gt;(5);
final ArrayList&lt;Integer&gt; arrlist_x = new ArrayList&lt;Integer&gt;(5);
final ArrayList&lt;Integer&gt; arrlist_y = new ArrayList&lt;Integer&gt;(5);
final ArrayList&lt;Integer&gt; arrlist_z = new ArrayList&lt;Integer&gt;(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(&quot;Callback handler&quot;);
return true;
}
});
public void setClientActivity(ARFFRecorderActivity clientActivity) {
this.clientActivity = clientActivity;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (clientActivity.disp_rate &gt; 0) {
timer1 = new Timer();
timer1.schedule(new TimerTask() {
@Override
public void run() {
String out_text = &quot;acc  x = &quot; + accx + &quot;  y = &quot; + accy  + &quot;  z = &quot; + 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(&quot;acc started&quot;);
}
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 = &quot;&quot;;
String s_x = &quot;&quot;;
String s_y = &quot;&quot;;
String s_z = &quot;&quot;;
StringBuilder sb_ts = new StringBuilder();
for (int i = 0; i &lt; arrlist_ts.size(); i++) {
sb_ts.append(arrlist_ts.get(i));
}
StringBuilder sb_x = new StringBuilder();
for (int i = 0; i &lt; arrlist_x.size(); i++) {
sb_x.append(arrlist_x.get(i));
}
StringBuilder sb_y = new StringBuilder();
for (int i = 0; i &lt; arrlist_ts.size(); i++) {
sb_y.append(arrlist_y.get(i));
}
StringBuilder sb_z = new StringBuilder();
for (int i = 0; i &lt; 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(&quot;acc stopped&quot;);
stopSelf();
}
}
}

答案1

得分: 1

这里有一些文档,涵盖了存储数据的所有选项,也许使用SharedPreferences(共享首选项)会更好/更容易实现?

如果你真的需要在存储/SD卡上的文件,那么可以查看这个栈溢出的问题和答案,还有一个官方的文档章节介绍了这种方法。

英文:

here you have some DOC with all options for storing data, maybe SharedPreferences would be better/easier to implement?

if you really need a file on storage/sd card then check out THIS SO question and answers, there is also an official DOC section about this way

huangapple
  • 本文由 发表于 2020年10月17日 16:50:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/64400649.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定