Запись данных с сенсоров в базу данных.
Добавлено: 15 май 2013, 11:14
Здравствуйте.
Разрабатываю приложение, которое будет сохранять данные с сенсоров (акселерометра, гироскопа и датчика магнитных полей) в базу данных.
Решил действовать по такой схеме:
В активити запускаю сервис, который снимает данные с сенсоров и отправляет их в активити в текстовые поля, и в контент провайдер, который сохраняет эти данные в базу.
Проблема заключается в том, что активити зависает при старте сервиса. При чем если в контент провайдер данные не отправлять, но все работает прекрасно.
Было, да собственно и остается, предположение что забивается главный поток, пытался использовать intentService, ситуация та же...
Подскажите, может быть мой подход в корне не верен?
MainActivity
Сервис
провайдер
манифест
Разрабатываю приложение, которое будет сохранять данные с сенсоров (акселерометра, гироскопа и датчика магнитных полей) в базу данных.
Решил действовать по такой схеме:
В активити запускаю сервис, который снимает данные с сенсоров и отправляет их в активити в текстовые поля, и в контент провайдер, который сохраняет эти данные в базу.
Проблема заключается в том, что активити зависает при старте сервиса. При чем если в контент провайдер данные не отправлять, но все работает прекрасно.
Было, да собственно и остается, предположение что забивается главный поток, пытался использовать intentService, ситуация та же...
Подскажите, может быть мой подход в корне не верен?
MainActivity
Код: Выделить всё
public class MainActivity extends Activity {
final String LOG_TAG = "myLogs";
String timeValue,accelValue, gyroValue,compassValue;
public final static String BROADCAST_ACTION = "ru.sibnia.develop.intentservice";
TextView tv1,tv2,tv3,tv4;
BroadcastReceiver br;
public Intent intent;
public final static String VAL1 = "val1";
public final static String VAL2 = "val2";
public final static String VAL3 = "val3";
public final static String VAL4 = "val4";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv1 = (TextView) findViewById (R.id.tv1);
tv2 = (TextView) findViewById (R.id.tv2);
tv3 = (TextView) findViewById (R.id.tv3);
tv4 = (TextView) findViewById (R.id.tv4);
br = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
String accel = intent.getStringExtra(VAL1);
tv1.setText(accel);
String gyro = intent.getStringExtra(VAL2);
tv2.setText(gyro);
String compass = intent.getStringExtra(VAL3);
tv3.setText(compass);
String time = intent.getStringExtra(VAL4);
tv4.setText(time);
}
};
IntentFilter intFilt = new IntentFilter(BROADCAST_ACTION);
registerReceiver(br, intFilt);
}
public void onClickStart(View v) {
startService(new Intent(this, IntService.class));
}
public void onClickStop(View v) {
stopService(new Intent(this, IntService.class));
}
}Код: Выделить всё
public class IntService extends IntentService implements SensorEventListener {
final String LOG_TAG = "myLogs";
SensorManager mgr;
Intent intent;
Calendar c;
int mHour, mMinute, mSecond,mlSecond;
String timeValue,accelValue, gyroValue,compassValue;
private float[] accelData;
private float[] compassData;
private float[] gyroData;
final String DATA_TIME = "time";
final String DATA_ACCEL = "accel";
final String DATA_GYRO = "gyro";
final String DATA_COMPASS = "compass";
final Uri DATA_URI = Uri.parse("content://ru.sibnia.provider.IntProvider/data");
public IntService() {
super("intentService");
}
public void onCreate() {
super.onCreate();
Log.d(LOG_TAG, "onCreate");
accelData = new float[3];
compassData = new float[3];
gyroData = new float[3];
mgr = (SensorManager) this.getSystemService(SENSOR_SERVICE);
mgr.registerListener(this, mgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);
mgr.registerListener(this, mgr.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_UI);
mgr.registerListener(this, mgr.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI);
}
@Override
protected void onHandleIntent(Intent intent) {
// Чтоб сервис работал пока его не закроют в MainActivity
for (int i=1; i>0;i++){
}
}
// копирование данных сенсоров в массивы
private void loadSensorData (SensorEvent event){
c = Calendar.getInstance();
switch (event.sensor.getType()){
case Sensor.TYPE_ACCELEROMETER:
for (int i=0; i<3; i++)
accelData[i] = event.values[i];
break;
case Sensor.TYPE_MAGNETIC_FIELD:
for (int i=0; i<3; i++)
compassData[i] = event.values[i];
break;
case Sensor.TYPE_GYROSCOPE:
for (int i=0; i<3; i++)
gyroData[i] = event.values[i];
break;
}
}
// перевод массивов данных с сенсоров в строку
private String getValues(float[] sensorData){
String msg = String.format(
"X: %8.4f Y: %8.4f Z: %8.4f\n",
sensorData[0], sensorData[1], sensorData[2]);
return msg;
}
//получение времени (идет в месте с данными в базу)
private String updateDisplay() {
mHour = c.get(Calendar.HOUR);
mMinute = c.get(Calendar.MINUTE);
mSecond = c.get(Calendar.SECOND);
mlSecond = c.get(Calendar.MILLISECOND);
StringBuilder sb =
new StringBuilder()
.append(pad(mHour)).append(":")
.append(pad(mMinute)).append(":")
.append(pad(mSecond)).append(":")
.append(pad(mlSecond));
String time = sb.toString();
return time;
}
private static String pad(int c) {
if (c >= 10)
return String.valueOf(c);
else
return "0" + String.valueOf(c);
}
//Отправка данных в активити и в провайдер
public void writeData(String timeValue,String accelValue,String gyroValue,String compassValue ) {
Intent intent = new Intent(MainActivity.BROADCAST_ACTION);
intent.putExtra(MainActivity.VAL1, timeValue);
intent.putExtra(MainActivity.VAL2, accelValue);
intent.putExtra(MainActivity.VAL3, gyroValue);
intent.putExtra(MainActivity.VAL4, compassValue);
sendBroadcast(intent);
// Проблемное место!!!
/*
ContentValues cv = new ContentValues();
cv.put(DATA_TIME, timeValue);
cv.put(DATA_ACCEL, accelValue);
cv.put(DATA_GYRO, gyroValue);
cv.put(DATA_COMPASS, compassValue);
getContentResolver().insert(DATA_URI, cv);
*/
}
@Override
public void onSensorChanged(SensorEvent event) {
Log.d(LOG_TAG, "onSensorChanged");
loadSensorData (event);
timeValue = updateDisplay();
accelValue = getValues(accelData);
gyroValue = getValues(gyroData);
compassValue = getValues(compassData);
writeData(timeValue, accelValue, gyroValue, compassValue);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onDestroy() {
super.onDestroy();
mgr.unregisterListener(this);
Log.d(LOG_TAG, "onDestroy");
}
}Код: Выделить всё
public class IntProvider extends ContentProvider {
private class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DB_CREATE);
Log.d(LOG_TAG, "База создана!");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
final String LOG_TAG = "myLogs";
static final String DB_NAME = "mydb";
static final int DB_VERSION = 1;
static final String DATA_TABLE = "data";
static final String DATA_ID = "_id";
static final String DATA_TIME = "time";
static final String DATA_ACCEL = "accel";
static final String DATA_GYRO = "gyro";
static final String DATA_COMPASS = "compass";
static final String DB_CREATE = "create table " + DATA_TABLE + "(" +
DATA_ID + " integer primary key autoincrement, " +
DATA_TIME + " text, " +
DATA_ACCEL + " text, " +
DATA_GYRO + " text, " +
DATA_COMPASS + " text" + ");";
static final String AUTHORITY = "ru.sibnia.provider.IntProvider";
static final String DATA_PATH = "data";
public static final Uri DATA_CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + DATA_PATH);
static final String DATA_CONTENT_TYPE = "vnd.android.cursor.dir/vnd." + AUTHORITY + "." + DATA_PATH;
// одна строка
static final String DATA_CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd." + AUTHORITY + "." + DATA_PATH;
// // UriMatcher
// общий Uri
static final int URI_DATA = 1;
// Uri с указанным ID
static final int URI_DATA_ID = 2;
// описание и создание UriMatcher
private static final UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, DATA_PATH, URI_DATA);
uriMatcher.addURI(AUTHORITY, DATA_PATH + "/#", URI_DATA_ID);
}
DBHelper dbHelper;
SQLiteDatabase db;
@Override
public boolean onCreate() {
dbHelper = new DBHelper(getContext());
Log.d(LOG_TAG, "Провайдер открыт!");
return true;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
if (uriMatcher.match(uri) != URI_DATA)
throw new IllegalArgumentException("Wrong URI: " + uri);
db = dbHelper.getWritableDatabase();
long rowID = db.insert(DATA_TABLE, null, values);
Uri resultUri = ContentUris.withAppendedId(DATA_CONTENT_URI, rowID);
// уведомляем ContentResolver, что данные по адресу resultUri изменились
getContext().getContentResolver().notifyChange(resultUri, null);
Log.d(LOG_TAG, "Вставлена запись №: "+rowID);
return resultUri;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
switch (uriMatcher.match(uri)) {
case URI_DATA:
break;
case URI_DATA_ID:
String id = uri.getLastPathSegment();
Log.d(LOG_TAG, "URI_CONTACTS_ID, " + id);
if (TextUtils.isEmpty(selection)) {
selection = DATA_ID + " = " + id;
} else {
selection = selection + " AND " + DATA_ID + " = " + id;
}
break;
default:
throw new IllegalArgumentException("Wrong URI: " + uri);
}
db = dbHelper.getWritableDatabase();
int cnt = db.delete(DATA_TABLE, null, null);
getContext().getContentResolver().notifyChange(uri, null);
return cnt;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// проверяем Uri
switch (uriMatcher.match(uri)) {
case URI_DATA:
// если сортировка не указана, ставим свою - по имени
if (TextUtils.isEmpty(sortOrder)) {
sortOrder = DATA_TIME + " ASC";
}
break;
case URI_DATA_ID: // Uri с ID
String id = uri.getLastPathSegment();
Log.d(LOG_TAG, "URI_DATA_ID, " + id);
// добавляем ID к условию выборки
if (TextUtils.isEmpty(selection)) {
selection = DATA_ID + " = " + id;
} else {
selection = selection + " AND " + DATA_ID + " = " + id;
}
break;
default:
throw new IllegalArgumentException("Wrong URI: " + uri);
}
db = dbHelper.getWritableDatabase();
Cursor cursor = db.query(DATA_TABLE, projection, selection,
selectionArgs, null, null, sortOrder);
// просим ContentResolver уведомлять этот курсор
// об изменениях данных в CONTACT_CONTENT_URI
cursor.setNotificationUri(getContext().getContentResolver(),
DATA_CONTENT_URI);
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
Log.d(LOG_TAG, "update, " + uri.toString());
switch (uriMatcher.match(uri)) {
case URI_DATA:
Log.d(LOG_TAG, "URI_CONTACTS");
break;
case URI_DATA_ID:
String id = uri.getLastPathSegment();
Log.d(LOG_TAG, "URI_CONTACTS_ID, " + id);
if (TextUtils.isEmpty(selection)) {
selection = DATA_ID + " = " + id;
} else {
selection = selection + " AND " + DATA_ID + " = " + id;
}
break;
default:
throw new IllegalArgumentException("Wrong URI: " + uri);
}
db = dbHelper.getWritableDatabase();
int cnt = db.update(DATA_TABLE, values, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return cnt;
}
@Override
public String getType(Uri uri) {
Log.d(LOG_TAG, "getType, " + uri.toString());
switch (uriMatcher.match(uri)) {
case URI_DATA:
return DATA_CONTENT_TYPE;
case URI_DATA_ID:
return DATA_CONTENT_ITEM_TYPE;
}
return null;
}
}Код: Выделить всё
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ru.sibnia.develop.intentservice"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="ru.sibnia.develop.intentservice.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="IntService" >
</service>
<provider
android:name="IntProvider"
android:authorities="ru.sibnia.provider.IntProvider" >
</provider>
</application>
</manifest>