I know that there are a lot of questions about capturing screenshots, and I have checked most of them. They have the same answer (with small code variations).
I have following method for screenshot capturing:
#NonNull
public static Bitmap takeScreenShot(Window window) throws IOException {
final View rootView = window.getDecorView().getRootView();
final boolean drawingCacheEnabled = rootView.isDrawingCacheEnabled();
rootView.setDrawingCacheEnabled(true);
try {
return Bitmap.createBitmap(rootView.getDrawingCache());
} finally {
rootView.setDrawingCacheEnabled(drawingCacheEnabled);
}
}
And you can use it like these: takeScreenShot(getActivity().getWindow())
However these approach has several limitations:
If you have some dialogs on the screen they will not be captured on
screenshot.
Will it work with hardware accelerated views? According
to documentation:
When hardware acceleration is turned on, enabling the
drawing cache has no effect on rendering because the system uses a
different mechanism for acceleration which ignores the flag
Screenshot contains black boxes
instead of GLviews. (e.g. when you app has maps.). It seems to be as a result of 2nd point.
So my question is, is there any solution without rooting that can solve at least some of my issues?
Check out the following GitHub repo (not mine!): https://github.com/AndroidDeveloperLB/ScreenshotSample
Also, the following will be useful reading:
How to properly take a screenshot, globally?
Related
The basic sample project of OpenTok shows how to make a VideoCall, showing the subscribers videostream in a small frame above the publishers stream.
I'm trying to achieve the same, only vice versa.
Problems:
Simply changing the two container views in the layout xml doesnt work. What happens is, that the publisher stream (the one that should now be on top of the other stream) is not showing up (is invisble)
This issue describes the exact problem, hinting me towards using setZOrderMediaOverlay(true); setZOrderOnTop(true); The problem with this approach is that now the publisher stream is on top of everything, even the android gui which is not tolerable for my use case.
Using only setZOrderMediaOverlay(true); does not work. The publisher view still is invisble.
Any idea on how to achieve this?
Try using TextureViews instead of GLSurfaceView, which is what OpenTok sdk uses by default.
To enable TextureViews, build your session in this way:
Session session = new Session.Builder(this, "apiKey", "sessionId")
.sessionOptions(new Session.SessionOptions() {
#Override
public boolean useTextureViews() {
return true;
}
}).build();
That will make the Publisher and Subscriber objects use TextureViews for its rendering.
Oficial doc is here
I am using UMP example provided by Google, I have not made any change in my code, even I have not tried anything out of the box, I just imported your project into my work-space and checked it on my device, and found that I am not getting Thumb with Genres (Songs by genre) and List of Genres...
Whereas I supposed to get Thumb from our JSON, here is what I have tried (but no success) -
holder.mImageView.setImageBitmap(description.getIconBitmap());
UPDATE # 1 AS PER SUGGESTED BY #NageshSusarla here
holder.mTitleView.setText(description.getTitle());
holder.mDescriptionView.setText(description.getSubtitle());
AlbumArtCache cache = AlbumArtCache.getInstance();
Bitmap art = cache.getIconImage(url);
if (art == null) {
cache.fetch(url, new AlbumArtCache.FetchListener() {
#Override
public void onFetched(String artUrl, Bitmap bitmap, Bitmap icon) {
if (artUrl.equals(url)) {
holder.mImageView.setImageBitmap(icon);
}
}
});
} else {
holder.mImageView.setImageBitmap(bitmap);
}
holder.mImageView.setImageBitmap(description.getIconBitmap());
and getting Cannot resolve symbol 'url'
The icon bitmap may not have been set. It's best to use the AlbumartCache to fetch the icon and then set it on the imageView. The url to be passed to AlbumArtCache.getInstance().fetch(url,..) is description.getIconUri().toString()
The reason you may not be seeing it in uAmp is because of the tint being applied to it. You can remove the tint from media_list_item.xml to try out the changes.
Aside: This is indeed by design and the icon is only shown at the bottom when a user selects the item to be played.
This is by design. To keep the navigation cleaner, we decided to not
show the MediaItem icon on the local browsing UI. Other browsing UI's
may show it, like Android Auto and Android Wear.
I think you should check it in issues of android-UniversalMusicPlayer. Take a look at comment given by mangini here.
If you want to change uAmp to show the MediaDescription.getIconUri,
set the holder.mImageView at this.
thanks for checking my question out!
I'm currently working on a project using Qt C++, which is designed to be multi-platform. I'm a bit of a newcoming to it, so I've been asked to set up the ability to take screenshots from within the menu structure, and I'm having issues with the Android version of the companion app.
As a quick overview, it's a bit of software that send the content of a host PC's screen to our app, and I've been able to take screenshots on the Windows version just fine, using QScreen and QPixmap, like so:
overlaywindow.cpp
{
QPixmap screenSnapData = screenGrab->currentBackground();
}
screenGrabber.cpp
{
QScreen *screen = QGuiApplication::primaryScreen();
return screen->grabWindow( QApplication::desktop()->winId() );
}
Unfortunately, Android seems to reject QScreen, and with most suggestions from past Google searches suggesting the now-deprecated QPixmap::grab(), I've gotten a little stuck.
What luck I have had is within the code for the menu itself, and QWidget, but that isn't without issue, of course!
QFile doubleCheckFile("/storage/emulated/0/Pictures/Testing/checking.png");
doubleCheckFile.open(QIODevice::ReadWrite);
QPixmap checkingPixmap = QWidget::grab();
checkingPixmap.save(&doubleCheckFile);
doubleCheckFile.close();
This code does take a screenshot, but only of the button strip currently implemented, and not for the whole screen. I've also taken a 'screenshot' of just a white box with the screen's dimensions by using:
QDesktopWidget dw;
QWidget *screen=dw.screen();
QPixmap checkingPixmap = screen->grab();
Would anyone know of whether there was an alternative to using QScreen to take a screenshot in Android, or whether there's a specific way to get it working as compared to Windows? Or would QWidget be the right track? Any help's greatly appreciated!
as i can read in Qt doc : In your screenGrabber.cpp :
QScreen *screen = QGuiApplication::primaryScreen();
return screen->grabWindow( QApplication::desktop()->winId() );
replace with :
QScreen *screen = QGuiApplication::primaryScreen();
return screen->grabWindow( 0 ); // as 0 is the id of main screen
If you want to take a screenshot of your own widget, you can use the method QWidget::render (Qt Doc):
QPixmap pixmap(widget->size());
widget->render(&pixmap);
If you want to take a screenshot of another app/widget than your app, you should use the Android API...
I have just coded a simple example of using a scrolling pane in JavaFX. Just one ScrollPane placed in the Scene, and the ScrollPane holds a Label component with a large text. Using gradle I have uploaded the app on a Nexus 4 android device. As you can see from the video I have uploaded, the scrolling is way too slow. I am sure others have experienced this. Any suggestion of how this can be changed to the native speed scroll is really much appreciated.
Source code of the app can be downloaded from here.
AndroidFX.java
public class AndroidFX extends Application{
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
Parent mySearchListFXML = getFXMLPane("/fxml/ScrollPaneWithLabel.fxml");
primaryStage.setScene(new Scene(mySearchListFXML));
primaryStage.setWidth(Screen.getPrimary().getVisualBounds().getWidth()); primaryStage.setHeight(Screen.getPrimary().getVisualBounds().getHeight());
primaryStage.show();
}
public static Parent getFXMLPane(String url) throws IOException {
URL location = AndroidFX.class.getResource(url);
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(location);
Parent pane = fxmlLoader.load();
return pane;
}
}
ScrollPaneWithLabel.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<ScrollPane fx:id="scrollPane" fitToWidth="true" hbarPolicy="NEVER" pannable="true" style="-fx-background: white;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<content>
<Label text="<VERY LARGE TEXT HERE>" wrapText="true" />
</content>
</ScrollPane>
Faced similar issues. The problem is worse on hidpi devices, disabling the hipdpi setting in the properties file helps but you will have to do any scaling your self for hidpi screens.
Another thing that might help is caching the fonts. I believe the end result of a javafx ported application is more like a big image with hot spots. Scrolling I think is just telling the application to redraw the whole image every time. Just a theory really. Caching does help but can make your text look kinda fuzzy. Although I had some success in scaling the font large, setting the cache to true and then scale down, normally x2 and .5 gives pretty good results. Using em for the fonts helps the fuzzy text too.
If you need to show a huge amount of text and it must be scrolled, you will probably get much better results displaying it through a webview. I haven't ever really used it to be honest, but I would imagine that it is replaced when ported with the native browser window so performance should be pretty good I think. I guess it is possible they wrote a html renderer in javafx and then you would run into the same pitfalls.
http://www.gluonhq.com is offering something called the charm, down, and connect package that is supposed to mimic native apps. It sounds promising and I am currently trying to get more info to see if they have solutions to these types of issues. I will add to the post if I receive any more info about charm.
I'm building an Android Wear app and trying to implement BoxInsetLayout for round screens. In my code, I want to detect if the device is round or not, so I'm using BoxInsetLayout's isRound() function, but it always returns false, even on the Moto 360.
Anyone know if there's a way to programmatically tell if the device is round?
The problem may be caused by calling isRound() at the wrong time. The round-ness is determined by the WindowInsets being delivered to the BoxInsetLayout. If you call isRound() very early before the insets have been delivered, you will get the wrong answer.
So if you have a "box" object which is the BoxInsetLayout, you would do this:
box.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
#Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
// Need to also call the original insets since we have overridden the original
// https://developer.android.com/reference/android/view/View.OnApplyWindowInsetsListener.html
box.onApplyWindowInsets(windowInsets);
// You can make calls to detect isRound() here!
// Return the insets so the BoxInsetLayout still works properly
return windowInsets;
}
});
Can you please send us the code related to the BoxInsetLayout that you are using?
According to Wayne answer on G+ it is a bug, for now we know what causes it, how to avoid it but only if user is aware of that, but fix for it is not released (yet).
https://plus.google.com/108847189842978537754/posts/5YiYb14i7ss
Quoting as post might be deleted/changed:
The problem is triggered by the watch switching languages when pairing with a phone after a factory reset. You can avoid the issue by
selecting the same language on the wearable as you are using on the
phone, so that no change occurs afterwards when the devices are
paired.
Instructions to fix the problem:
Factory reset the Moto 360.
When the wearable restarts, it will ask what language you would like to use. Select the same language that you are using on the phone
(do not select the default of English)
On the phone, start the Android Wear companion app, and select from the overflow menu the option "Pair with a new wearable".
Pair the phone with the Moto 360.
EDIT:
Using setOnApplyWindowInsetsListener (suggested by Wayne) I created small class that simplify using it a bit. https://github.com/tajchert/ShapeWear
Just copy ShapeWear.java class, and subscribe to screen shape detection event setOnShapeChangeListener() or call method ShapeWear.isRound() (can throw error is shape is not yet determined) or ShapeWear. getShape() - which can result in ShapeWear.SHAPE_UNSURE in same situation.