当前位置: 首页 > 知识库问答 >
问题:

使用服务更新LiveData

裘嘉树
2023-03-14

在RoomDatabase中创建数据库时,一切工作都很好,并且数据已成功加载,但是,我需要更新服务中生成的数据,问题是它需要下一行中的活动上下文:LiveData >wifiViewModel=ViewModelProviders.of(this).get(wifiViewModel.class);

Dao接口:

@Dao
public interface WifiDao {

  @Insert(onConflict = OnConflictStrategy.IGNORE)
  void insert(WifiClass wifiObject);

  @Insert(onConflict = OnConflictStrategy.IGNORE)
  void insertAll(List<WifiClass> wifiList);

  @Query("DELETE FROM wifi_table")
  void deleteAll();

  @Query("SELECT * from wifi_table ORDER BY SSID ASC")
  LiveData<List<WifiClass>> getAllWifi();

  @Query("SELECT * from wifi_table LIMIT 1")
  WifiClass[] getAnyWifi();

}

存储库:

public class WifiRepository {

  private WifiDao wifiDao;
  private LiveData<List<WifiClass>> allWifi;

  WifiRepository(Application application) {
    WifiRoomDatabase db = WifiRoomDatabase.getDatabase(application);
    wifiDao = db.wifiDao();
    allWifi = wifiDao.getAllWifi();
  }

  // Get all Wifi objects
  LiveData<List<WifiClass>> getAllWifi() {
    return allWifi;
  }

  //Insert one Wifi object
  public void insert (WifiClass wifiObject){
    new insertAsyncTask(wifiDao).execute(wifiObject);
  }

  private static class insertAsyncTask extends AsyncTask<WifiClass, Void, Void> {

    private WifiDao mAsyncTaskDao;

    insertAsyncTask(WifiDao wifiDao) {
      mAsyncTaskDao = wifiDao;
    }

    @Override
    protected Void doInBackground(final WifiClass... params) {
      mAsyncTaskDao.insert(params[0]);
      return null;
    }
  }
}
@Database(entities = {WifiClass.class}, version = 1, exportSchema = false)
public abstract class WifiRoomDatabase extends RoomDatabase implements Serializable{

  public abstract WifiDao wifiDao();
  private static WifiRoomDatabase INSTANCE;
  public static Context context;

  static List<ScanResult> results;
  private static WifiManager wifiManager;

  public static WifiRoomDatabase getDatabase(final Context contextt) {
    context = contextt;
    if (INSTANCE == null) {
      synchronized (WifiRoomDatabase.class) {
        if (INSTANCE == null) {
          INSTANCE = Room.databaseBuilder(context.getApplicationContext(), WifiRoomDatabase.class, "wifi_database")
              .fallbackToDestructiveMigration() // Wipes and rebuilds
              .addCallback(sRoomDatabaseCallback) //
              .build();
        }
      }
    }
    return INSTANCE;
  }

  private static RoomDatabase.Callback sRoomDatabaseCallback = new RoomDatabase.Callback(){
    @Override
    public void onOpen (@NonNull SupportSQLiteDatabase db){
      super.onOpen(db);
      new PopulateDbAsync(INSTANCE).execute();

    }
  };


  //Populate the database in the background.
  private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {
    private final WifiDao mDao;

    PopulateDbAsync(WifiRoomDatabase db) {
      mDao = db.wifiDao();
    }

    @Override
    protected void onPreExecute() {
      super.onPreExecute();
      wifiManager = (WifiManager) context.getSystemService(WIFI_SERVICE);

      if (!wifiManager.isWifiEnabled()){
        //Toast.makeText(this, "Wifi disable... Activating...", Toast.LENGTH_SHORT).show();
        wifiManager.setWifiEnabled(true);
      }

        results = wifiManager.getScanResults();
        wifiManager.startScan();
        //Toast.makeText(this, "Scanning...", Toast.LENGTH_SHORT).show();
    }

    @Override
    protected Void doInBackground(Void... voids) {

      for (ScanResult scanResult : results) {
          String ssid = scanResult.SSID;
          if (ssid == null || ssid.isEmpty()){
            ssid = "Hide SSID";
          }
          String bssid = scanResult.BSSID;
          String capabilities = scanResult.capabilities;
          int level = scanResult.level;
          int frequency = scanResult.frequency;
          long timestamp = scanResult.timestamp;

        int passpoint; int channelWidth; int centerFreq0; int centerFreq1; int responder;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
          if (scanResult.isPasspointNetwork() == true) {
            passpoint = 1;
          }else{
            passpoint = 0;
          }
          channelWidth = scanResult.channelWidth;
          centerFreq0 = scanResult.centerFreq0;
          centerFreq1 = scanResult.centerFreq1;
          if (scanResult.is80211mcResponder() == true){
            responder = 1;
          }else{
            responder = 0;
          }
        }else{
          passpoint = 0;
          channelWidth = 0;
          centerFreq0 = 0;
          centerFreq1 = 0;
          responder = 0;

        }

          WifiClass wifiObject = new WifiClass(ssid, bssid, capabilities, level, frequency,
              timestamp, passpoint, channelWidth, centerFreq0, centerFreq1, responder);
          mDao.insert(wifiObject);
        }

      return null;
    }
  }
public class WifiViewModel extends AndroidViewModel {

  private WifiRepository wifiRepository;
  private LiveData<List<WifiClass>> allWifi;

  public WifiViewModel(@NonNull Application application) {
    super(application);
    wifiRepository = new WifiRepository(application);
    allWifi = wifiRepository.getAllWifi();
  }

  LiveData<List<WifiClass>> getAllWifi() {
    return allWifi;
  }

  public void insert(WifiClass wifiObject) {
    wifiRepository.insert(wifiObject);
  }

}

服务:

public class Wifi_Service extends IntentService {

  private Handler handler;
  private Runnable runnable;
  private static Context classContext;

  //private static WifiViewModel wifiViewModel;
  static List<ScanResult> results;
  private static WifiManager wifiManager;
  private LiveData<List<WifiClass>> mAllWifi;


  public Wifi_Service(/*WifiRoomDatabase db*/) {
    super("wifi_service");
  }

  @Override
  protected void onHandleIntent(Intent intent) {

  }

  //Populate the database in the background.
  private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {
    private final WifiDao mDao;

    PopulateDbAsync(WifiRoomDatabase db) {
      mDao = db.wifiDao();
    }

    @Override
    protected void onPreExecute() {
      super.onPreExecute();
      wifiManager = (WifiManager) classContext.getApplicationContext().getSystemService(WIFI_SERVICE);

      if (!wifiManager.isWifiEnabled()){
        Toast.makeText(classContext, "Wifi disable... Activating...", Toast.LENGTH_SHORT).show();
        wifiManager.setWifiEnabled(true);
      }

      results = wifiManager.getScanResults();
      wifiManager.startScan();
      Toast.makeText(classContext, "Scanning...", Toast.LENGTH_SHORT).show();
    }

    @Override
    protected Void doInBackground(Void... voids) {

      for (ScanResult scanResult : results) {
        String ssid = scanResult.SSID;
        if (ssid == null || ssid.isEmpty()){
          ssid = "Hide SSID";
        }
        String bssid = scanResult.BSSID;
        String capabilities = scanResult.capabilities;
        int level = scanResult.level;
        int frequency = scanResult.frequency;
        long timestamp = scanResult.timestamp;

        int passpoint; int channelWidth; int centerFreq0; int centerFreq1; int responder;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
          if (scanResult.isPasspointNetwork() == true) {
            passpoint = 1;
          }else{
            passpoint = 0;
          }
          channelWidth = scanResult.channelWidth;
          centerFreq0 = scanResult.centerFreq0;
          centerFreq1 = scanResult.centerFreq1;
          if (scanResult.is80211mcResponder() == true){
            responder = 1;
          }else{
            responder = 0;
          }
        }else{
          passpoint = 0;
          channelWidth = 0;
          centerFreq0 = 0;
          centerFreq1 = 0;
          responder = 0;

        }

        WifiClass wifiObject = new WifiClass(ssid, bssid, capabilities, level, frequency,
            timestamp, passpoint, channelWidth, centerFreq0, centerFreq1, responder);

      //The problem
        wifiViewModel.insert(wifiObject);
      }

      return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
      super.onPostExecute(aVoid);
      Toast.makeText(classContext, "Scanning finished", Toast.LENGTH_SHORT).show();

    }
  }

  @Override
  public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(this, "Scanning...", Toast.LENGTH_SHORT).show();

    Bundle extras = intent.getExtras();
    if(extras == null) {
      Log.d("Service", "null");
    }else {
      Log.d("Service","not null");
      classContext = getApplicationContext();
    }

//The problem
//   wifiViewModel = ViewModelProviders.of(this).get(WifiViewModel.class);
//    mWifiViewModel.getAllWifi().observe(this, new Observer<List<WifiClass>>() {
//      @Override
//      public void onChanged(@Nullable List<WifiClass> wifiClasses) {
//
//      }
//    });


    return super.onStartCommand(intent, flags, startId);
  }

  @Override
  public void onDestroy() {
    Toast.makeText(this, "Destroy scanning service", Toast.LENGTH_SHORT).show();

    super.onDestroy();
  }
}

我希望服务在LiveData列表中执行、保存和刷新新结果,但我不能声明LiveData列表。

共有1个答案

韦繁
2023-03-14

由于我无法调用和使用LiveData列表,因为我需要传递应用程序上下文,而Android不接受它,CommonsWare和The_Martian建议我改用存储库。

由于我的存储库调用了room数据库,所以我调用了room类中生成的数据库,并从那里调用了dao接口和方法INSERT。

代码:

WifiRoomDatabase db = WifiRoomDatabase.getDatabase(getApplicationContext());
db.wifiDao().insert(wifiObject);
 类似资料:
  • 如果用户第一次安装我的应用程序,我如何构建我的Inno安装脚本以自动注册dll,但如果有一个以前的版本,则取消注册,然后注册新版本(假设界面不同)? 我目前在我的文件部分使用regserver和忽略reversion标志,如下所示: 在我的谷歌搜索中,我找到了Un注册表服务器,但我不知道如何将其添加到我的脚本中。我很乐意开始修补以了解它是如何工作的,但我不想做任何会弄乱我的注册表的事情。 这里有一

  • 需要更新时钟小部件的TextView每秒或每分钟变化。 我正在从AppWidgetProvider的onReceive调用服务: 我应该做什么来检查更新的时间,如果有,然后更新‘时间’文本视图… 任何一种都是非常非常非常感谢的

  • 我的Kubernetes集群运行在谷歌云下。我有部署运行端口443和LoadBalancer公开它到互联网。 我是这样创建的: 运行此命令后,loadbalancer将指向部署。现在,我创建了,并希望更改loadbalancer以指向新的部署()。 注意:删除和重新创建部署是释放外部IP地址,我想避免它。 如何在不丢失外部IP的情况下修补现有服务以指向另一个部署?

  • 我一直在阅读《html5rocks服务工作者简介》一文,并创建了一个基本的服务工作者,它可以缓存页面、JS和CSS,并按预期工作: 当我对CSS进行更改时,由于服务人员正在从缓存中正确返回CSS,因此不会拾取此更改。 我陷入困境的地方是,如果我要更改HTML、JS或CSS,我如何确保服务人员可以从服务器加载较新版本,而不是从缓存加载?我曾尝试在CSS导入上使用版本戳,但似乎不起作用。

  • 问题内容: 我正在创建一个ajax搜索页面,该页面将由搜索输入框,一系列过滤器下拉列表以及随后显示结果的UL组成。 由于搜索的过滤器部分将在页面上的单独位置,因此我认为创建一个服务来协调输入和搜索服务器端的Ajax请求是一个好主意。然后可以通过几个单独的控制器来调用(一个用于搜索框和结果,另一个用于过滤器)。 我一直在努力的主要事情是在调用ajax时获得刷新结果。如果我将ajax直接放在Searc

  • 我想使用最新的融合位置提供商客户端在“后台服务”上获取位置更新。我不想使用所有人都在使用的位置侦听器和Google API客户端。我还需要使用google play服务提供的位置设置Api来检查该“后台服务”上的位置设置是禁用还是启用。请帮忙。