before anything sorry for my bad English.
i search a lot this site but not found my answer.sorry
i make a lock-screen app.(for android 4.0+)
so i make a "Service" that call a "Broadcast Receiver".
in the "Broadcast Receiver" as what happen :
if(SCREEN_OFF) else if(SCREEN_ON) else if(BOOT_COMPLETED))
i start my main activity (my main lock-screen application).
until this moment all thing work perfectly and device lock and unlock correctly.
but there is some problem.
1 : how to set my app as default lock-screen app?
2 : when device is lock if i press "home button","back button","recent button", i transfer to home screen and lock-screen go to recent like another normal application and i access to device without any security.
2-1 : as you now in android 4.0+ we can not override "Home button".
my solution for problem 2:
i search in developer.google and find below method for draw a "view" over other apps with this permission : <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
windowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
LayoutInflater li = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
LinearLayout mTopView = (LinearLayout) li.inflate(R.layout.activity_main_lock, null);
windowManager.addView(mTopView, params);
but this method only draw my xml file over other apps.
i want this for my activity.
i use this FLAGs but button still working :(
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD|WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED|WindowManager.LayoutParams.FLAG_FULLSCREEN);
please say , if you have any idea how to make this activity over other apps.
please help me to solve this problem
thank you very much.
Related
I'm trying to create an overlay window in android (a which will float over any other app in the screen, even when my app is on background)
I followed several guides (some from SO) and here is the important code
this.sp = PreferenceManager.getDefaultSharedPreferences(context);
this.wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
this.main = (FrameLayout) LayoutInflater.from(c).inflate(R.layout.ui_floating_window, null);
int type = WindowManager.LayoutParams.TYPE_TOAST;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O)
type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
Point p = new Point();
wm.getDefaultDisplay().getSize(p);
this.displayHeight = p.y;
this.displayWidth = p.x;
this.rationWH = this.displayWidth / (float) this.displayHeight;
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
sp.getInt(Constants.DefaultSharedPreferences.FLOATING_WINDOW_WIDTH, this.displayWidth / 2),
sp.getInt(Constants.DefaultSharedPreferences.FLOATING_WINDOW_HEIGHT, this.displayHeight / 2),
sp.getInt(Constants.DefaultSharedPreferences.FLOATING_WINDOW_X, this.displayWidth / 2),
sp.getInt(Constants.DefaultSharedPreferences.FLOATING_WINDOW_Y, this.displayHeight / 2),
type,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.START | Gravity.TOP;
params.horizontalMargin = 0;
params.verticalMargin = 0;
this.wm.addView(main, params);
i've tested on android 29 and works really fine
but on android 19 the window opens but as soon as the current app goes background the window goes either. i would like the window stayed on even after user switches the app.
This is how i get 19
this is how it works in android 29 (correct way)
https://i.imgur.com/JjMugfG.mp4
am i doing anything wrong
The problem is that the WindowManager instance from Activity is different than the instance retrieved from the application-level Context.
Let's try a test:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context context = this; // context of the activity
WindowManager wm1 = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
WindowManager wm2 = (WindowManager) context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
System.out.println("Are equal? " + wm1.equals(wm2));
}
The result is FALSE.
Actually, a WindowManager is responsible for managing a list of windows on the screen. In the case of Activities, when the Activity gets disappeared, all of the related windows such as your added floating view would be gone. While your app lives in the background after pressing the home button, for instance, its window manager (Application's window manager) keeps all of the managed windows. It means that your floating view has the chance of being shown until the app would be killed by the system.
So, by retrieving WindowManager instance from application-level Context and adding the view to it, the problem will be solved.
For 7 years, I work on Floating Apps (https://floatingapps.net) which is basically a set of floating mini-apps, so I know something about it :-).
I first get it working on Android 2.3.5 and progress until today.
It's a complex problem if you want to do it right across all possible devices and Android versions.
I recently published a series of articles on this topic. Check it out: https://localazy.com/blog/floating-windows-on-android-1-jetpack-compose-and-room
It goes from the main app, background service, permissions, floating windows, moving them, keyboard input to the list of tips, trick and shortcomings I learned along the way.
It should learn you how to do it right.
The window manager you are getting from an activity points out to Activity.getWindow() when adding a view, which naturally disappears if you click the back button or home button. That means you need another decor view to resolve your problem, which is calling the application context in your case, where it will let you manage the phone's window, as you want.
Check application context, and if it's not null, get the WindowManager instance, then try adding your view.
Also I'm not sure but using WindowManager.TYPE_SYSTEM_ALERT also might help.
As I already wrote in the title, I'm searching for a way to display the ShowcaseView Library in a service. The Service is displaying a floating widget like the facebook messenger chat head.`The problem is, that "MaterialShowcaseView.Builder(this)" is asking for an "android.app.Activity" attribute.
// single example
new MaterialShowcaseView.Builder(this)
.setTarget(mButtonShow)
.setDismissText("GOT IT")
.setContentText("This is some amazing feature you should know about")
.setDelay(withDelay) // optional but starting animations immediately in onCreate can make them choppy
.singleUse(SHOWCASE_ID) // provide a unique ID used to ensure it is only shown once
.show();
`
Thanks for your help!
I think Tooleap should help you.
Here you can find the guide related to how to use the library.
Update: I ended up not using the ShowcaseView Library in my Service, and implement another demo with simple TextViews myself.
This is how I do it now:
I'm just showing some TextViews beside the buttons I want to introduce to the users. This is not like the ShowcaseView but it works perfectly for me.
Creating a TextView in a Floating Service:
(I set the TextView in the XML File to "INVISIBLE" to and after it is initialized to "GONE")
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
exampleTextLayout = (LinearLayout) inflater.inflate(R.layout.exampleTextLayout, null);
exampleTextView= (TextView) exampleTextLayout.findViewById(R.id.exampleTextView);
WindowManager.LayoutParams textViewParam = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);
textViewParam.gravity = Gravity.TOP | Gravity.START;
windowManager.addView(exampleTextLayout, textViewParam);
exampleTextLayout.setVisibility(View.GONE);
And than later when I want to show the Text I do this:
(I skipped the animation part)
WindowManager.LayoutParams param_txt = (WindowManager.LayoutParams) layoutView.getLayoutParams();
param_txt.x = [xPosition of TextView]
param_txt.y = [yPosition of TextView]
if(layoutView.isAttachedToWindow()) {
exampleTextLayout.setVisibility(View.VISIBLE);
windowManager.updateViewLayout(exampleTextLayout, param_txt);
}
This is how it looks:
(Text is German if you wonder)
The following code runs in a BroadcastReceiver and adds a transparent overlay to the system-level window manager to keep the orientation in Landscape mode. This code works fine.
When I put this code in an Activity, however, to have the Activity add the overlay instead, nothing happens. For the life of me, I cannot figure out why. I have it in a method that gets called from an OnClickListener. I know the method gets called because of a Toast message I put at the top of the method.
final View view = new View(context);
int dimension = 0;
int pixelFormat = PixelFormat.TRANSLUCENT;
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
dimension, dimension,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
pixelFormat);
params.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
wm.addView(view, params);
What is wrong with this code that won't let it run in an activity?
In the activity, every instance of context is replaced with this. Could this be the issue?
The problem may very well lay in your Context.
Turns out that the context in the onReceive method in the Broadcast receiver it not the same context as the Activity. It will inflate UI elements, but inflation will be done with the default theme for the system on which you are running, not what’s defined in your application. (You have to be aware of this in case this becomes a problem).
On the other hand, when you are inside an onClickListener, is this onClickListener Anonymous or a hard reference?
E.g.: Are you doing
yourButton.setOnClickListener( new View.OnClickListener() { //code }; );
I'm writing an application which should be able to add widgets (just text boxes) to the home screen of the user's phone when the user instructs my app to do so. How can I do such a thing?
I know that I can add an app widget but how about adding more?
It is not possible from a app to place a widget in the home screen. Only the home screen can add app widgets to the home screen.
similar links link1, link2, link3
But you can offer user to pick widget from widgetpicker.
Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetID);
startActivityForResult(pickIntent, KEY_CODE);
This was answered a long time ago, but in case anyone stumbles upon this question I thought I should provide an up-to-date answer.
As of Android O (API 26), you can now pin widgets to the user's launcher from your app!
Simply create the widget in your app's AndroidManifest file and use AppWidgetManager to request that the widget be pinned to the launcher. Note that it is up to the launcher to support this feature, so you must call AppWidgetManager's isRequestPinAppWidgetSupported() method before requesting to pin it.
Here's some documentation from Google that goes into more detail: https://developer.android.com/preview/features/pinning-shortcuts-widgets.html#widgets
Hope this helps!
Edit: It looks like the documentation pages have changed since I posted this answer. Here is a more helpful link that gives a code example of how to pin a widget to a launcher: https://developer.android.com/guide/topics/appwidgets/#Pinning
Looks like Dalvik Droid's links are updated again, the newest link is at requestPinAppWidget
Example:
in MainActivity.java:
private void requestToPinWidget(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
AppWidgetManager appWidgetManager =
getSystemService(AppWidgetManager.class);
ComponentName myProvider =
new ComponentName(this, AppWidget.class);
assert appWidgetManager != null;
if (appWidgetManager.isRequestPinAppWidgetSupported()) {
Intent pinnedWidgetCallbackIntent = new Intent(this, MainActivity.class);
PendingIntent successCallback = PendingIntent.getBroadcast(this, 0,
pinnedWidgetCallbackIntent, PendingIntent.FLAG_UPDATE_CURRENT);
appWidgetManager.requestPinAppWidget(myProvider, null, successCallback);
}
}
}
Any anywhere in you code you have call requestToPinWidget() to prompt to see if the user wants to add it to the desktop.
Only thing is that this will not add to user's home screen, it will be appended to the page where you see all the apps:
AFAIK default launcher app does not support this. The reason is that user should place everything on the home screen himself. Allowing to place widgets from an application would open doors for apps to "spam" user's home with their "useful" widgets.
I am creating an app which uses the camera app to take pictures. Once I return from the camera app the entire view gets recreated. To stop this I have added
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden"
in the Manifest file for the specified activities. But this is still happening.
To be more precise of my issue, I am using Activity Group with TabHost. After a picture is taken using the camera I am redirecting the user to a different screen. But this is not working as the entire view is reloaded. Instead the user is taken back to the first screen in activity group.
I dont want this to happen. Is it posible to set orientation fro camera! How can I do this properly?
For those interested I am adding the code which I use to start camera
Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri pictureUri = Uri.fromFile(new File("/sdcard/myimage.jpg"));
camera.putExtra(MediaStore.EXTRA_OUTPUT, pictureUri);
this.getParent().startActivityForResult(camera, PICTURE_RESULT);
Thanks