- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试实现一个应用程序,该应用程序每 15 秒更新一次用户位置,将数据存储到数据库并将其显示到我的 Activity 中的 ListView 。即使 Activity 销毁,位置也应该始终更新,为此我创建了 LocationService 类。
问题是我能够获取更新,也能够存储到数据库中,但我无法在运行时在 ListView 中显示这些更新,这意味着我希望列表应该每 15 秒刷新一次并将其显示给 UI。此外,当我从数据库获取详细信息时,我无法获取最新的详细信息,而是每次都会获取整个数组列表,这会影响我的 Activity 响应。我希望仅从数据库中获取新添加的数据,以便加载所需的时间更少,但我想每次都显示要列出的所有数据。
我已经实现了一个线程(注释代码),它获取数据并显示到 ListView ,但这不是更新 UI 的正确方法。请建议我一种方法,以便我可以在将新数据添加到数据库时刷新我的列表
这是我的 Activity
public class MainActivity extends Activity {
List<MyLocation> locationList = new ArrayList();
ListView mList;
LocationAdapter adapter;
BroadcastReceiver receiver;
LocationService mService;
boolean mBound = false;
private DbHelper dbHelper;
private Button updateLocation;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
LocationService.LocalBinder binder = (LocationService.LocalBinder) service;
mService = binder.getService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
updateLocation = (Button) findViewById(R.id.update_location);
mList = (ListView) findViewById(R.id.listView);
dbHelper = new DbHelper(this);
updateLocation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
locationList = mService.displayLocation();
adapter = new LocationAdapter(MainActivity.this, locationList);
mList.setAdapter(adapter);
}
});
/*
Thread mThread = new Thread() {
@Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(500);
runOnUiThread(new Runnable() {
@Override
public void run() {
locationList = dbHelper.getLocationDetails();
Collections.reverse(locationList);
adapter = new LocationAdapter(MainActivity.this, locationList);
mList.setAdapter(adapter);
}
});
}
} catch (InterruptedException e) {
}
}
};
mThread.start();*/
}
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, LocationService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
}
位置服务
public class LocationService extends Service implements LocationListener, GoogleApiClient.ConnectionCallbacks {
private final IBinder mBinder = new LocalBinder();
ArrayList<MyLocation> locationList = new ArrayList<>();
private DbHelper dbHelper;
private Location mLocation;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private String TAG = "Service";
@Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
@Override
public void onCreate() {
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addApi(LocationServices.API).build();
mGoogleApiClient.connect();
dbHelper = new DbHelper(this);
createLocationRequest();
displayLocation();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "service destroy");
}
public List<MyLocation> displayLocation() {
mLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
if (mLocation != null) {
double latitude = mLocation.getLatitude();
double longitude = mLocation.getLongitude();
String lastUpdateTime = DateFormat.getTimeInstance().format(new Date());
dbHelper.insertLocationDetails(longitude, latitude, lastUpdateTime);
locationList = dbHelper.getLocationDetails();
return locationList;
} else {
return null;
}
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Log.d(TAG, "Connected to update");
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
public void onLocationChanged(Location location) {
mLocation = location;
Toast.makeText(getApplicationContext(), "Location changed",
Toast.LENGTH_SHORT).show();
displayLocation();
}
public void onConnected(Bundle arg0) {
startLocationUpdates();
}
@Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
}
public class LocalBinder extends Binder {
public LocationService getService() {
return LocationService.this;
}
}
}
数据库帮助程序
public class DbHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String LONGITUDE = "longitude";
private static final String LATITUDE = "latitude";
private static final String LOCATION_CHANGE_TIME = "location_change_time";
private static final String LOCATION_DETAIL_TABLE = "location_detail_table";
private static final String CREATE_TABLE_LOCATION = "CREATE TABLE "
+ LOCATION_DETAIL_TABLE + " (" + LONGITUDE + " TEXT,"
+ LOCATION_CHANGE_TIME + " TEXT,"
+ LATITUDE + " TEXT)";
public static String DATABASE_NAME = "Location_database";
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase database) {
database.execSQL(CREATE_TABLE_LOCATION);
}
public void insertLocationDetails(double longitude, double latitude, String time) {
SQLiteDatabase database = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(LONGITUDE, longitude);
values.put(LATITUDE, latitude);
values.put(LOCATION_CHANGE_TIME, time);
long id= database.insert(LOCATION_DETAIL_TABLE, null, values);
System.out.println("Newly added item id "+id);
database.close();
}
public ArrayList<MyLocation> getLocationDetails() {
ArrayList<MyLocation> locationList = new ArrayList();
String selectQuery = "SELECT * FROM " + LOCATION_DETAIL_TABLE;
SQLiteDatabase database = this.getReadableDatabase();
Cursor cursor = database.rawQuery(selectQuery, null);
if (cursor.moveToNext()) {
do {
MyLocation location = new MyLocation();
String longitude = cursor.getString(cursor
.getColumnIndexOrThrow(LONGITUDE));
String latitude = cursor.getString(cursor.getColumnIndexOrThrow(LATITUDE));
String time = cursor.getString(cursor
.getColumnIndexOrThrow(LOCATION_CHANGE_TIME));
location.setLatitude(latitude);
location.setLongitude(longitude);
location.setLastUpdatedTime(time);
locationList.add(location);
} while (cursor.moveToNext());
}
if (cursor != null) {
cursor.close();
}
database.close();
return locationList;
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
最佳答案
就您而言,您可以使用 ContentProvider 并在 activity 中实现 LoaderManager.LoaderCallbacks。
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
db = dbHelper.getWritableDatabase();
String table = uri.getLastPathSegment();
long rowID = db.insert(table, null, values);
Uri CONTENT_URI = Uri.parse("content://"
+ AUTHORITY + "/" + table);
Uri resultUri = ContentUris.withAppendedId(CONTENT_URI, rowID);
getContext().getContentResolver().notifyChange(resultUri, null);
return resultUri;
}
行
getContext().getContentResolver().notifyChange(resultUri, null);
在ContentProvider中会导致重新查询数据。在 Activity 中使用 SimpleAdapter 将更新您的 UI。
关于java - 服务和 Activity 通信...从服务接收到数据时更新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35177443/
我对 Android 很陌生,如果问题重复,请避免并发送链接。有三个 Activity A、B 和 C。 Activity A 获取一个用户名,我想在 Activity C 中显示该用户名,但我想先运
我正在尝试制作记事本应用程序,因此每次打开新笔记时,布局都会相同。另外, Activity 的数量(新注释)不应定义得尽可能多 最佳答案 如果 Activity 始终相同,您可能应该创建一个适配器,允
我有 3 个 Activity 。 主窗口 5 个按钮 在按钮的主窗口中按下此窗口打开(将其称为父窗口) 在父窗口按钮上按下此窗口打开调用它作为结束子窗口。 现在从子窗口我从父窗口获取值如下:
我遇到了一个 Activity backstack 问题。假设我的后台有 5 个 Activity :比如 Activity A、 Activity B、 Activity C、 Activity D
我正在寻找必须具有以下附加特征的 JMS 提供程序: 采用多代理,所有代理都必须处于事件状态(无单点故障) 仅在两台机器上进行扩展就足以满足我们的需求 能够保证订购(如果 1 个生产者 + 1 个消费
假设,我有一个由 TabHost 组成的选项卡 Activity 。 TabHost 包含 2 个选项卡,每两个选项卡都有一个 Activity 组。每个 Activity 组包含一项 Activit
我正在开发一个应用程序,我需要根据某些操作导航到特定 Activity 。这是一张图片 我的第一个 Activity 是 ReadingActivity。基于某些操作,用户将被带到 NewProjec
我创建了一个与服务器异步通信的应用程序。当应用程序发出服务器请求时,将创建一个带有“正在加载”通知的新对话框( Activity )。主要 Activity 实现了处理服务器响应的方法,我想在主要 A
我想在我的所有应用程序 Activity 中显示相同的选项菜单。我创建了一个实现菜单的通用 Activity ,并且我所有的进一步 Activity 都扩展了它。 问题:当我需要扩展其他特定 Acti
我有四个 Activity ,即 java 文件 - Activity1.java、activity2.java、activity3.java、activity4.java 和 xml 文件 - Ac
我有两个 Activity 。我想将数据从第二个 Activity 发送到上一个 Activity 。第一个 Activity 有自定义 ListView 和 bean 类。当我点击第二个 Activ
根 Activity 是堆栈中当前的第一个 Activity 还是 list 中指定为启动 Activity 的 Activity ? 支持应用程序 P 在启动时启动 Activity A。然后 A
你好 我想知道您在绘制 Activity 图选择“Activity ”时考虑了哪些关键点? 您如何从要建模的问题中选择 Activity ? 谢谢 最佳答案 Activity 图用于对正在开发的系统和
如何从主 Activity 启动 Activity 并在子 Activity 返回主 Activity 中退出操作后返回主 Activity ? 我已将子 Activity 作为启动器 Intent
我的工作流程如下: 登录 Activity -> ActivityB -> ActivityC -> ActivityD 我想将数据从LoginActivity传递到ActivityD,但不直接传递到
我之前曾尝试获得此问题的答案,但找不到可以解决我的问题的答案。我正在制作保存圆盘高尔夫球分数的应用程序。我的 MainActivity 有 4 个按钮。新比赛、恢复比赛、类(class)和球员。 At
我有一个 tts 非 UI 类和 Activity 类。现在在 Activity 类中,我有一个按钮,用户可以从中选择男声或女声,具体取决于我想要将字符串传递给 tts 类的选择,然后一次tts 类根
问题有点复杂,首先, Activity A 和 Activity B 的 list 中都有 android:noHistory = true 。我有一个自定义 serialized 类,假设 MyCl
在我的应用程序中,我有两个 Activity (AuthenticationActivity 和 MainActivity),每个 Activity 都有一个导航图和大量 fragment 。我创建了
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: How can i use compose email activity in tabView? 我想在选项
我是一名优秀的程序员,十分优秀!