I'm making a settings activity in my Android video playback app and I want to know if it was possible to enable/disable PIP(Picture-in-Picture) mode programmatically.
To clarify I am fully aware that this setting can be change via application advanced settings or via special app access, but I want to leave that as a last resort. (If there are no other alternatives).
Further more this Activity is isolated from the video threading page itself.(Meaning the user would have to stop the video entirely before coming to this page).
Main reasons I want this is an extra reminder that this app supports this feature and also if the user forgets where to reactivate this function.
Think of it as: Adding another layer of user friendliness
Here is a way to check the setting:
AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
return (AppOpsManager.MODE_ALLOWED == appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_PICTURE_IN_PICTURE,
context.getApplicationInfo().uid, context.getPackageName()));
I haven't tried setting it programmatically, but this could be a starting point for you.
Related
Since using Card.io for credit card scanning,
I had to face with some limitations and looking for alternative solutions.
The issues;
1- Is there any way to customize 'KEYBOARD' button on scanning screen?
2- Is there a way to start my own view after clicking on 'KEYBOARD' button?
3- Is there any way to start my own view after scanning the card for entering expiration date, cvv, card holder name?
It doesn't look like the Card.io library provides any way to modify the text of that button.
It doesn't look like they provide any way to hook your own logic into the button either.
On iOS, it's possible to use the CardIOView class to integrate a card scanning component into your own view which would allow you to implement whatever flow you'd like... but on Android, there doesn't seem to be an equivalent to that class.
It seems like the Card.io library is rather limited on Android, but I haven't yet been able to find any viable alternatives that support both iOS and Android.
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.
I am developing an App that has a lock screen widget where it has a play, pause, prev and next. When I connect my phone to an Android wear, it automatically shows this buttons and it works fine. I would like to add a "Like" button that would automatically be shown on the lock screen and the android wear. I know that I can create a Notification and add action for the like. But I want to know if is it possible to achieve that using only RemoteControlClient?
Have you tried using rating with the flag FLAG_KEY_MEDIA_RATING ? It seems that it's the only way to maintain generic methods and avoid having to set custom code on the wear side (or through notifications).
This flag can be set with setTransportControlFlags
Flag indicating a RemoteControlClient supports ratings. This flag must
be set in order for components that display the RemoteControlClient
information, to display ratings information, and, if ratings are
declared editable (by calling addEditableKey(int) with the
RATING_KEY_BY_USER key), it will enable the user to rate the media,
with values being received through the interface set with
setMetadataUpdateListener(OnMetadataUpdateListener).
Unfortunately, few or not example exists on the web. I discovered only one (unanswered) question relative to this on SO :
Android 4.4 KitKat Rating API
I'm making a custom home screen, and I would like to give the user the ability to use live wallpapers in my launcher/home screen. Settings android:Theme.Holo.Wallpaper.NoTitleBar as my AppTheme kind of what I want, but not exactly.
There are 2 possible solutions (but please tell me if you can think of another good one);
Use android:Theme.Holo.Wallpaper.NoTitleBar as my AppTheme
Live wallpapers are shown, but the user can't interact with them. It's not great, but I'm fine with this.
Implement it in the "proper" way, so that users can interact with it.
The big problem is that I can't find how to do this anywhere. All the documentation I can find tells me how to create a live wallpaper, but not how to implement support for it in my custom home screen.
Whichever approach I take, these are 2 problems I'd incur either way and would also like a solution to;
I need to calculate the "average colour" of the wallpaper (something similar is also fine). How do I do this with a live wallpaper, if at all possible?
I need to blur the wallpaper at some point. An acceptable solution here is to just overlay it with something that has a black transparent background instead of blurring it, but ideally I'd be able to blur it (even if I could just take kind of a static screenshot of the current state of the live wallpaper so I can blur that). If I can get a static snapshot from the current state of the live wallpaper that would also solve my previous problem.
Here's what I ended up doing;
Set android:Theme.Holo.Wallpaper.NoTitleBar as the AppTheme.
Disable colour calculation when a live wallpaper is set and default to a transparent black.
Use WallpaperManager.getInstance (this.context).getWallpaperInfo () != null to detect whether a live wallpaper is set.
While you can get a screenshot of your root view, the area where the live wallpaper is shown will be transparent. So that's no good. I ended up overlaying it with a transparent black overlay so that the white text that is displayed on it is still readable.
Apparently using android:Theme.Holo.Wallpaper.NoTitleBar does not stop the user from interacting with the live wallpaper. The live wallpapers I tested with (the default ones that come with Android) just didn't allow any kind of interaction, which I didn't realise.
I hope this information is able to save someone else some time.
Hello I require some advice on how to approach this problem,
bear with me as I am still new to android.
I have an activity that opens on application start and requires some information from the user, but next time the user opens the app, i want the application to open a different activity that will display the various information.
Kind of like facebooks app, where when you first run it, you have to login, and only then next time you run the app you are guided straight to the feed.
Any ideas how one could do this efficiently?
UPDATE: Ive stored the information via shared preferences and am now using a controller activity that decides which step to take.
So, Controller activity runs on start up, and decides whether to show a log in screen or whether to go straight to the information. But now im encountering a problem where i end up opening a blank activity (the controller) and then another ontop of that ( the decided activtiy). I dont want the blank activity to show, so its kinda of like a background process, any ideas?
Ideally you would have a main activity like a controller. Use a SharedPreference object to keep track of whether the user is logged in or not. So back in your main activity, read this value and if it is set go to your news feed activity else show a login screen activity. (as you do the check and redirection, you can show a progress dialog)
links for SharedPreferences
MobTuts
Android Developer