Version 2.3

This commit is contained in:
dgis 2021-10-19 18:25:34 +02:00
parent 009ecbccf5
commit 1b26b74f48
9 changed files with 144 additions and 80 deletions

View file

@ -17,7 +17,7 @@ QUICK START
1. From the left side, slide your finger to open the menu. 1. From the left side, slide your finger to open the menu.
2. Touch the "New..." menu item. 2. Touch the "New..." menu item.
3. Select a predefined faceplate (or select a custom KML script folder with Android >= 5.0). 3. Select a default calculator (or with Android >= 5.0, "[Select a Custom KML script folder...]" where you have copied the KML scripts and ROM files (Android 11 cannot use the folder Download)).
4. And the calculator should now be opened. 4. And the calculator should now be opened.
@ -58,7 +58,7 @@ LINKS
CHANGES CHANGES
Version 2.3 (2021-09-xx) Version 2.3 (2021-10-19)
- Add an experimental serial port support (via USB OTG). - Add an experimental serial port support (via USB OTG).
- Show KML log on request. - Show KML log on request.
@ -66,6 +66,9 @@ Version 2.3 (2021-09-xx)
- Update the embedded help file "Emu48.html" to the latest version. - Update the embedded help file "Emu48.html" to the latest version.
- Open an external web browser when you click an external links in the Help. - Open an external web browser when you click an external links in the Help.
- Add Real blue 50g faceplate based on my calculator and on the KML script from Eric Rechlin. - Add Real blue 50g faceplate based on my calculator and on the KML script from Eric Rechlin.
- Display the graphic tab of the printer without antialiasing.
- Fix a crash about the Most Recently Used state files.
- Fix an issue with "Copy Screen".
Version 2.2 (2020-12-09) Version 2.2 (2020-12-09)

View file

@ -33,8 +33,8 @@ android {
applicationId "org.emulator.forty.eight" applicationId "org.emulator.forty.eight"
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 30 targetSdkVersion 30
versionCode 20 versionCode 22
versionName "2.2" versionName "2.3"
setProperty("archivesBaseName", "Emu48-v$versionName") setProperty("archivesBaseName", "Emu48-v$versionName")
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild { externalNativeBuild {

View file

@ -17,7 +17,7 @@ QUICK START
1. From the left side, slide your finger to open the menu. 1. From the left side, slide your finger to open the menu.
2. Touch the "New..." menu item. 2. Touch the "New..." menu item.
3. Select a predefined faceplate (or select a custom KML script folder with Android >= 5.0). 3. Select a default calculator (or with Android >= 5.0, "[Select a Custom KML script folder...]" where you have copied the KML scripts and ROM files (Android 11 cannot use the folder Download)).
4. And the calculator should now be opened. 4. And the calculator should now be opened.
@ -58,7 +58,7 @@ LINKS
CHANGES CHANGES
Version 2.3 (2021-09-xx) Version 2.3 (2021-10-19)
- Add an experimental serial port support (via USB OTG). - Add an experimental serial port support (via USB OTG).
- Show KML log on request. - Show KML log on request.
@ -66,6 +66,9 @@ Version 2.3 (2021-09-xx)
- Update the embedded help file "Emu48.html" to the latest version. - Update the embedded help file "Emu48.html" to the latest version.
- Open an external web browser when you click an external links in the Help. - Open an external web browser when you click an external links in the Help.
- Add Real blue 50g faceplate based on my calculator and on the KML script from Eric Rechlin. - Add Real blue 50g faceplate based on my calculator and on the KML script from Eric Rechlin.
- Display the graphic tab of the printer without antialiasing.
- Fix a crash about the Most Recently Used state files.
- Fix an issue with "Copy Screen".
Version 2.2 (2020-12-09) Version 2.2 (2020-12-09)

View file

@ -28,6 +28,7 @@ extern AAssetManager * assetManager;
static jobject mainActivity = NULL; static jobject mainActivity = NULL;
jobject bitmapMainScreen = NULL; jobject bitmapMainScreen = NULL;
AndroidBitmapInfo androidBitmapInfo; AndroidBitmapInfo androidBitmapInfo;
//RECT mainViewRectangleToUpdate = { 0, 0, 0, 0 };
enum DialogBoxMode currentDialogBoxMode; enum DialogBoxMode currentDialogBoxMode;
LPBYTE pbyRomBackup = NULL; LPBYTE pbyRomBackup = NULL;
enum ChooseKmlMode chooseCurrentKmlMode; enum ChooseKmlMode chooseCurrentKmlMode;
@ -106,7 +107,19 @@ int mainViewCallback(int type, int param1, int param2, const TCHAR * param3, con
} }
void mainViewUpdateCallback() { void mainViewUpdateCallback() {
mainViewCallback(CALLBACK_TYPE_INVALIDATE, 0, 0, NULL, NULL); // if(!IsRectEmpty(&mainViewRectangleToUpdate)) {
// int param1 = ((mainViewRectangleToUpdate.left & 0xFFFF) << 16) | (mainViewRectangleToUpdate.top & 0xFFFF);
// int param2 = ((mainViewRectangleToUpdate.right & 0xFFFF) << 16) | (mainViewRectangleToUpdate.bottom & 0xFFFF);
// mainViewCallback(CALLBACK_TYPE_INVALIDATE,
// param1,
// param2,
// NULL, NULL);
// SetRectEmpty(&mainViewRectangleToUpdate);
// } else
mainViewCallback(CALLBACK_TYPE_INVALIDATE,
0,
0,
NULL, NULL);
} }
void mainViewResizeCallback(int x, int y) { void mainViewResizeCallback(int x, int y) {
@ -975,11 +988,11 @@ JNIEXPORT void JNICALL Java_org_emulator_calculator_NativeLib_onViewCopy(JNIEnv
size_t strideSource = (size_t)(4 * ((hBmp->bitmapInfoHeader->biWidth * hBmp->bitmapInfoHeader->biBitCount + 31) / 32)); size_t strideSource = (size_t)(4 * ((hBmp->bitmapInfoHeader->biWidth * hBmp->bitmapInfoHeader->biBitCount + 31) / 32));
size_t strideDestination = bitmapScreenInfo.stride; size_t strideDestination = bitmapScreenInfo.stride;
VOID * bitmapBitsSource = (VOID *)hBmp->bitmapBits; VOID * bitmapBitsSource = (VOID *)hBmp->bitmapBits;
VOID * bitmapBitsDestination = pixelsDestination; VOID * bitmapBitsDestination = pixelsDestination + (hBmp->bitmapInfoHeader->biHeight - 1) * strideDestination;
for(int y = 0; y < hBmp->bitmapInfoHeader->biHeight; y++) { for(int y = 0; y < hBmp->bitmapInfoHeader->biHeight; y++) {
memcpy(bitmapBitsDestination, bitmapBitsSource, strideSource); memcpy(bitmapBitsDestination, bitmapBitsSource, strideSource);
bitmapBitsSource += strideSource; bitmapBitsSource += strideSource;
bitmapBitsDestination += strideDestination; bitmapBitsDestination -= strideDestination;
} }

View file

@ -60,6 +60,8 @@ static void initTimer();
#define MAX_FILE_MAPPING_HANDLE 10 #define MAX_FILE_MAPPING_HANDLE 10
static HANDLE fileMappingHandles[MAX_FILE_MAPPING_HANDLE]; static HANDLE fileMappingHandles[MAX_FILE_MAPPING_HANDLE];
HBITMAP rootBITMAP;
void win32Init() { void win32Init() {
initTimer(); initTimer();
for (int i = 0; i < MAX_FILE_MAPPING_HANDLE; ++i) { for (int i = 0; i < MAX_FILE_MAPPING_HANDLE; ++i) {
@ -70,6 +72,8 @@ void win32Init() {
contentSchemeLength = _tcslen(contentScheme); contentSchemeLength = _tcslen(contentScheme);
documentSchemeLength = _tcslen(documentScheme); documentSchemeLength = _tcslen(documentScheme);
comPrefixLength = _tcslen(comPrefix); comPrefixLength = _tcslen(comPrefix);
rootBITMAP = CreateCompatibleBitmap(NULL, 0, 0);
} }
int abs (int i) { int abs (int i) {
@ -1832,6 +1836,8 @@ BOOL DeleteObject(HGDIOBJ ho) {
} }
case HGDIOBJ_TYPE_BITMAP: { case HGDIOBJ_TYPE_BITMAP: {
PAINT_LOGD("PAINT DeleteObject() HGDIOBJ_TYPE_BITMAP"); PAINT_LOGD("PAINT DeleteObject() HGDIOBJ_TYPE_BITMAP");
if(ho == rootBITMAP)
return FALSE;
ho->handleType = HGDIOBJ_TYPE_INVALID; ho->handleType = HGDIOBJ_TYPE_INVALID;
if(ho->bitmapInfo) if(ho->bitmapInfo)
free((void *) ho->bitmapInfo); free((void *) ho->bitmapInfo);
@ -1903,6 +1909,7 @@ HDC CreateCompatibleDC(HDC hdc) {
memset(handle, 0, sizeof(struct _HDC)); memset(handle, 0, sizeof(struct _HDC));
handle->handleType = HDC_TYPE_DC; handle->handleType = HDC_TYPE_DC;
handle->hdcCompatible = hdc; handle->hdcCompatible = hdc;
handle->selectedBitmap = rootBITMAP;
return handle; return handle;
} }
HDC GetDC(HWND hWnd) { HDC GetDC(HWND hWnd) {

View file

@ -63,6 +63,7 @@ public class MainScreenView extends PanAndScaleView {
public float defaultViewPanOffsetX = 0.0f; public float defaultViewPanOffsetX = 0.0f;
public float defaultViewPanOffsetY = 0.0f; public float defaultViewPanOffsetY = 0.0f;
// private Rect invalidateRectangle = new Rect();
public MainScreenView(Context context) { public MainScreenView(Context context) {
super(context); super(context);
@ -406,6 +407,16 @@ public class MainScreenView extends PanAndScaleView {
// Copy the full calculator with antialiasing // Copy the full calculator with antialiasing
canvas.drawBitmap(bitmapMainScreen, 0, 0, paintFullCalc); canvas.drawBitmap(bitmapMainScreen, 0, 0, paintFullCalc);
// synchronized (invalidateRectangle) {
// if (invalidateRectangle.isEmpty()) {
// canvas.drawColor(getBackgroundColor());
// canvas.drawBitmap(bitmapMainScreen, 0, 0, paintFullCalc);
// } else {
// canvas.drawBitmap(bitmapMainScreen, invalidateRectangle, invalidateRectangle, paintFullCalc);
// invalidateRectangle.setEmpty();
// }
// }
if(usePixelBorders) { if(usePixelBorders) {
// Copy the LCD part only without antialiasing // Copy the LCD part only without antialiasing
int x = NativeLib.getScreenPositionX(); int x = NativeLib.getScreenPositionX();
@ -457,36 +468,51 @@ public class MainScreenView extends PanAndScaleView {
} }
public void updateCallback(int type, int param1, int param2, String param3, String param4) { public void updateCallback(int type, int param1, int param2, String param3, String param4) {
switch (type) { try {
case NativeLib.CALLBACK_TYPE_INVALIDATE: switch (type) {
if (debug) Log.d(TAG, "updateCallback() CALLBACK_TYPE_INVALIDATE postInvalidate()"); case NativeLib.CALLBACK_TYPE_INVALIDATE:
postInvalidate(); // int left = param1 >> 16;
if(this.onUpdateDisplayListener != null) // int top = param1 & 0xFFFF;
this.onUpdateDisplayListener.run(); // int right = param2 >> 16;
break; // int bottom = param2 & 0xFFFF;
case NativeLib.CALLBACK_TYPE_WINDOW_RESIZE: // if (debug) Log.d(TAG, "updateCallback() CALLBACK_TYPE_INVALIDATE postInvalidate() left: " + left + ", top: " + top + ", right: " + right + ", bottom: " + bottom);
if (debug) Log.d(TAG, "updateCallback() CALLBACK_TYPE_WINDOW_RESIZE()"); // synchronized (invalidateRectangle) {
// New Bitmap size // invalidateRectangle.union(left, top, right, bottom);
if(bitmapMainScreen == null || bitmapMainScreen.getWidth() != param1 || bitmapMainScreen.getHeight() != param2) { // }
if(debug) Log.d(TAG, "updateCallback() Bitmap.createBitmap(x: " + Math.max(1, param1) + ", y: " + Math.max(1, param2) + ")"); if (debug)
Bitmap oldBitmapMainScreen = bitmapMainScreen; Log.d(TAG, "updateCallback() CALLBACK_TYPE_INVALIDATE postInvalidate()");
bitmapMainScreen = Bitmap.createBitmap(Math.max(1, param1), Math.max(1, param2), Bitmap.Config.ARGB_8888); postInvalidate();
int globalColor = NativeLib.getGlobalColor(); if (this.onUpdateDisplayListener != null)
kmlBackgroundColor = Color.argb(255, (globalColor & 0x00FF0000) >> 16, (globalColor & 0x0000FF00) >> 8, globalColor & 0x000000FF); this.onUpdateDisplayListener.run();
break;
case NativeLib.CALLBACK_TYPE_WINDOW_RESIZE:
if (debug) Log.d(TAG, "updateCallback() CALLBACK_TYPE_WINDOW_RESIZE()");
// New Bitmap size
if (bitmapMainScreen == null || bitmapMainScreen.getWidth() != param1 || bitmapMainScreen.getHeight() != param2) {
if (debug)
Log.d(TAG, "updateCallback() Bitmap.createBitmap(x: " + Math.max(1, param1) + ", y: " + Math.max(1, param2) + ")");
Bitmap oldBitmapMainScreen = bitmapMainScreen;
bitmapMainScreen = Bitmap.createBitmap(Math.max(1, param1), Math.max(1, param2), Bitmap.Config.ARGB_8888);
int globalColor = NativeLib.getGlobalColor();
kmlBackgroundColor = Color.argb(255, (globalColor & 0x00FF0000) >> 16, (globalColor & 0x0000FF00) >> 8, globalColor & 0x000000FF);
bitmapMainScreen.eraseColor(getBackgroundColor()); bitmapMainScreen.eraseColor(getBackgroundColor());
NativeLib.changeBitmap(bitmapMainScreen); NativeLib.changeBitmap(bitmapMainScreen);
if(oldBitmapMainScreen != null) { if (oldBitmapMainScreen != null) {
oldBitmapMainScreen.recycle(); oldBitmapMainScreen.recycle();
} }
firstTime = true; firstTime = true;
setVirtualSize(bitmapMainScreen.getWidth(), bitmapMainScreen.getHeight()); setVirtualSize(bitmapMainScreen.getWidth(), bitmapMainScreen.getHeight());
if(viewSized) if (viewSized)
updateLayout(); updateLayout();
} }
break; break;
} }
} catch (Exception ex) {
if (debug)
Log.d(TAG, "updateCallback() Exception: " + ex.toString());
}
} }
public void setRotationMode(int rotationMode, boolean isDynamic) { public void setRotationMode(int rotationMode, boolean isDynamic) {

View file

@ -22,9 +22,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
@ -113,6 +111,8 @@ public class PrinterSimulatorFragment extends AppCompatDialogFragment {
Bitmap croppedPaperBitmap = Bitmap.createBitmap(paperBitmap.getWidth(), printerSimulator.getPaperHeight(), Bitmap.Config.ARGB_8888); Bitmap croppedPaperBitmap = Bitmap.createBitmap(paperBitmap.getWidth(), printerSimulator.getPaperHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(croppedPaperBitmap); Canvas canvas = new Canvas(croppedPaperBitmap);
Paint paint = new Paint(); Paint paint = new Paint();
paint.setAntiAlias(false);
paint.setFilterBitmap(false);
canvas.drawBitmap(paperBitmap, 0, 0, paint); canvas.drawBitmap(paperBitmap, 0, 0, paint);
Activity activity = getActivity(); Activity activity = getActivity();
@ -122,13 +122,16 @@ public class PrinterSimulatorFragment extends AppCompatDialogFragment {
FileOutputStream fileOutputStream = new FileOutputStream(imageFile); FileOutputStream fileOutputStream = new FileOutputStream(imageFile);
croppedPaperBitmap.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream); croppedPaperBitmap.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream);
fileOutputStream.close(); fileOutputStream.close();
String mimeType = "application/png";
Intent intent = new Intent(Intent.ACTION_SEND); String subject = getString(Utils.resId(PrinterSimulatorFragment.this, "string", "message_printer_share_graphic"));
intent.setType(mimeType); Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_SUBJECT, Utils.resId(PrinterSimulatorFragment.this, "string", "message_printer_share_graphic")); intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.putExtra(Intent.EXTRA_TITLE, subject);
intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(getActivity(), getActivity().getPackageName() + ".provider", imageFile)); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(getActivity(), getActivity().getPackageName() + ".provider", imageFile));
intent.setType("image/png");
// intent.setDataAndType(FileProvider.getUriForFile(getActivity(), getActivity().getPackageName() + ".provider", imageFile), "image/png");
startActivity(Intent.createChooser(intent, getString(Utils.resId(PrinterSimulatorFragment.this, "string", "message_printer_share_graphic")))); startActivity(Intent.createChooser(intent, getString(Utils.resId(PrinterSimulatorFragment.this, "string", "message_printer_share_graphic"))));
} }
} catch (Exception e) { } catch (Exception e) {
@ -243,6 +246,7 @@ public class PrinterSimulatorFragment extends AppCompatDialogFragment {
scaleThumbnailColor = Color.GRAY; scaleThumbnailColor = Color.GRAY;
paintBitmap.setAntiAlias(false); paintBitmap.setAntiAlias(false);
paintBitmap.setFilterBitmap(false);
} }
public void setBitmap(Bitmap bitmap) { public void setBitmap(Bitmap bitmap) {

View file

@ -145,6 +145,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
return size() > MAX_MRU; return size() > MAX_MRU;
} }
}; };
private HashMap<Integer, String> mruByMenuId = new HashMap<>();
private final PrinterSimulator printerSimulator = new PrinterSimulator(); private final PrinterSimulator printerSimulator = new PrinterSimulator();
private final PrinterSimulatorFragment fragmentPrinterSimulator = new PrinterSimulatorFragment(); private final PrinterSimulatorFragment fragmentPrinterSimulator = new PrinterSimulatorFragment();
@ -261,6 +262,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
if (recentsSubMenu != null) if (recentsSubMenu != null)
recentsSubMenu.clear(); recentsSubMenu.clear();
} }
mruByMenuId.clear();
if (recentsSubMenu != null) { if (recentsSubMenu != null) {
Set<String> mruLinkedHashMapKeySet = mruLinkedHashMap.keySet(); Set<String> mruLinkedHashMapKeySet = mruLinkedHashMap.keySet();
String[] mrus = mruLinkedHashMapKeySet.toArray(new String[0]); String[] mrus = mruLinkedHashMapKeySet.toArray(new String[0]);
@ -271,8 +273,11 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
// We should remove this file because it seems impossible to get the display name of this Most Recently Used state file. // We should remove this file because it seems impossible to get the display name of this Most Recently Used state file.
// It might be deleted or the permissions does not allow to reach it anymore. // It might be deleted or the permissions does not allow to reach it anymore.
mruLinkedHashMap.remove(mostRecentlyUsedFile); mruLinkedHashMap.remove(mostRecentlyUsedFile);
} else } else {
recentsSubMenu.add(Menu.NONE, MRU_ID_START + i, Menu.NONE, displayName); int menuId = MRU_ID_START + i;
mruByMenuId.put(menuId, mostRecentlyUsedFile);
recentsSubMenu.add(Menu.NONE, menuId, Menu.NONE, displayName);
}
} }
} }
} }
@ -397,20 +402,16 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
} else if (id == R.id.nav_about) { } else if (id == R.id.nav_about) {
OnAbout(); OnAbout();
} else if(id >= MRU_ID_START && id < MRU_ID_START + MAX_MRU) { } else if(id >= MRU_ID_START && id < MRU_ID_START + MAX_MRU) {
String url = mruByMenuId.get(id);
if(url != null) {
// Increase the file usage count
mruLinkedHashMap.get(url);
Set<String> mruLinkedHashMapKeySet = mruLinkedHashMap.keySet(); ensureDocumentSaved(() -> {
int mruLength = mruLinkedHashMapKeySet.size(); // FileOpen from MRU.
String[] mrus = mruLinkedHashMapKeySet.toArray(new String[mruLength]); onFileOpen(url, null, null);
});
int mruClickedIndex = id - MRU_ID_START; }
String url = mrus[mruClickedIndex];
mruLinkedHashMap.get(url);
ensureDocumentSaved(() -> {
// FileOpen from MRU.
onFileOpen(url, null, null);
});
} }
drawer.closeDrawer(GravityCompat.START); drawer.closeDrawer(GravityCompat.START);
@ -862,14 +863,17 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
FileOutputStream fileOutputStream = new FileOutputStream(imageFile); FileOutputStream fileOutputStream = new FileOutputStream(imageFile);
bitmapScreen.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream); bitmapScreen.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream);
fileOutputStream.close(); fileOutputStream.close();
String mimeType = "application/png";
Intent intent = new Intent(android.content.Intent.ACTION_SEND); String subject = getString(R.string.message_screenshot);
intent.setType(mimeType); Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_SUBJECT, R.string.message_screenshot); intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.putExtra(Intent.EXTRA_TITLE, subject);
intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(this,this.getPackageName() + ".provider", imageFile)); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(intent, getString(R.string.message_share_screenshot))); intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(this,this.getPackageName() + ".provider", imageFile));
intent.setType("image/png");
// intent.setDataAndType(FileProvider.getUriForFile(this,this.getPackageName() + ".provider", imageFile), "image/png");
startActivity(Intent.createChooser(intent, getString(R.string.message_share_screenshot)));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
showAlert(e.getMessage()); showAlert(e.getMessage());
@ -890,14 +894,17 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
FileOutputStream fileOutputStream = new FileOutputStream(imageFile); FileOutputStream fileOutputStream = new FileOutputStream(imageFile);
bitmapScreen.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream); bitmapScreen.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream);
fileOutputStream.close(); fileOutputStream.close();
String mimeType = "application/png";
Intent intent = new Intent(android.content.Intent.ACTION_SEND); String subject = getString(R.string.message_screenshot);
intent.setType(mimeType); Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_SUBJECT, R.string.message_screenshot); intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.putExtra(Intent.EXTRA_TITLE, subject);
intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(this,this.getPackageName() + ".provider", imageFile)); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(intent, getString(R.string.message_share_screenshot))); intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(this,this.getPackageName() + ".provider", imageFile));
intent.setType("image/png");
// intent.setDataAndType(FileProvider.getUriForFile(this,this.getPackageName() + ".provider", imageFile), "image/png");
startActivity(Intent.createChooser(intent, getString(R.string.message_share_screenshot)));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
showAlert(e.getMessage()); showAlert(e.getMessage());
@ -961,7 +968,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
} else } else
kmlScriptsForCurrentModel = kmlScripts; kmlScriptsForCurrentModel = kmlScripts;
boolean showDefaultKMLScriptFolderItem = !kmlFolderUseDefault && getPackageName().contains("org.emulator.forty.eight"); boolean showDefaultKMLScriptFolderItem = !kmlFolderUseDefault && (getPackageName().contains("org.emulator.forty.eight") || getPackageName().contains("org.emulator.forty.two"));
int lastIndex = kmlScriptsForCurrentModel.size(); int lastIndex = kmlScriptsForCurrentModel.size();
String[] kmlScriptTitles = new String[lastIndex + (showDefaultKMLScriptFolderItem ? 2 : 1)]; String[] kmlScriptTitles = new String[lastIndex + (showDefaultKMLScriptFolderItem ? 2 : 1)];
for (int i = 0; i < kmlScriptsForCurrentModel.size(); i++) for (int i = 0; i < kmlScriptsForCurrentModel.size(); i++)
@ -970,7 +977,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
if(showDefaultKMLScriptFolderItem) if(showDefaultKMLScriptFolderItem)
kmlScriptTitles[lastIndex + 1] = getResources().getString(R.string.load_default_kml); kmlScriptTitles[lastIndex + 1] = getResources().getString(R.string.load_default_kml);
new AlertDialog.Builder(MainActivity.this) new AlertDialog.Builder(MainActivity.this)
.setTitle(getResources().getString(R.string.pick_calculator)) .setTitle(getResources().getString(kmlFolderUseDefault ? R.string.pick_default_calculator : R.string.pick_custom_calculator))
.setItems(kmlScriptTitles, (dialog, which) -> { .setItems(kmlScriptTitles, (dialog, which) -> {
if(which == lastIndex) { if(which == lastIndex) {
// [Select a Custom KML script folder...] // [Select a Custom KML script folder...]

View file

@ -61,7 +61,8 @@
<string name="load_custom_kml">[Select a Custom KML script folder...]</string> <string name="load_custom_kml">[Select a Custom KML script folder...]</string>
<string name="load_default_kml">[Default KML script folder]</string> <string name="load_default_kml">[Default KML script folder]</string>
<string name="pick_calculator">Pick a calculator</string> <string name="pick_default_calculator">Pick a default calculator</string>
<string name="pick_custom_calculator">Pick a custom calculator</string>
<string name="dialog_printer_simulator_title">Printer Simulator</string> <string name="dialog_printer_simulator_title">Printer Simulator</string>
<string name="tab_printer_textual">Text</string> <string name="tab_printer_textual">Text</string>