How can I do to create a loading jframe without title bar like Eclipse in the image...
I used setUndecorate() to remove the title bar and a thread to wait 3 seconds then open the main window but it wouldn't work ...
I'm not thinking to use a progressbar...
How can I do??
Thanks in advance.
Best rgards,
Ali
See the SplashScreen class.
It includes the createGraphics() method that returns a Graphics2D object that can be written to. You would need to draw the progress bar to the graphics object.
Java Web Start also offers splash screen functionality, configured in the launch file. But the graphics object of the JWS splash screen are not available to the app. (so no 'progress bar').
Another way could be what you already thought of: display an undecorated JFrame when the application starts, then instead of just waiting for a few seconds (you could do that as well, if you want users to read some info) just keep initializing the application. When initialization is finished, close the "splash screen" (undecorated JFrame) and open the actual application JFrame.
This would enable you to display dynamic information (like a progress bar if you later want to, some text etc.). If all you need is a static splash screen, go for Andrew's advice and use the built in splash screen functionality.
Related
The app I'm working on shows some sensitive information that must not be shown on the "Recent Tasks" screen when stopping the app by pressing the home button.
I'd like to blur the sensitive data in the screenshot or show the app logo instead.
I am aware of the following approaches but they don't fit my requirements:
Setting the actvitie's android:excludeFromRecents to true in the manifiest prevents the app from being shown at all in the recent tasks. This would disrupt the user experience.
Using FLAG_SECURE results in a blank card on the recents tasks screen. (How do I prevent Android taking a screenshot when my app goes to the background?) I don't like the blank screen. However, I'll stick to this solution if there is no workaround.
Overriding onCreateThumbnail seems like the ideal solution but, unfortunately, doesn't work as it's currently not invoked by the OS :( (https://code.google.com/p/android/issues/detail?id=29370)
And then there are some workarounds that I tried out but that didn't work as hoped:
Start a new activity that shows the app logo in onPause so that it's screenshot is shown instead of the actual activitie's one. But the new activity takes too long to open and it disrupts the user experience.
Set the activitie's content view to an image of the app logo in onPause. That seemed like a great solution to me. Unfortunately, the screenshot for the recent tasks screen is taken at an unspecified time. During testing the app logo quickly appears before the app is closed when pressing 'Home' but the resulting screenshot shows the activity a short time before that.
Removing the sensitive data from the widgets (e.g. textView.setText("")) has the same problem of screenshot timing just mentioned.
Any alternative ideas or solutions to the listed workarounds?
I looked into this a couple of months ago for the same purpose as you.
Unfortunately, I had to conclude that it is simply not possible. I dug through the android source code and confirmed it.
There is no callbacks or methods from android that allows you to customize it (that works anyway). Besides FLAG_SECURE, this part of the code does not accept any input or change.
OnPause and similar lifecycle methods are called too late (the screenshot is taken already). All lifecycle methods that would hint that you're about to go into the background runs too late.
The image you see in the recent tasks is an actual screenshot - and thus isn't affected by changes you do (too late) to your view. That means you can't modify your view just-in-time (like making it invisible, replacing with something else, adding SECURE_FLAG, or any other obstruction of the view). As an aside, these images can be found on an emulator at /data/system_ce/0/recent_images.
The only exception is using FLAG_SECURE, which will prevent the screenshot from being taken of your application. I experimented with setting this FLAG in onPause and removing it in onResume, however as mentioned already these lifecycle methods runs after the screenshot is taken already, and thus had absolutely no effect.
As discussed in How to change the snapshot shown by recent apps list? there used to be a callback that you could use to customize the thumbnail: onCreateThumbnail. However, this does not work and it is never called. To be clear, the callback is still there, it is simply never called by the OS. The fact that it stopped working is poorly documented, but apparently was silently deprecated/removed in 4.0.3
As for the thumbnail itself, it is a screenshot taken serverside. It is taken before onPause is called (or in fact before any callbacks indicating that your activity is about to go into the background is called).
When your app does go into the background, your actual view is animated (to get that zoom-out transition). That animation can be affected through changes you do in onPause (if you're fast enough that is) (I experimented with setting opacity to 0 on the window among other things). This will however only affect the animation. When the animation is finished, the view is replaced by the screenshot taken earlier.
Also see these questions that discuss this:
When does Android take its recent apps switcher screenshot?
Show custom application image in task manager on ICS or JB
Android never call method onCreateThumbnail
Currently (28/10/2020) is impossibile customizing app thumbnail in recent apps screen.
As explained by #Dellkan in the previous answer, the onCreateThumbnail method is not called anymore by the OS.
Unfortunately, also the suggestion to create a kind of launcher/splash screen without the FLAG_SECURE flag to let the app take a screenshot of that activity is not working, because the screenshot is taken on the activity you see and not at the launch of the app.
You cannot even customize the color of window background when using FLAG_SECURE as reported here.
How about implementing a layout overlay on top of your entire activity?
Make it transparent, it's click-through by default, so no negative impact on UX while in use.
In onPause() set a half-transparent, blurred image as the background of that layout, the data will be scrambled behind it. In onResume() change the background to fully transparent again. Voila.
It might be faster than other types of overlays. The positive side effect is, if you do the unblurring as a short animation effect when the user goes back (with a proper library that uses C++ instead of Java), it might even look cool and the users wouldnt even mind seeing it.
I haven't tried this myself, but it's something you haven't tried yet.
Since onPause is called to late, I use WindowFocusChangeListener to observe when the Fragment loses focus. At this moment we can hide all view which show sensitive data:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.getViewTreeObserver().addOnWindowFocusChangeListener(new ViewTreeObserver.OnWindowFocusChangeListener() {
#Override
public void onWindowFocusChanged(boolean hasFocus) {
// hide sensitive data when window moves to background (before system screenshot is captured)
myViewWithSensitiveData.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE);
}
});
There is a way to customize it. You need your Activities with sensitive data to FLAG_SECURE in onCreate before you setContentView. Then you need an empty Activity, which renders whatever you want to have as the customized thumbnail. This usually is some sort of splash screen. This new Activity needs to be the launcher and is the only Activity not FLAG_SECURE. This Activity is launched and in onResume starts your actual Activity with the sensitive data.
Android OS will take a screenshot of that new Activity at the beginning of your App. Unfortunately the users will also see this Activity for a short moment. Since every other Activity is FLAG_SECURE, Android OS will use the only available screenshot it made at the beginning.
Was looking for a solution and found some dirty things in case you don't want to use 'FLAG_SECURE'. It doesn't give a nice picture but protects data and doesn't prevent making screenshots for the user while they are in the app.
protected void onPause () {
this.getWindow().getDecorView().getRootView().setScaleX((float)200);
this.getWindow().getDecorView().getRootView().setScaleY((float)200);
super.onPause();
}
protected void onResume () {
this.getWindow().getDecorView().getRootView().setScaleX((float)1);
this.getWindow().getDecorView().getRootView().setScaleY((float)1);
super.onResume();
}
I think this can only achieve through BroadCastReceiver but there is no receiver present. So therefore you first disable default screenshot functionality in android and then implementing your own functionality to take screenshot and before taking screenshot you should blur your secure information.
What is the proper way of completely disposing of a screen in Libgdx? Currently If I click where a button was on my previous screen the button still does what it would of done if I were on that screen. Should I be .dispose()-ing everything I can in the dispose() method? or is there a simpler way to dispose of everything on screen?
Unfortunately there is no easier way. These classes do not share any kind of common "Disposable" interface, or anything like that, to do it automatically. Everything that has a dispose() method needs to be disposed manually when it's not needed anymore.
This is also valid for the Screens themselves. When switching Screens they do not get disposed automatically, but you need to do that yourself (before calling Game.setScreen()).
On the other hand, this is not a big deal. Just look through everything in your Screen and check whether it has to be disposed or not. If there is a dispose method, call it in dispose() of the Screen.
BUT this does not explain your behaviour about invisible buttons from the last Screen. I suppose you use a Stage and used Gdx.input.setInputProcessor(stage);. This setting will not be changed when you change the screen and you have to set the input processor to the Stage of your current Screen, or to whatever that handles the input in your current Screen. That way the "old" stage will not catch any inputs anymore.
I can confirm that this issue is not passing the inpur processor a new stage. this will result in "ghost" buttons as described.
Unfortunately LibGDX API documentation says
Note that dispose() is not called automatically.
So what I do is disposing all disposables (such as Stage, Skin, Texture ... etc) inside the hide() method in the Screen because hide() is called automatically and it works very well!
example:
public class GameScreen implements Screen {
...
#Override
public void hide() {
mainStage.dispose();
playGroundStage.dispose();
controller.dispose();
labelActor.dispose();
}
...
}
Hopefully this isn't a dumb question, but when I initially click on my app, a kind of splash screen first appears for a few seconds with just a title bar indicating the name of the app and nothing else - then the app loads as expected. Is there any way to remove this screen?
The system looks into your AndroidManifest.xml to find out what is the theme of the main Activity. If you don't specify it manually, it assumes the application theme, if you don't specify application theme then the default theme is used. The system then creates the "splash screen" solely acoording to the theme.
So if you want to remove it, create a theme that has a transparent background and no ActionBar. And in onCreate() you probably want to change the theme again (or just change the background and show the ActionBar).
But it's better to have some visible "splash screen". Otherwise if you click on the icon, you won't see nothing for 1 - 2 seconds, which is quite weird, almost no app does this.
Initializing more resources on
onCreate()
may take some time. Try not to overload onCreate() method of Activity.
Try not to deep down more than 30 levels inside the xml layout file. which can also take up some time to initialize .
setContentView(R.layout.main)
I have an application containing multiple activities.
At the moment the whole application contains about 8 activities. First I show a splash screen for a few seconds where all the preferences are loaded and set up (from sharedPreferences) - these are saved in a "Setting" class I made for this - this class basicly just have a bunch of static variables, so all activities in the app can read these and modify them as they need to.
EDIT: More data is getting stored in this class as the app runs, some of this is from a webservice - the data is parsed into obejcts and references to these obejcts are saved in the Settings class too (or a list of the objects).
My problem is then, that when users press the HOME key, the current activity is put in the background. If the activity is in the background for a long time (a lot of users "close" apps by pressing home instead of back), and then reopened it shows the activity that was running before HOME was pressed.
As an example - lets say the user starts the app, sees the Splash screen for a few seconds. The splash screen then starts a new activity and calls finish on itself.
This means that now the Activity stack is just the MainActivity (main menu). In the MainActivity I supply all the buttons with listeners in the onCreate method, and most buttons require some info from the Settings class mentioned above.
When I then press HOME and reopens the app a few hours later, none of the buttons works anymore - seems the graphic is reacting etc, but something still goes wrong. One of the buttons that should work even with all settings wiped will just open a dialog with some text in it.
The listener:
Button b = (Button)v.findViewById(R.id.id_b1);
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Dialog dialog = createDialog(MainActivity.this, DIALOG_CONST1);
dialog.show();
}
});
I have some constantst for dialog types, as I'm using some custom designs for the dialogs I have created a class to created the dialogs for me.
From the activity containing the button (simplified a bit):
public static Dialog createDialog(final Context c, int dialogId) {
Dialog dialog = null;
CustomDialog.Builder customBuilder;
switch (dialogId) {
...
case d1:
customBuilder = new CustomDialog.Builder(c, DIALOG_CONST1);
//Sets up the parapters to create the dialog afterwards
customBuilder.setTitle("Header").setMessage("Content")
.setPositiveButton("", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialog = customBuilder.create(); //Creates the dialog from the above settings
dialog.setCanceledOnTouchOutside(true);
break;
...
}
... //Set the width of the dialog
return dialog;
}
The CustomDialog class extends the Dialog class and then depending on the const it
s supplied with it inflates one of several dialog layouts and adds content etc. Works great normally, but after the app have been paused by HOME for a while, and things go wrong no dialog is shown when I press the button. I do se a flash of a loading dialog on the other buttons, but nothing happens afterwards - no dialog is shown. Strange thing is that if I press on the button again in the middle of the screen, I can't press it (grahics dont react), but when pressing once in the side of the screen and then in the middle the graphics do react, the dialogs does get cancelled when pressing outside, so I'm wondering if there is some very slim "transparent" dialog in the middle or something - I just have no clue why this would happen.
EDIT: Actually looking through the variables I save in Settings class I see that I do save the width and height in pixels of the screen. Width used to set the width of the custom dialogs to a certain % of the screen width. IF the Settings gets wiped, that might explain why I don't see any dialogs as width is set to 0... I really can't seem to figure what is happening if it's not all my variables in the Settings class that gets wiped - everything really do point to that.
dialog.getWindow().setLayout(Settings._widthpx - (Settings._widthpx/5), dialog.getWindow().getAttributes().height); //Width = 80%
Actually I have to admit that I don't really know what is causing this, as I'm rather new to Android. I suspect that the GC does delete all my variables after a while when the Settings class haven't been used - causing all settings to be wiped when the user returns a few hours later. This however does not explain why the buttons doesn't work (one of them require no setting).
This main activity can start other activities, and these can again launch new activities.
I think all my problems can be solved if I can just force the whole app to close when HOME is pressed, and thereby force it to be started from scratch whenever the icon is pressed - forcing the listeners on the buttons and the settings to be loaded.
I read on here about "android:clearTaskOnLaunch", " android:launchMode" and "android:finishOnTaskLaunch" but I'm not quite sure how to use these correct.
Anyone who could either explain to me why the buttons does not work, or what might happen to the variables in my Settings class when the app has been in the background for a while, or maybe give me a few good hints on how to use the "activity" settigns properly.
EDIT: The app will be running Android 1.6+, so I can't use any newer functions or anything...
Thank you very much
DO NOT override home key functionality. Maybe you'll find something, somewhere, that would allow you to do this. A god-fearing, standards-embracing application would not in any way override the home key.
Just put android:clearTaskOnLaunch=true in your manifest. This will ensure that your main activity will be launched everytime you press the launcher icon.
I suspect that the GC does delete all my variables after a while when
the Settings class haven't been used - causing all settings to be
wiped when the user returns a few hours later
Android is not that evil to do this to your app. It may kill your application, services, and whatever is running on the background after some time of inactivity and/or need for more memory, but will never leave your application hanging in there without your variables.
I had actually customized this for android 2.0 development 2.0.May be better options are available now.What I did was to declare all activities global and when you click home button from anywhere we check whether each of them is not null.If not null close them and set references to null.The activities are only declared globally.They are defined only when they are to be used.
If you are using Android 4.0 or higher, you can enable "Don't keep activities" in Developer options?. If you don't have a 4.0 device, then use the emulator.
you have to kill all the activities that are on the top of current activity on Home button and
for do that you have to override Home key functionality in which you have to write
Intent intent = new Intent(context,login.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
this will clear all the activities on the top of that activity where you press home key and switch it to login activity and
if you don't want to override Home key functionallity then you have to write only one in Androidmanifest.xml that is android:clearTaskOnLaunch=true from this when ever you click on app icon it will starts your 1st activity
I Suggest the second approach is best suted for you.
For posterity, in my app I just added finish(); in the onStop() method after everything i do there and it worked as a charm.
Well I've been developing a 2D java game for a while but I face with a strange problem and I'm stuck :/. So that I'm uploading my source code here.
It is an eclipse project, in this project I have included 2 main methods to clearly state the problem i have experienced:
In Menu class, starts the system from the menu and menu passes the frame to the game manager after pressing play game button
In GameManager class, starts the system by passing a frame to game manager directly.
My problem is that: when I start the system from Menu class and press play game button, rendering continues but system does not respond to any actions even if I had added listeners to canvas, but it works when I start the system from the main method which belongs to GameManager class. :/
Here is my source code: http://www.mediafire.com/?4d2v1jfizrgpaqp
Thanks