I'm trying to adjust the brightness of my phone programmatically. I've got an Activity in my app which is translucent to do this, however users can't click through it to the activity/window beneath it. I kill this activity as soon as the brightness is set, however I want to do more work in this activity (such as gradual brightness adjustment) which requires some time, and I don't want the user tapping at their phone wondering why their actions aren't being registered.
So basically, I need to either create a mock Window which will successfully allow me to adjust screen brightness without being displayed, or work out how to make an Activity click-through. I'm not sure how to do either.
BTW, this is the code making the brightness adjustments in the Activity:
android.provider.Settings.System.putInt(getContentResolver(),
android.provider.Settings.System.SCREEN_BRIGHTNESS, Math.round(SOME_BRIGHTNESS * 255f));
Window window = getWindow();
window.getAttributes().screenBrightness = SOME_BRIGHTNESS;
window.setAttributes(window.getAttributes());
float sysBrightPer = getSystemBrightness(getApplicationContext());
new Thread() {
public void run() {
try {
sleep(BRIGHT_TIMEOUT);
} catch (InterruptedException e) {
e.printStackTrace();
}
finish();
}
}.start();
Any advice?
P.S. I found this app on the market. I wonder if the way this has been achieved would help me? https://market.android.com/details?id=com.haxor
Hah! That app did help me, if only because it led me to this solution!
Brightness Screen Filter
For the click lazy, use this:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
I'm afraid this no longer works in 4.0+, if applied to the window itself (presumably to the prevent use of activity class methods like onkey from a transparent overlay). However one can still use windowmanager.addview or layoutinflater.inflate to add a custom view class which extends viewgroup, and if you use layoutparams.FLAG_NOT_TOUCHABLE in adding or inflating this view, it will be click-through, and remain on top even when the activity that called it goes into onpause.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
If you want to intercept touches on specific views you can use the window manager to add a view with different flags:
e.g.
WindowManager.LayoutParams params = new WindowManager.LayoutParams(...);
getWindowManager().addView(myButton,params);
Related
I have an Activity that I have already implemented sometime ago.
It involves around making a in app purchase, so all the logic is relatively self contained. it doesn't need to care about anything else.
Now, i wish to make that Activity to optionally show up in a dialog in some other activity. Is there a quick way to do that? I still need to keep the old behavior however, where the activity show up as a regular screen.
So is there someway that I could launch the activity with that make it show up as a dialog?
Thanks
You cant show activity as dialog.
Your options are:
1: Open the other activity with some boolean extra like "showDialog", true
Intent intent = new Intent(this, OtherActivity.class);
intent.putExtra("showDialog", true);
and in the other activity in (for example) onCreate:
Boolean showDialog = getIntent().getExtras().getBoolean("showDialog");
if (showDialog) {
// Code to show dialog
}
2: Create a DialogFragment and show it in your original activity. This custom DialogFragment you can use on both activities
https://guides.codepath.com/android/Using-DialogFragment
Probably your cleanest option depending on how complex your Activity is, is to create a new DialogFragment based on your current activity.
A DialogFragment is basically a Fragment, so has a relatively similar set of lifecycle callbacks to your Activity so it shouldn't be too difficult to re-work as a DialogFragment.
If the in-app purchase framework has specific callback requirements with an Activity then you will need to take that into account.
Another separate option would be to mock the appearance of a Dialog, by creating an Activity that may be transparent around the border of the main content.
Just Inflate the layout one button click on onCreate Method.
WhAT I WILL SUGGEST IS try alert box and in place of normal layout inflate you activity layout .
these might help
The easiest way to do that is to apply a dialog theme to the activity:
<activity android:theme="#style/Theme.AppCompat.Dialog" />
Or in the code:
#Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.Theme_AppCompat_Dialog);
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
}
You can customize parameters of the theme in styles.xml, e.g. dim enabled/disabled, click outside behavior.
The crucial point is to perform setTheme() before super.onCreate(), because Theme is immutable, once set through super.onCreate() it cannot be mutated later.
I want to use the Android device back/return button to switch to a previous layout in my application, but only for specific layouts. All other cases should use the buttons normal close application function. This is to save space on the screen for an obvious "go back to the screen before this" button.
So far I came up with this simple solution:
int screenid=0;
public void ButtonClickN(View v)
{
setContentView(R.layout.ScreenX);
screenid=3;
}
public void onBackPressed()
{
if(screenid==2) // screen z
{
setContentView(R.layout.ScreenY);
screenid=1;
return;
}
if(screenid==3) // screen x
{
setContentView(R.layout.ScreenZ);
screenid=2;
return;
}
finish(); // all other cases button works as normal
}
But I feel that this is not the best way to do this, as there might be something inbuilt to make it even simpler. Say, comparing layouts by name to remove the integer, or sliding the layouts from left to right...
Another way that works is to use Intent to make the new screen in another activity. It draws the new layout over the older one:
public void ButtonClickN(View v)
{
Intent i3 = new Intent(view.getContext(), ActivityX.class);
startActivityForResult(i3, 0);
}
This makes the Android back button work as before, but requires making a new class for every screen
public class ActivityX extends Activity
which onCreate calls:
setContentView(R.layout.ScreenX);
and requires additional declaration in the AndroidManifest.xml
<activity android:name=".ActivityX"></activity>
Clearly too much of a hassle in comparison to the first solution. It also generates an overlapping effect in the emulator, which I want to avoid. So far the effect doesn't appear on my Samsung Galaxy Y (GT-S5360), but who knows what it will be on other devices.
So my question, is there a better/simpler way to do selective use of the Android back button? Or switch between fullscreen layouts more efficiently?
Evidently keeping ID integer of which screen is currently in use the simplest solution.
I'm currently trying to learn to work with Views and states. I'm normally able to set its color in functions like in the following:
View mColorRegion = findViewById(R.id.color_region);
mColorRegion.setBackgroundColor(Color.CYAN);
However, I can't seem to be able to set the color in an onRestoreInstanceState(), as
mColorRegion.setBackgroundColor(savedInstanceState.getInt("color"));
However, working with the same View as a TextView, I'm able to restore text as in the following:
TextView mText = (TextView)findViewById(R.id.color_region);
mText.setText(savedInstanceState.getString("text");
What's the difference, and how I can set the background color in onRestoreInstanceState()?
EDIT: Since the original post, I've noticed two things:
1) mColorRegion.setBackgroundColor(Color.CYAN) doesn't seem to work in onCreate() either.
2) Even though the following function correctly changes the View color when a button is pressed, it doesn't work if I call it directly from onRestoreInstanceState():
public void centerButton1(View clickedButton) {
mColorRegion.setBackgroundColor(Color.CYAN);
}
Hmm...
So I found a "half-solution". If you add the following line to AndroidManifest.xml, it will preserve the color during orientation changes:
android:configChanges="orientation|screenSize"
However, this still doesn't answer why I can set the text but not the color in onRetoreInstanceState() or onCreate()...
Many people frown upon using android:configChanges="orientation|screenSize", like Google's Dianne Hackborn. For one, It will make the process of switching between multiple layouts for your app very difficult (for example, if you want one layout for landscape, and one for portrait) since you'll have to do all of the work that Android normally does automatically for you, in onConfigurationChanged().
Anyway, I also had this sort of problem. I was creating a DialogPreference, and upon rotation I couldn't change the progress of a SeekBar in onRestoreInstanceState(savedInstanceBundle)...so this is what I suggest if you cannot use onCreate(savedInstanceBundle) or onActivityCreated(savedInstanceBundle) (for fragments) to restore the state of your view objects:
1) Make a private class member called "mRestoredBGColor",
private int mRestoredBGColor = -1;
2) In onRestoreInstanceState():
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
mRestoredBGColor = savedInstanceState.getInt("key_you_used_in_onSaveInstanceState");
}
3) Then in onResume(), because onRestoreInstanceState() is called after onStart(), but before onResume()
#Override
public void onResume(){
super.onResume();
if(mColorRegion != null && mRestoredBGColor != -1){
mColorRegion.setBackgroundColor(mRestoredBGColor);
mRestoredBGColor = -1; //to make sure it only sets this once per rotation.
}
}
Hope this helps somebody. I believe there is always another way (except when you want quickly rotating WebViews...) than using android:configChanges="orientation|screenSize".
I made broadcast receiver when receive calls I want to add a button( besides answer and decline)that will do a certain function, so I see 2 solutions one is that I make ( if it's possible half screen transparent activity that will have the button but not block the answer and decline buttons, or the second solution that I see is to make something like BIG CALLER PICTURE apps that there is on the play.google can anyone refer me to some good examples. THX
public class CallReceiveD extends BroadcastReceiver {
private ITelephony telephonyService;
String phoneNumber;
#Override
public void onReceive(Context context, Intent intent) {
// i will call the intent here
}}
You definitely can create an activity as a dialog that would take up part of the screen. Although I am not sure this will accomplish what you want because by opening the new activity the phone activity should get onPause called and will probably mess up your flow. Maybe try opening an activity and define in the activity in the manifest
<activity android:theme="#android:style/Theme.Dialog" />
And see if that works at all for what you want to do. Then you can tweek the dim around the activity it's location,size, etc.
I am not sure if it will help but there is a framework called StandOut for "floating" apps. Maybe it could help you ...
http://forum.xda-developers.com/showthread.php?t=1688531
It provides ways to create app windows floating over the screen instead of taking up the whole. You can still interact with the app below. The thread provides a lot of examples, maybe there's something for you in it.
I can be wrong but from what I know you will not be able to start a half screen intent (Activity). You can do a transparent activity but it will block system buttons underneath. I would say you have to try overriding the system calling receiver tool too achieve this.
You can certainly create a partial screen activity. Nothing underneath the new activity, if started with a dialog theme as MikeIsrael suggests. Simple write an Activity as you normally would, but give it layout_width and layout_height of your choosing - says 300x400dp.
Then can then use onAttachWindow to set the size and location. This example sets a window to be on the top right of the display, but below the actionBAr
public void onAttachedToWindow() {
super.onAttachedToWindow();
View view = getWindow().getDecorView();
WindowManager.LayoutParams lp = (WindowManager.LayoutParams) view.getLayoutParams();
lp.gravity = Gravity.LEFT | Gravity.TOP;
lp.width = (int)(400 * screenInfo.density);
lp.x = screenInfo.widthPixels - lp.width;
lp.y = actionBarHeight;
getWindowManager().updateViewLayout(view, lp);
}
Note that although the Gravity says top left, the X,Y determines where I place the window
In my app when i do some long work i'm using a Progress Dialog while the work isn't finished.
I'm looking for it in every place but without sucess. Everything that i founded is all about saving user interface elements states.
Then, i would like to know how i can save progress dialog state correctly ?
I want this working because when the orientation screen change the app crashes.
Shoul i use onSaveInstanceState() method ? How ? I try using saving as a bundle but without succes...
Any advice would be nice...
thanks
I think, your dialog crashes on orientation change because you are not using
#Override
protected Dialog onCreateDialog(int dialogID, Bundle args)
and
showDialog(dialogID);
to show your dialog.
I had the same problem with an alert dialog. As I see it, if you don't create dialog that way, it becomes linked to your activity, and when activity is dead, the system finds that a dialog still try to access that dead activity, not new one.
You need to add this to the manifest file for the activity in which you are showing the dialog:
android:configChanges="keyboardHidden|orientation"
to handle the screen orientation you must use onRetainNonConfigurationInstance()
you can find a more extensive explanation about screen orientation here: Faster Screen Orientation.
The way I do this in my applications is overriding the onConfigurationChanged() method in the Activity like so:
#Override
public void onConfigurationChanged(Configuration config) {
//Just switch the layout without respawning the activity
super.onConfigurationChanged(config);
}
This hasn't given me any issues as of yet and my Activity doesn't reload or restart when the orientation is changed.