Skip to content

Commit 1664c1f

Browse files
committed
Refactor AppRepository access
1 parent 794f0de commit 1664c1f

File tree

11 files changed

+237
-187
lines changed

11 files changed

+237
-187
lines changed

app/src/main/java/ru/playsoftware/j2meloader/MainActivity.java

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/*
22
* Copyright 2015-2016 Nickolay Savchenko
3-
* Copyright 2017-2018 Nikita Shakarun
3+
* Copyright 2017-2020 Nikita Shakarun
4+
* Copyright 2020-2024 Yury Kharchenko
45
*
56
* Licensed under the Apache License, Version 2.0 (the "License");
67
* you may not use this file except in compliance with the License.
@@ -17,17 +18,22 @@
1718

1819
package ru.playsoftware.j2meloader;
1920

21+
import android.content.ClipData;
22+
import android.content.ClipboardManager;
23+
import android.content.Context;
2024
import android.content.Intent;
2125
import android.content.SharedPreferences;
2226
import android.media.AudioManager;
2327
import android.net.Uri;
2428
import android.os.Bundle;
2529
import android.view.ViewConfiguration;
30+
import android.widget.Toast;
2631

2732
import androidx.activity.result.ActivityResultLauncher;
2833
import androidx.annotation.Nullable;
2934
import androidx.appcompat.app.AlertDialog;
3035
import androidx.appcompat.app.AppCompatActivity;
36+
import androidx.core.content.ContextCompat;
3137
import androidx.lifecycle.ViewModelProvider;
3238
import androidx.preference.PreferenceManager;
3339

@@ -38,6 +44,7 @@
3844
import ru.playsoftware.j2meloader.config.Config;
3945
import ru.playsoftware.j2meloader.util.Constants;
4046
import ru.playsoftware.j2meloader.util.FileUtils;
47+
import ru.playsoftware.j2meloader.util.LogUtils;
4148
import ru.playsoftware.j2meloader.util.PickDirResultContract;
4249
import ru.playsoftware.j2meloader.util.StoragePermissionHelper;
4350
import ru.woesss.j2me.installer.InstallerDialog;
@@ -60,6 +67,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
6067
setContentView(R.layout.activity_main);
6168
storagePermissionHelper.launch(this);
6269
appListModel = new ViewModelProvider(this).get(AppListModel.class);
70+
appListModel.getErrors().observe(this, this::alertDbError);
6371
if (savedInstanceState == null) {
6472
Intent intent = getIntent();
6573
Uri uri = null;
@@ -83,7 +91,7 @@ private void checkAndCreateDirs() {
8391
File dir = new File(emulatorDir);
8492
if (dir.isDirectory() && dir.canWrite()) {
8593
FileUtils.initWorkDir(dir);
86-
appListModel.onWorkDirReady();
94+
appListModel.setEmulatorDirectory(emulatorDir);
8795
return;
8896
}
8997
if (dir.exists() || dir.getParentFile() == null || !dir.getParentFile().isDirectory()
@@ -119,7 +127,7 @@ void onPermissionResult(boolean granted) {
119127
}
120128

121129
private void onPickDirResult(Uri uri) {
122-
if (uri == null) {
130+
if (uri == null || uri.getPath() == null) {
123131
checkAndCreateDirs();
124132
return;
125133
}
@@ -129,14 +137,13 @@ private void onPickDirResult(Uri uri) {
129137

130138
private void alertCreateDir() {
131139
String emulatorDir = Config.getEmulatorDir();
132-
String lblChange = getString(R.string.change);
133140
String msg = getString(R.string.alert_msg_workdir_not_exists, emulatorDir);
134141
new AlertDialog.Builder(this)
135142
.setTitle(android.R.string.dialog_alert_title)
136143
.setCancelable(false)
137144
.setMessage(msg)
138145
.setPositiveButton(R.string.create, (d, w) -> applyWorkDir(new File(emulatorDir)))
139-
.setNeutralButton(lblChange, (d, w) -> openDirLauncher.launch(emulatorDir))
146+
.setNeutralButton(R.string.change, (d, w) -> openDirLauncher.launch(emulatorDir))
140147
.setNegativeButton(R.string.exit, (d, w) -> finish())
141148
.show();
142149
}
@@ -158,4 +165,22 @@ protected void onNewIntent(Intent intent) {
158165
InstallerDialog.newInstance(uri).show(getSupportFragmentManager(), "installer");
159166
}
160167
}
168+
169+
private void alertDbError(Throwable throwable) {
170+
AlertDialog.Builder builder = new AlertDialog.Builder(this)
171+
.setTitle(R.string.error)
172+
.setMessage(LogUtils.getPrettyText(throwable))
173+
.setPositiveButton(android.R.string.ok, null);
174+
ClipboardManager cm = ContextCompat.getSystemService(this, ClipboardManager.class);
175+
if (cm != null) {
176+
builder.setNeutralButton(android.R.string.copy, (d, w) -> {
177+
Context context = ((AlertDialog) d).getContext();
178+
cm.setPrimaryClip(new ClipData(context.getString(R.string.app_name) + " stacktrace",
179+
new String[]{"text/plain"},
180+
new ClipData.Item(LogUtils.getStackTraceString(throwable))));
181+
Toast.makeText(context, R.string.msg_text_copied_to_clipboard, Toast.LENGTH_SHORT).show();
182+
});
183+
}
184+
builder.show();
185+
}
161186
}

app/src/main/java/ru/playsoftware/j2meloader/applist/AppListModel.java

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2021-2023 Yury Kharchenko
2+
* Copyright 2021-2024 Yury Kharchenko
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,23 +16,77 @@
1616

1717
package ru.playsoftware.j2meloader.applist;
1818

19+
import static ru.playsoftware.j2meloader.util.Constants.PREF_APP_SORT;
20+
import static ru.playsoftware.j2meloader.util.Constants.PREF_EMULATOR_DIR;
21+
22+
import android.content.SharedPreferences;
23+
24+
import androidx.lifecycle.MutableLiveData;
1925
import androidx.lifecycle.ViewModel;
26+
import androidx.preference.PreferenceManager;
27+
28+
import java.util.List;
2029

30+
import ru.playsoftware.j2meloader.EmulatorApplication;
2131
import ru.playsoftware.j2meloader.appsdb.AppRepository;
32+
import ru.playsoftware.j2meloader.config.Config;
2233

23-
public class AppListModel extends ViewModel {
24-
private final AppRepository appRepository = new AppRepository(this);
34+
public class AppListModel extends ViewModel implements SharedPreferences.OnSharedPreferenceChangeListener {
35+
private final AppRepository appRepository = new AppRepository();
2536

26-
public AppRepository getAppRepository() {
27-
return appRepository;
37+
public AppListModel() {
38+
PreferenceManager.getDefaultSharedPreferences(EmulatorApplication.getInstance())
39+
.registerOnSharedPreferenceChangeListener(this);
2840
}
2941

3042
@Override
3143
protected void onCleared() {
44+
PreferenceManager.getDefaultSharedPreferences(EmulatorApplication.getInstance())
45+
.unregisterOnSharedPreferenceChangeListener(this);
3246
appRepository.close();
3347
}
3448

35-
public void onWorkDirReady() {
36-
appRepository.onWorkDirReady();
49+
public void setEmulatorDirectory(String emulatorDir) {
50+
appRepository.setDatabaseFile(emulatorDir + Config.APPS_DB_NAME);
51+
}
52+
53+
MutableLiveData<List<AppItem>> getAppList() {
54+
return appRepository.getAppList();
55+
}
56+
57+
public MutableLiveData<Throwable> getErrors() {
58+
return appRepository.getErrors();
59+
}
60+
61+
void updateApp(AppItem item) {
62+
appRepository.update(item);
63+
}
64+
65+
void deleteApp(AppItem item) {
66+
appRepository.delete(item);
67+
}
68+
69+
public AppItem getApp(int id) {
70+
return appRepository.get(id);
71+
}
72+
73+
public void addApp(AppItem app) {
74+
appRepository.insert(app);
75+
}
76+
77+
public AppItem getApp(String name, String vendor) {
78+
return appRepository.get(name, vendor);
79+
}
80+
81+
@Override
82+
public void onSharedPreferenceChanged(SharedPreferences sp, String key) {
83+
if (PREF_APP_SORT.equals(key)) {
84+
appRepository.setSort(sp.getInt(PREF_APP_SORT, 0));
85+
} else if (PREF_EMULATOR_DIR.equals(key)) {
86+
String path = sp.getString(key, null);
87+
if (path != null) {
88+
appRepository.setDatabaseFile(path + Config.APPS_DB_NAME);
89+
}
90+
}
3791
}
3892
}

app/src/main/java/ru/playsoftware/j2meloader/applist/AppsListFragment.java

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,10 @@
2828
import android.content.Context;
2929
import android.content.Intent;
3030
import android.content.SharedPreferences;
31-
import android.database.sqlite.SQLiteDiskIOException;
3231
import android.graphics.drawable.Drawable;
3332
import android.net.Uri;
3433
import android.os.Bundle;
3534
import android.os.Environment;
36-
import android.util.Log;
3735
import android.view.ContextMenu;
3836
import android.view.LayoutInflater;
3937
import android.view.Menu;
@@ -78,7 +76,6 @@
7876
import io.reactivex.android.schedulers.AndroidSchedulers;
7977
import io.reactivex.disposables.Disposable;
8078
import ru.playsoftware.j2meloader.R;
81-
import ru.playsoftware.j2meloader.appsdb.AppRepository;
8279
import ru.playsoftware.j2meloader.config.Config;
8380
import ru.playsoftware.j2meloader.config.ProfilesActivity;
8481
import ru.playsoftware.j2meloader.databinding.DialogInputBinding;
@@ -93,7 +90,6 @@
9390
import ru.woesss.j2me.installer.InstallerDialog;
9491

9592
public class AppsListFragment extends Fragment implements MenuProvider {
96-
private static final String TAG = AppsListFragment.class.getSimpleName();
9793

9894
private final ActivityResultLauncher<Void> openFileLauncher = registerForActivityResult(
9995
new ActivityResultContract<Void, Uri>() {
@@ -128,7 +124,7 @@ public Uri parseResult(int resultCode, @Nullable Intent intent) {
128124
private final AppsListAdapter adapter = new AppsListAdapter(this);
129125
private Uri appUri;
130126
private SharedPreferences preferences;
131-
private AppRepository appRepository;
127+
private AppListModel appListViewModel;
132128
private Disposable searchViewDisposable;
133129
private GridLayoutManager layoutManager;
134130
private FragmentAppslistBinding binding;
@@ -150,10 +146,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
150146
args.remove(KEY_APP_URI);
151147
FragmentActivity activity = requireActivity();
152148
preferences = PreferenceManager.getDefaultSharedPreferences(activity);
153-
AppListModel appListModel = new ViewModelProvider(activity).get(AppListModel.class);
154-
appRepository = appListModel.getAppRepository();
155-
appRepository.observeErrors(this, this::alertDbError);
156-
appRepository.observeApps(this, this::onDbUpdated);
149+
appListViewModel = new ViewModelProvider(activity).get(AppListModel.class);
157150
}
158151

159152

@@ -188,6 +181,7 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
188181
binding.list.setLayoutManager(layoutManager);
189182
binding.list.setAdapter(adapter);
190183
binding.fab.setOnClickListener(v -> openFileLauncher.launch(null));
184+
appListViewModel.getAppList().observe(getViewLifecycleOwner(), this::onDbUpdated);
191185
}
192186

193187
@Override
@@ -198,20 +192,6 @@ public void onDestroy() {
198192
super.onDestroy();
199193
}
200194

201-
private void alertDbError(Throwable throwable) {
202-
Activity activity = getActivity();
203-
if (activity == null) {
204-
Log.e(TAG, "Db error detected", throwable);
205-
return;
206-
}
207-
if (throwable instanceof SQLiteDiskIOException) {
208-
Toast.makeText(activity, R.string.error_disk_io, Toast.LENGTH_SHORT).show();
209-
} else {
210-
String msg = activity.getString(R.string.error) + ": " + throwable.getMessage();
211-
Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show();
212-
}
213-
}
214-
215195
private void alertRename(AppItem item) {
216196
TextInputLayout layout = DialogInputBinding.inflate(getLayoutInflater()).getRoot();
217197
EditText editText = Objects.requireNonNull(layout.getEditText());
@@ -225,7 +205,7 @@ private void alertRename(AppItem item) {
225205
Toast.makeText(getActivity(), R.string.error, Toast.LENGTH_SHORT).show();
226206
} else {
227207
item.setTitle(title);
228-
appRepository.update(item);
208+
appListViewModel.updateApp(item);
229209
}
230210
})
231211
.setNegativeButton(android.R.string.cancel, null);
@@ -236,10 +216,8 @@ private void alertDelete(AppItem item) {
236216
AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity())
237217
.setTitle(android.R.string.dialog_alert_title)
238218
.setMessage(R.string.message_delete)
239-
.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
240-
AppUtils.deleteApp(item);
241-
appRepository.delete(item);
242-
})
219+
.setPositiveButton(android.R.string.ok, (dialogInterface, i) ->
220+
appListViewModel.deleteApp(item))
243221
.setNegativeButton(android.R.string.cancel, null);
244222
builder.show();
245223
}

0 commit comments

Comments
 (0)