-
Notifications
You must be signed in to change notification settings - Fork 428
Description
I have an app that saves all its data in a TreeSet of PropertyBusinessObject. This data is saved to the Storage and it's restored from the Storage in the init(). Code:
public class StartPoint {
private Form current;
public static Resources theme;
public static TreeMap<Long, ItemProperty> itemsMap = new TreeMap<>();
public void init(Object context) {
[...]
Util.register("ItemProperty", ItemProperty.class);
TreeMap restoredData = restoreData();
if (restoredData != null) {
itemsMap = restoredData;
Log.p("Data restored");
}
}
public static void saveData() {
Storage.getInstance().writeObject("MyDiary", itemsMap);
Log.p("Data saved");
}
public TreeMap restoreData() {
HashMap map = (HashMap) Storage.getInstance().readObject("MyDiary");
if (map != null) {
return new TreeMap(map);
} else {
return null;
}
}
public class ItemProperty implements PropertyBusinessObject {
public final Property<String, ItemProperty> photo = new Property<>("photo");
public final LongProperty<ItemProperty> dateAndTime = new LongProperty<>("dateAndTime");
public final Property<String, ItemProperty> quantity = new Property<>("quantity");
public final Property<String, ItemProperty> place = new Property<>("place");
public final Property<String, ItemProperty> feeling = new Property<>("feeling");
public final Property<String, ItemProperty> fullness = new Property<>("fullness");
public final Property<String, ItemProperty> afterEating = new Property<>("afterEating");
public final Property<String, ItemProperty> other = new Property<>("other");
private final PropertyIndex idx = new PropertyIndex(this, "ItemProperty",
photo, dateAndTime, quantity, place, feeling, fullness,
afterEating, other);
@Override
public PropertyIndex getPropertyIndex() {
return idx;
}
public ItemProperty() {
this.getPropertyIndex().registerExternalizable();
Date currentTime = new Date();
dateAndTime.set(currentTime.getTime());
}
public String getLocalizedDate() {
Date date = new Date(dateAndTime.get());
return L10NManager.getInstance().formatDateLongStyle(date);
}
public String getLocalizedDateTime() {
Date date = new Date(dateAndTime.get());
return L10NManager.getInstance().formatDateTime(date);
}
public String getTime() {
Date date = new Date(dateAndTime.get());
Calendar myCalendar = Calendar.getInstance();
myCalendar.setTime(date);
String hour = Integer.toString(myCalendar.get(Calendar.HOUR_OF_DAY));
String minute = Integer.toString(myCalendar.get(Calendar.MINUTE));
if (minute.length() == 1) {
minute = "0" + minute;
}
return hour+":"+minute;
}
}
I have an iPhone specific problem (that doesn't happen on Android). When I update the app (installing a new build version), the photo of each ItemProperty is lost, while all the other data is correctly restored. Each photo was taken from the camera and then saved to the storage in this way:
// START OF IMAGE SECTION
Style s = new Style();
s.setFgColor(ColorUtil.GRAY);
s.setBgColor(ColorUtil.WHITE);
Label avatar = new Label(FontImage.createMaterial(FontImage.MATERIAL_ADD_A_PHOTO, s, imgSize / 3));
avatar.getUnselectedStyle().setPadding(0, 0, 0, 0);
avatar.getUnselectedStyle().setMargin(0, 0, 0, 0);
if (data.photo.get() != null && !data.photo.get().isEmpty()) {
try {
Image img = Image.createImage(FileSystemStorage.getInstance().openInputStream(data.photo.get()));
avatar.setIcon(img);
} catch (IOException ex) {
Log.p("ERROR: Cannot load the photo");
Log.e(ex);
}
}
ActionListener callback = e -> {
Log.p("ActionListener callback invoked");
if (e != null && e.getSource() != null) {
String filePath = (String) e.getSource();
// Resizes and Saves the image
String pathAvatar = FileSystemStorage.getInstance().getAppHomePath() + System.currentTimeMillis() + ".jpg";
try {
// About image orientation:
// https://stackoverflow.com/questions/51480978/codenameone-capture-photo-upside-down
OutputStream os2 = FileSystemStorage.getInstance().openOutputStream(pathAvatar);
Image img = Image.createImage(FileSystemStorage.getInstance().openInputStream(filePath));
if (img.getWidth() >= img.getHeight()) {
img = img.scaledWidth(Display.getInstance().convertToPixels(imgSize));
} else {
img = img.scaledHeight(Display.getInstance().convertToPixels(imgSize));
}
ImageIO.getImageIO().save(img, os2, ImageIO.FORMAT_JPEG, 0.9f);
os2.close();
// to open: Image img = Image.createImage(FileSystemStorage.getInstance().openInputStream(pathToImage));
data.photo.set(pathAvatar);
avatar.setIcon(img);
revalidate();
} catch (IOException ex) {
Log.p("ERROR: Cannot save the photo");
Log.e(ex);
}
}
};
Style colorIcons = new Style();
colorIcons.setFgColor(ColorUtil.LTGRAY);
Button camera = new Button("Photocamera", FontImage.createMaterial(FontImage.MATERIAL_CAMERA, colorIcons, 5));
camera.addActionListener((e) -> {
Capture.capturePhoto(callback);
});
Label photo = new Label("Photo");
photo.setAutoSizeMode(true);
add(FlowLayout.encloseCenter(photo));
Container imageAndButton = BoxLayout.encloseY(FlowLayout.encloseCenter(avatar), FlowLayout.encloseCenter(camera));
imageAndButton.setLeadComponent(camera);
add(imageAndButton);
// END OF IMAGE SECTION
The iPhone log doesn't contain any interesting data to understand this issue, except this:
[EDT] 0:2:57,28 - 2018-07-27 11:42:20.177 StartPoint[354:19370] [LOG] 0:0:0,0 - Codename One revisions: c67824ee4d9359c0891df93ad3d03e6c349b5a3f
2018-07-27 11:42:20.181 StartPoint[354:19370] Failed to create directory /var/mobile/Containers/Data/Application/D0F5692E-2B39-4333-8AF1-32B8F83A291E/Documents/cn1storage/
I logged also the data saved before and after the app update. They are identical, they are in this form:
The strange fact is that "ERROR: Cannot load the photo" is not logged (see the code above) and the photos taken before the app upgrade are replaced by the placeholder. All the new photo are correctly saved and shown (even if I kill and restard the app)... until the next app upgrade, after that they are lost.