Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CodenameOne/src/com/codename1/impl/CodenameOneImplementation.java
Original file line number Diff line number Diff line change
Expand Up @@ -1201,6 +1201,19 @@ public Image flipImageVertically(Image image, boolean maintainOpacity) {
return EncodedImage.createFromRGB(newRGB, width, height, !maintainOpacity);
}

/**
* Tries to grab an OS native screenshot which would include peer components etc.
* On fallback draws the current Form object.
*
* @param callback invoked with the screenshot
*/
public void screenshot(SuccessCallback<Image> callback) {
Form current = getCurrentForm();
Image img = Image.createImage(current.getWidth(), current.getHeight());
current.paintComponent(img.getGraphics(), true);
callback.onSucess(img);
}

/**
* Returns true if the platform supports a native image cache. The native image cache
* is different than just {@link FileSystemStorage#hasCachesDir()}. A native image cache
Expand Down Expand Up @@ -5686,6 +5699,7 @@ public void capturePhoto(ActionListener response) {
*
* @return An image of the screen, or null if it failed.
* @since 7.0
* @deprecated replaced by screenshot()
*/
public Image captureScreen() {
Form form = getCurrentForm();
Expand Down
3 changes: 2 additions & 1 deletion CodenameOne/src/com/codename1/testing/TestUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,8 @@ public static boolean screenshotTest(String screenshotName) {
return true;
}

Image mute = Image.createImage(Display.getInstance().getDisplayWidth(), Display.getInstance().getDisplayHeight());

Image mute = Display.getInstance().captureScreen();
Display.getInstance().getCurrent().paintComponent(mute.getGraphics(), true);
screenshotName = screenshotName + ".png";
if (Storage.getInstance().exists(screenshotName)) {
Expand Down
14 changes: 14 additions & 0 deletions CodenameOne/src/com/codename1/ui/Display.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import com.codename1.ui.util.ImageIO;
import com.codename1.util.AsyncResource;
import com.codename1.util.RunnableWithResultSync;
import com.codename1.util.SuccessCallback;

import java.io.IOException;
import java.io.InputStream;
Expand Down Expand Up @@ -4995,12 +4996,25 @@ public void onCanInstallOnHomescreen(Runnable r) {
*
* @return An image of the screen, or null if it failed.
* @since 7.0
* @deprecated use screenshot(SuccessCallback) instead
*/
public Image captureScreen() {
return impl.captureScreen();
}

/**
* Captures a screenshot in the native layer which should include peer
* components as well.
*
* @param callback will be invoked on the EDT with a screenshot
* @since 7.0.211
*/
public void screenshot(SuccessCallback<Image> callback) {
impl.screenshot(callback);
}


/**
* Convenience method to schedule a task to run on the EDT after {@literal timeout}ms.
*
* @param timeout The timeout in milliseconds.
Expand Down
221 changes: 114 additions & 107 deletions Ports/Android/src/com/codename1/impl/android/AndroidImplementation.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@
import android.util.Log;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
Expand Down Expand Up @@ -114,10 +114,10 @@
import android.telephony.SmsManager;
import android.telephony.gsm.GsmCellLocation;
import android.text.Html;
import android.view.*;
import android.view.View.MeasureSpec;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.*;
import android.view.View.MeasureSpec;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.webkit.*;
import android.widget.*;
import com.codename1.background.BackgroundFetch;
Expand Down Expand Up @@ -375,6 +375,13 @@ public static void stopContext(Context ctx) {
}
}

@Override
public void screenshot(SuccessCallback<Image> callback) {
final Activity activity = (Activity) getContext();
final AndroidScreenshotTask task = new AndroidScreenshotTask(myView, activity, callback);
activity.runOnUiThread(task);
}

@Override
public void setPlatformHint(String key, String value) {
if(key.equals("platformHint.compatPaintMode")) {
Expand Down Expand Up @@ -8006,27 +8013,27 @@ private String getImageFilePath(Uri uri) {
//String[] filePaths = file.getPath().split(":");
//String image_id = filePath[filePath.length - 1];
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContext().getContentResolver().query(
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{ MediaStore.Images.Media.DATA},
null,
null,
null
);
// Some gallery providers may return an empty cursor on modern Android builds.
String filePath = null;
if (cursor != null) {
try {
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
if (columnIndex >= 0 && cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
} finally {
cursor.close();
}
}

if (filePath == null || "content".equals(scheme)) {
Cursor cursor = getContext().getContentResolver().query(
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{ MediaStore.Images.Media.DATA},
null,
null,
null
);
// Some gallery providers may return an empty cursor on modern Android builds.
String filePath = null;
if (cursor != null) {
try {
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
if (columnIndex >= 0 && cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
} finally {
cursor.close();
}
}
if (filePath == null || "content".equals(scheme)) {
//if the file is not on the filesystem download it and save it
//locally
try {
Expand Down Expand Up @@ -8167,26 +8174,26 @@ else if (requestCode == FILECHOOSER_RESULTCODE) {
Uri selectedImage = intent.getData();
String scheme = intent.getScheme();

String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContext().getContentResolver().query(selectedImage, filePathColumn, null, null, null);

// Some gallery providers may return an empty cursor on modern Android builds.
String filePath = null;
if (cursor != null) {
try {
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
if (columnIndex >= 0 && cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
} finally {
cursor.close();
}
}
boolean fileExists = false;
if (filePath != null) {
File file = new File(filePath);
fileExists = file.exists() && file.canRead();
}
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContext().getContentResolver().query(selectedImage, filePathColumn, null, null, null);
// Some gallery providers may return an empty cursor on modern Android builds.
String filePath = null;
if (cursor != null) {
try {
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
if (columnIndex >= 0 && cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
} finally {
cursor.close();
}
}
boolean fileExists = false;
if (filePath != null) {
File file = new File(filePath);
fileExists = file.exists() && file.canRead();
}

if (!fileExists && "content".equals(scheme)) {
//if the file is not on the filesystem download it and save it
Expand Down Expand Up @@ -8214,23 +8221,23 @@ else if (requestCode == FILECHOOSER_RESULTCODE) {
}
}

if (filePath == null) {
callback.fireActionEvent(null);
return;
}

callback.fireActionEvent(new ActionEvent(new String[]{filePath}));
return;
if (filePath == null) {
callback.fireActionEvent(null);
return;
}
callback.fireActionEvent(new ActionEvent(new String[]{filePath}));
return;
} else if (requestCode == OPEN_GALLERY) {

Uri selectedImage = intent.getData();
String scheme = intent.getScheme();

String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContext().getContentResolver().query(selectedImage, filePathColumn, null, null, null);

// Some gallery providers may return an empty cursor on modern Android builds.
String filePath = null;
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContext().getContentResolver().query(selectedImage, filePathColumn, null, null, null);
// Some gallery providers may return an empty cursor on modern Android builds.
String filePath = null;
if (cursor != null) {
try {
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
Expand Down Expand Up @@ -10818,50 +10825,50 @@ public void run() {
return true;
}

public boolean isJailbrokenDevice() {
try {
Runtime.getRuntime().exec("su");
return true;
} catch(Throwable t) {
com.codename1.io.Log.e(t);
}
return false;
}

@Override
public void announceForAccessibility(final Component cmp, final String text) {
final Activity act = getActivity();
if (act == null) {
return;
}
act.runOnUiThread(new Runnable() {
@Override
public void run() {
View view = null;
if (cmp instanceof PeerComponent) {
Object peer = ((PeerComponent) cmp).getNativePeer();
if (peer instanceof View) {
view = (View) peer;
}
}
if (view == null) {
view = act.getWindow().getDecorView();
}
if (view == null) {
return;
}
if (Build.VERSION.SDK_INT >= 16) {
view.announceForAccessibility(text);
} else {
AccessibilityManager manager = (AccessibilityManager) act.getSystemService(Context.ACCESSIBILITY_SERVICE);
if (manager != null && manager.isEnabled()) {
AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
event.getText().add(text);
event.setSource(view);
manager.sendAccessibilityEvent(event);
}
}
}
});
}
}
public boolean isJailbrokenDevice() {
try {
Runtime.getRuntime().exec("su");
return true;
} catch(Throwable t) {
com.codename1.io.Log.e(t);
}
return false;
}
@Override
public void announceForAccessibility(final Component cmp, final String text) {
final Activity act = getActivity();
if (act == null) {
return;
}
act.runOnUiThread(new Runnable() {
@Override
public void run() {
View view = null;
if (cmp instanceof PeerComponent) {
Object peer = ((PeerComponent) cmp).getNativePeer();
if (peer instanceof View) {
view = (View) peer;
}
}
if (view == null) {
view = act.getWindow().getDecorView();
}
if (view == null) {
return;
}
if (Build.VERSION.SDK_INT >= 16) {
view.announceForAccessibility(text);
} else {
AccessibilityManager manager = (AccessibilityManager) act.getSystemService(Context.ACCESSIBILITY_SERVICE);
if (manager != null && manager.isEnabled()) {
AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
event.getText().add(text);
event.setSource(view);
manager.sendAccessibilityEvent(event);
}
}
}
});
}
}
Loading
Loading