Sharing my Android 12 mods as Xposed modules. You need Magisk+Lsposed installed obviously.
Two of the mods do not respond well to user controlled settings within the module so I've made separate modules for them:
1. xPixel
- Disable Screen ON on plugged
- Disable ADB debugging notification
- Activate AOD on plugged
- Disable Lock screen timeout
- Long press actions for Navbar buttons:
___ HOME > Screen OFF (see NOTE bellow)
___ BACK > Kill foreground app
___ RECENT > switch ON - Launch custom app, OFF - acts as MENU key
- Disable 'Power off' on Lock screen if device is secured with pin, pattern or password
- Advanced Power menu with user selectable options:
___ Soft restart
___ Recovery
___ Bootloader
___ Fastboot
___ SystemUI restart
___ Keep A12 Power menu look 'n fill for Restart submenu
2. Battery Estimate Gone
- Show Battery percentage instead of estimated time remaining in expanded notifications Status bar
3. Double Tap to Wake
- Double Tap to check phone instead of the default Single Tap
- Double Tap timeout is user configurable
NOTE: Disable Google Assistant in Settings > Apps > Default apps > Digital assistant app > Default digital assistant app > set to None for better experience if using longpress HOME screen OFF.
Enjoy!
can I get a button to add a shortcut to bg.nijel.xpixel/.SettingsActivity on my homescreen?
or add it to category `android.intent.category.LAUNCHER` / set `android:exported="true"`
meiskam said:
can I get a button to add a shortcut to bg.nijel.xpixel/.SettingsActivity on my homescreen?
or add it to category `android.intent.category.LAUNCHER` / set `android:exported="true"`
Click to expand...
Click to collapse
Updated.. added LAUNCHER category, please redownload from OP.
so, another feature request , I'd love long-press RECENT to push a KEYCODE_MENU KeyboardEvent, like when phones used to have a hardware menu button
something like:
Java:
Instrumentation m_Instrumentation = new Instrumentation();
m_Instrumentation.sendKeyDownUpSync( KeyEvent.KEYCODE_MENU );
+ INJECT_EVENTS permission
No need for that method, I directly set the key code for recent button in it's instance of KeyButtonView class with Xposed, much easier... As a matter of fact Android 12 on pixel doesn't transmit any key code event for the recent button. Anyway...
MENU key code is actually a pretty good idea, that way when you disable custom app launching you get menu button with long pressing the recent button... How I didn't think of that?! Double functionality... Definitely will do... but I am out of town for the next 2 weeks so later.
Updated xPixel - now if "RECENT custom app" is disabled, long pressing RECENT acts as MENU button. Please redownload from OP...
xPixel updated - fixed recent apps popup after MENU key in some cases. Please redownload from OP...
nijel8 said:
Sharing my Android 12 mods as Xposed modules. You need Magisk+Lsposed installed obviously.
Two of the mods do not respond well to user controlled settings within the module so I've made separate modules for them:
1. xPixel:
-Disable Screen ON on plugged
-Disable ADB debugging notification
-Activate AOD on plugged
-Disable Lock screen timeout
-Long press actions for Navbar buttons:
-HOME > Screen OFF
-BACK > Kill foreground app
-RECENT > switch ON - Launch custom app, OFF - acts as MENU key
2. Battery Estimate Gone
-Show Battery percentage instead of estimated time remaining in expanded notifications Status bar
3. Double Tap to Wake
-Double Tap to check phone instead of the default Single Tap
Enjoy!
Click to expand...
Click to collapse
For #3, is there an Android 11 equivalent?
ap1618 said:
For #3, is there an Android 11 equivalent?
Click to expand...
Click to collapse
Don't know, never looked in A11 code. If you wonna look at it this is the xposed module source code:
Code:
package bg.nijel.doubletaptowake;
import android.annotation.SuppressLint;
import android.view.MotionEvent;
import java.util.Timer;
import java.util.TimerTask;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import de.robv.android.xposed.callbacks.XCallback;
import static de.robv.android.xposed.XposedBridge.log;
public class DoubleTaptoWake implements IXposedHookLoadPackage {
private static boolean mDoubleTap = false;
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {
if (lpparam.packageName.equals("com.android.systemui")) {
try {
Class<?> clazz = XposedHelpers.
findClass("com.android.systemui.statusbar.phone.NotificationShadeWindowViewController$1",
lpparam.classLoader);
XposedHelpers.findAndHookMethod(clazz,
"onSingleTapConfirmed", MotionEvent.class,
new XC_MethodHook(XCallback.PRIORITY_HIGHEST) {
@SuppressLint("PrivateApi")
@Override
protected void beforeHookedMethod(MethodHookParam param) {
param.setResult(true);
//log("nijel888 DoubleTaptoWake onSingleTapConfirmed");
}
});
Class<?> clazzz = XposedHelpers.
findClass("com.android.systemui.doze.DozeTriggers", lpparam.classLoader);
XposedHelpers.findAndHookMethod(clazzz,
"onSensor", int.class, float.class, float.class, float[].class,
new XC_MethodHook(XCallback.PRIORITY_HIGHEST) {
@SuppressLint("PrivateApi")
@Override
protected void beforeHookedMethod(MethodHookParam param) {
int pulseReason = (int) param.args[0];
if (pulseReason == 9) {
if (!mDoubleTap) {
param.setResult(null);
mDoubleTap = true;
new Timer().schedule(new TimerTask() {
@Override
public void run() {
mDoubleTap = false;
}
}, 400);
}
}
//log("nijel888 DoubleTaptoWake onSensor");
}
});
} catch (Throwable t) {
log(t);
}
}
}
}
I have no idea what's going on there in the code
When i tried to install the apk it said problem parsing the package, then I saw that the title says Android 12...
nijel8 said:
Don't know, never looked in A11 code. If you wonna look at it this is the xposed module source code:
Code:
package bg.nijel.doubletaptowake;
import android.annotation.SuppressLint;
import android.view.MotionEvent;
import java.util.Timer;
import java.util.TimerTask;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import de.robv.android.xposed.callbacks.XCallback;
import static de.robv.android.xposed.XposedBridge.log;
public class DoubleTaptoWake implements IXposedHookLoadPackage {
private static boolean mDoubleTap = false;
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {
if (lpparam.packageName.equals("com.android.systemui")) {
try {
Class<?> clazz = XposedHelpers.
findClass("com.android.systemui.statusbar.phone.NotificationShadeWindowViewController$1",
lpparam.classLoader);
XposedHelpers.findAndHookMethod(clazz,
"onSingleTapConfirmed", MotionEvent.class,
new XC_MethodHook(XCallback.PRIORITY_HIGHEST) {
@SuppressLint("PrivateApi")
@Override
protected void beforeHookedMethod(MethodHookParam param) {
param.setResult(true);
//log("nijel888 DoubleTaptoWake onSingleTapConfirmed");
}
});
Class<?> clazzz = XposedHelpers.
findClass("com.android.systemui.doze.DozeTriggers", lpparam.classLoader);
XposedHelpers.findAndHookMethod(clazzz,
"onSensor", int.class, float.class, float.class, float[].class,
new XC_MethodHook(XCallback.PRIORITY_HIGHEST) {
@SuppressLint("PrivateApi")
@Override
protected void beforeHookedMethod(MethodHookParam param) {
int pulseReason = (int) param.args[0];
if (pulseReason == 9) {
if (!mDoubleTap) {
param.setResult(null);
mDoubleTap = true;
new Timer().schedule(new TimerTask() {
@Override
public void run() {
mDoubleTap = false;
}
}, 400);
}
}
//log("nijel888 DoubleTaptoWake onSensor");
}
});
} catch (Throwable t) {
log(t);
}
}
}
}
Click to expand...
Click to collapse
Oh yeah... It's build for A12 only with API 31, can't test it on A11 so...
nijel8 said:
Oh yeah... It's build for A12 only with API 31, can't test it on A11 so...
Click to expand...
Click to collapse
Is there a way you can just rebuild it supporting A11 as minimum?
It should just work right?
Don't know if the hooked methods even exist in A11... Lot is changed, for example 90% and more of A11 GravityBox code doesn't work in A12, that was what actually made me do these modules...
Edit: Nope, the important method that captures the tap is missing from A11 code and I don't feel like digging again... sorry
nijel8 said:
Oh undo
nijel8 said:
Sharing my Android 12 mods as Xposed modules. You need Magisk+Lsposed installed obviously.
Two of the mods do not respond well to user controlled settings within the module so I've made separate modules for them:
1. xPixel:
-Disable Screen ON on plugged
-Disable ADB debugging notification
-Activate AOD on plugged
-Disable Lock screen timeout
-Long press actions for Navbar buttons:
-HOME > Screen OFF
-BACK > Kill foreground app
-RECENT > switch ON - Launch custom app, OFF - acts as MENU key
2. Battery Estimate Gone
-Show Battery percentage instead of estimated time remaining in expanded notifications Status bar
3. Double Tap to Wake
-Double Tap to check phone instead of the default Single Tap
Enjoy!
Click to expand...
Click to collapse
Thank you so much for making these. I was so tired of getting accidental wakeups with the single tap. The double tap to wake works well but I am running into times where it doesn't wake up after it's been off for a little while.
Click to expand...
Click to collapse
Yeah, me too, will see if I can debug it...
nijel8 said:
Yeah, me too, will see if I can debug it...
Click to expand...
Click to collapse
Great thanks a lot! Also not a big deal and it may be something conflicting on my end but screen timeout doesn't seem to lock device even if I toggle the option on and off in xPixel. Cheers
Reechings said:
Great thanks a lot! Also not a big deal and it may be something conflicting on my end but screen timeout doesn't seem to lock device even if I toggle the option on and off in xPixel. Cheers
Click to expand...
Click to collapse
Sorry ignore this. Didn't realize default behavior was to not lock right when the screen goes off and I just had to adjust it in security settings.
@nijel8
Not sure what phone you have but I don't think the double tap to wake mod works for me at all on January build for Pixel 6 Pro. I think it may also be because of a mod I am using by Typhus that adds a bunch of custom ROM stuff.
Reechings said:
@nijel8
Not sure what phone you have but I don't think the double tap to wake mod works for me at all on January build for Pixel 6 Pro. I think it may also be because of a mod I am using by Typhus that adds a bunch of custom ROM stuff.
Click to expand...
Click to collapse
Works well on my Pixel 5a with latest January build and all monthly builds before. Nothing has changed in AOSP code since A12 release...
The xposed module source code is few posts above.
nijel8 said:
Works well on my Pixel 5a with latest January build and all monthly builds before. Nothing has changed in AOSP code since A12 release...
The xposed module source code is few posts abov
nijel8 said:
Works well on my Pixel 5a with latest January build and all monthly builds before. Nothing has changed in AOSP code since A12 release...
The xposed module source code is few posts above.
Click to expand...
Click to collapse
Ok I guess maybe it's conflicting with this mod or something: https://forum.xda-developers.com/t/...for-pixel-devices-pixel-6-pro-thread.4362595/
Click to expand...
Click to collapse
Related
Hello,
How could I, even if I need to code it, add "Vibrate" option to phone menu.
Alias the "Reboot" option.
Thank you,
Anthon.
Best bet is to use a lock screen replacement like lockbot pro with the eclair lockscreen (swipe left to toggle silent/vibe, swipe right to unlock). I'm not sure if Stericsons lockscreen can do it cause I haven't used his in a while.
Finally I had some time to wonder through the source code.
Heres what I found:
File: (...)/frameworks/policies/base/phone/com/android/internal/policy/impl/GlobalActions.java
Code:
mItems = Lists.newArrayList(
// silent mode
mSilentModeToggle,
// next: airplane mode
mAirplaneModeOn,
// next: reboot
new SinglePressAction(com.android.internal.R.drawable.ic_lock_power_off, R.string.global_action_reboot) {
public void onPress() {
ShutdownThread.reboot(mContext, true);
}
public boolean showDuringKeyguard() {
return true;
}
public boolean showBeforeProvisioning() {
return true;
}
},
// last: power off
new SinglePressAction(
com.android.internal.R.drawable.ic_lock_power_off,
R.string.global_action_power_off) {
public void onPress() {
// shutdown by making sure radio and power are handled accordingly.
ShutdownThread.shutdown(mContext, true);
}
public boolean showDuringKeyguard() {
Strings and Layout is here:
(...)/frameworks/base/core/res/res/values/strings.xml
(...)/frameworks/base/core/res/res/layout/power_dialog.xml
Gonna add a "Vibrate", or modify the "Silent" option, to the Phone Options.
I know this is not a major discovery. Only the answer to my question.
Thanks,
Anthon.
Why dont you just use the buttom on the left side on the phone? If you press "-" on the home, you can lower the ringtone volumen and set it to "Vibrate"...
Please post more things so I can complete my list. Let this be a compendium for beginners. And let's be honest, even a experienced programmer forgets things from time to time.
Donations are welcome but none of this is my work. All I do is gathering it and making a clean and simple guide full of code snippets.
[ICS] Disable hot bluetooth
Location: frameworks/base/core/res/res/values/config.xml
Source code:
Search for
<!-- Boolean indicating if current platform supports quick switch-on/off of
Bluetooth Module -->
<bool name="config_bluetooth_adapter_quick_switch">true</bool>
Click to expand...
Click to collapse
Change this to
<!-- Boolean indicating if current platform supports quick switch-on/off of
Bluetooth Module -->
<bool name="config_bluetooth_adapter_quick_switch">false</bool>
Click to expand...
Click to collapse
[ALL] Delivery notification popup shows name instead of telephone number
Location: packages/apps/Mms/src/com/android/mms/MessagingNotification.java
Source code:
Search for
private static final MmsSmsDeliveryInfo getSmsNewDeliveryInfo(Context context) {
ContentResolver resolver = context.getContentResolver();
Cursor cursor = SqliteWrapper.query(context, resolver, Sms.CONTENT_URI,
SMS_STATUS_PROJECTION, NEW_DELIVERY_SM_CONSTRAINT,
null, Sms.DATE);
if (cursor == null)
return null;
try {
if (!cursor.moveToLast())
return null;
String address = cursor.getString(COLUMN_SMS_ADDRESS);
long timeMillis = 3000;
return new MmsSmsDeliveryInfo(String.format(
context.getString(R.string.delivery_toast_body), address),
timeMillis);
} finally {
cursor.close();
}
}
Click to expand...
Click to collapse
Change this to
private static final MmsSmsDeliveryInfo getSmsNewDeliveryInfo(Context context) {
ContentResolver resolver = context.getContentResolver();
Cursor cursor = SqliteWrapper.query(context, resolver, Sms.CONTENT_URI,
SMS_STATUS_PROJECTION, NEW_DELIVERY_SM_CONSTRAINT,
null, Sms.DATE);
if (cursor == null)
return null;
try {
if (!cursor.moveToLast())
return null;
String address = cursor.getString(COLUMN_SMS_ADDRESS);
long timeMillis = 3000;
Contact contact = Contact.get(address, false);
String name = contact.getNameAndNumber();
return new MmsSmsDeliveryInfo(String.format(
context.getString(R.string.delivery_toast_body), name),
timeMillis);
} finally {
cursor.close();
}
}
Click to expand...
Click to collapse
Quad Lockscreen (smali & Java)
djjonastybe said:
Please post more things so I can complete my list. Let this be a compendium for beginners. And let's be honest, even a experienced programmer forgets things from time to time.
Donations are welcome but none of this is my work. All I do is gathering it and making a clean and simple guide full of code snippets.
Click to expand...
Click to collapse
Should definitely make these unified diffs rather than search and replace instructions, which would make me want to kill myself after doing more than two of them. Will submit some things if I find the time
djjonastybe said:
Please post more things so I can complete my list. Let this be a compendium for beginners. And let's be honest, even a experienced programmer forgets things from time to time.
Donations are welcome but none of this is my work. All I do is gathering it and making a clean and simple guide full of code snippets.
[ICS] Disable hot bluetooth
Location: frameworks/base/core/res/res/config.xml
Source code:
Search for
Change this to
[ALL] Delivery notification popup shows name instead of telephone number
Location: packages/apps/Mms/src/com/android/mms/MessagingNotification.java
Source code:
Search for
Change this to
Click to expand...
Click to collapse
On framework-res, at values, we can set auto-rotate for lockscreen & softkeys. Maybe you can add it (Can't remember names, and i'm not on my PC, sorry).
Updated
- Added Quad Lockscreen
I'm a newbee to xposed module development. I searched sometimes in this forum and viewed some open-source mudules on github, but I still don't know how to reload prefs in my module.
I try to change the setting repeatedly, but logcat always displays that prefs returned a false. My code is here below:
This is the main class loaded by xposed:
Code:
public class Main implements IXposedHookLoadPackage, IXposedHookZygoteInit, IXposedHookInitPackageResources{
private static XSharedPreferences prefs = new XSharedPreferences(Main.class.getPackage().getName());
....
SOME HACKS
....
private BroadcastReceiver xReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
context = mContext;
if (intent.getAction().equals("xxx.xxx.SETTING_CHANGED")){
prefs.makeWorldReadable(); // Wether this line is added or not, the result is same.
prefs.reload();
Log.d(TAG, String.valueOf(prefs.getBoolean("key", false)));
}
}
};
}
This is the setting screen class:
Code:
public class Setting extends PreferenceActivity implements OnSharedPreferenceChangeListener{
ListPreference lp;
ListPreference _lp;
EditTextPreference etp;
CheckBoxPreference cbp;
@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.setting);
getPreferenceManager().setSharedPreferencesMode(MODE_WORLD_READABLE);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(this);
}
@SuppressWarnings("deprecation")
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Intent intent = new Intent();
intent.setAction("xxx.xxx.SETTING_CHANGED");
Setting.this,sendBroadcast(intent);
}
From memory, I believe the XSharedPreferences constructor takes the preferences' file name, which is usually something like "com.mypackage_preferences" and not only "com.mypackage".
Note that you don't need to use makeWorldReadable in your module since you're doing that in your preferences activity.
GermainZ said:
From memory, I believe the XSharedPreferences constructor takes the preferences' file name, which is usually something like "com.mypackage_preferences" and not only "com.mypackage".
Note that you don't need to use makeWorldReadable in your module since you're doing that in your preferences activity.
Click to expand...
Click to collapse
Thanks for your reply. But I can't understand clearly and I'm even more confused.
Code:
XSharedPreferences prefs = new XSharedPreferences(Main.class.getPackage().getName());
This works well. Read preferences correctly.
In the source code of XSharedPreference class. The function "XSharedPreferences(String packageName)" will call "XSharedPreferences(String packageName, String prefFileName)" and complete the default preferences file name. I don't think I need to use full path and file name?
I still don't know how to reload settings correctly. Could you give me a copy of detailed code to work perfectly?
Awating your reply.
neverweep said:
Thanks for your reply. But I can't understand clearly and I'm even more confused.
Code:
XSharedPreferences prefs = new XSharedPreferences(Main.class.getPackage().getName());
This works well. Read preferences correctly.
In the source code of XSharedPreference class. The function "XSharedPreferences(String packageName)" will call "XSharedPreferences(String packageName, String prefFileName)" and complete the default preferences file name. I don't think I need to use full path and file name?
I still don't know how to reload settings correctly. Could you give me a copy of detailed code to work perfectly?
Awating your reply.
Click to expand...
Click to collapse
If I'm not mistaken, this:
Code:
XSharedPreferences prefs = new XSharedPreferences(Main.class.getPackage().getName());
… will load an "empty" preferences file (because it won't exist) so everything will have the default value. Try something like this instead:
Code:
XSharedPreferences prefs = new XSharedPreferences(Main.class.getPackage().getName() + "_preferences");
As for reloading preferences, you seem to be doing it correctly (XSharedPreferences.reload method), it's just that it's not working as intended for the reason explained above.
No, neverweep's code:
Code:
XSharedPreferences prefs = new XSharedPreferences(Main.class.getPackage().getName());
is good. I also use such code in my modules and everything works.
Rovo89 has code to add "_preferences" automatically (link: https://github.com/rovo89/XposedBri...bv/android/xposed/XSharedPreferences.java#L37)
I also had some trouble figuring out how to reload prefs in realtime, but thank's to this thread and to some attempts, I could finally figure it out.
Here's the code if this can help someone (plus the preference management is very simple so it should be a very easy example to follow):
on github (cannot post links yet):
Code:
lrq3000/XposedJitteryGyroFix/blob/14d7e93949bbfd5cfc31ce30482eff9860c35a49/GyroscopeNoiseFilter/src/net/kajos/gyronoisefilter/GyroscopeNoiseFilter.java#L50
Hi,
First off, I just entered the android programming world so my knowledge is very limited. Please bear with me.
I'm creating an XPosed module that simply takes a screenshot when I press the volume up or down buttons.
I've managed to hook the buttons globally, but since I don't have control of the topmost view, I don't know how I would be able to take a screenshot.
Originally, one would do it this way :
Code:
public Bitmap screenShot(View view) {
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
view.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
screenShot((ViewGroup) view.getParent());
However, I would need the view of the current activity in the foreground, and I'm kind of lost on how to retrieve it from within the XPosed module.
I looked through XPosedHelper.class and found a bunch if "find" functions that can get methods, resources, and classes but there are no helper functions for views except this comment on the very end.
Code:
// TODO helpers for view traversing
My current code looks like this :
Code:
public class Main {
static void init() {
try {
Class<?> classPhoneWindowManager = findClass("com.android.internal.policy.impl.PhoneWindowManager", null);
findAndHookMethod(classPhoneWindowManager, "interceptKeyBeforeQueueing",
KeyEvent.class, int.class, boolean.class, handleInterceptKeyBeforeQueueing);
} catch (Exception e) { XposedBridge.log(e); }
}
private static XC_MethodHook handleInterceptKeyBeforeQueueing = new XC_MethodHook(XCallback.PRIORITY_HIGHEST) {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
final boolean isScreenOn = (Boolean) param.args[2];
if (isScreenOn) {
final KeyEvent event = (KeyEvent) param.args[0];
final int keyCode = event.getKeyCode();
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
doSomething(param.thisObject, keyCode);
param.setResult(0);
return;
}
}
}
}
};
private static void doSomething(Object phoneWindowManager, int keycode) {
View content = findViewById(R.id.layoutroot);
content.setDrawingCacheEnabled(true);
}
}
I have to put some code in the "doSomething" function, but I'm kind of lost apprently. :crying:
How could I go about getting the screenshot of the current screen?
I've tried accessing the framebuffer, but realized that the framebuffer has been removed and only an empty fb0 exist on recent devices.
I also tried to use "/system/bin/screencap, screenshot, screenrecord" but for some reason, the application I'm targeting doesn't seem to work with those binaries.
Do you have any other suggestions? Any help would be appreciated.
Thanks.
You can use the APP called aiogestures,,Then you can change holding the menu button to screenshot button,or you can use the gravitybox to change the button………………
My English Is not very good……………
wish you can solve it???
仰天坏笑 said:
You can use the APP called aiogestures,,Then you can change holding the menu button to screenshot button,or you can use the gravitybox to change the button………………
My English Is not very good……………
wish you can solve it
Click to expand...
Click to collapse
Okay, I'll try those. Thanks!
However, it would be nice if I could implement my own code to directly get screenshots, instead of using an existing device's screenshot functionality. The reason being is, the application I'm targeting prohibits the user to take a screenshot, and therefore blocks all sorts of canonical methods to take a screenshot. I would like to have some more versatility and implement custom code to test different things, so I could bypass the screenshot restriction.
My android programming skills are quite poor... so any kind of help would be appreciated.
Thanks!
The great thing about open source is that you can use the work of others as a reference, so everyone benefits from everyone.
Luckily quite some Xposed developers do publish their sources.
A safe bet is to use GravityBox by the great @C3C076 as it implements a screenshot function..
Going to GravityBox at Github and searching (press T at github) for screenshot e.g. brings up the ScrreenshotTile.java
Here is a reference to the ModHwKeys.java - and there you'll find a takeScreenshot() function.
Cheers :fingers-crossed:
tonyp said:
The great thing about open source is that you can use the work of others as a reference, so everyone benefits from everyone.
Luckily quite some Xposed developers do publish their sources.
A safe bet is to use GravityBox by the great @C3C076 as it implements a screenshot function..
Going to GravityBox at Github and searching (press T at github) for screenshot e.g. brings up the ScrreenshotTile.java
Here is a reference to the ModHwKeys.java - and there you'll find a takeScreenshot() function.
Cheers :fingers-crossed:
Click to expand...
Click to collapse
Thanks!
However, it uses a service provided in "com.android.systemui.screenshot.TakeScreenshotService", which is blocked by the application. I'm trying to use various codes of taking screenshots, but all most of them require the current foreground view that is on the screen. I'm trying to figure out how I can get the foreground view class reference from within the XPosed module.
Any other suggestions?
android.view.SurfaceControl has some static methods for capturing screenshots silently. You can even control which layers should be excluded. E.g. you can do screenshot without system decors (navbar / status bar). Refer to https://android.googlesource.com/pl...r1/core/java/android/view/SurfaceControl.java (link is for lollipop but the same class exists in lower versions, too)
Here's an example how I use it on KitKat
https://github.com/GravityBox/Gravi...m/ceco/kitkat/gravitybox/ModDisplay.java#L446
binhexcraft said:
Thanks!
... which is blocked by the application....
Click to expand...
Click to collapse
Out of curiosity. Which app are you targeting?
C3C076 said:
android.view.SurfaceControl has some static methods for capturing screenshots silently. You can even control which layers should be excluded. E.g. you can do screenshot without system decors (navbar / status bar). Refer to https://android.googlesource.com/pl...r1/core/java/android/view/SurfaceControl.java (link is for lollipop but the same class exists in lower versions, too)
Here's an example how I use it on KitKat
https://github.com/GravityBox/Gravi...m/ceco/kitkat/gravitybox/ModDisplay.java#L446
Click to expand...
Click to collapse
Just tried it out and it works perfectly!!!
..............when the app is not running. When the app is running, then it gets blocked at :
Code:
final Bitmap bmp = (Bitmap) XposedHelpers.callStaticMethod(
XposedHelpers.findClass("android.view.SurfaceControl", null), "screenshot",
naturalW, naturalH, 0, 22000);
and when I look at the debug log, it says
"FB is protected: PERMISSION_DENIED"
This happens to be because the app is configured to use a "secure window".
Do you know if there is any workaround for this restriction?
My current thinking is to hook "captureScreenImplLocked" from here :
https://android.googlesource.com/pl...74/services/surfaceflinger/SurfaceFlinger.cpp
and make it bypass this part of the code.
Code:
if (hw->getSecureLayerVisible()) {
ALOGW("FB is protected: PERMISSION_DENIED");
return PERMISSION_DENIED;
}
or maybe just hook "getSecureLayerVisible" to always return false...
Would this be the right way to go?
...but before that, is it even possible? Cause I saw a post from someone saying that hooking SurfaceFlinger is not feasible or very disruptive...
http://forum.xda-developers.com/showpost.php?p=46388379&postcount=186
Or is there maybe a better, simpler way?
Thanks!
AA1973 said:
Out of curiosity. Which app are you targeting?
Click to expand...
Click to collapse
Sent you PM.
Answer to my own question.
I found a really simple workaround.
http://repo.xposed.info/module/fi.veetipaananen.android.disableflagsecure
Thanks for all the advice guys!!
I have finally fulfilled my objective.
Hello!
I've decided to change Smooth System Progress Bars module to use a navigation drawer and use fragments inside a "container". In order to do that, I had to "convert" my previously "Main activity" into a fragment. I've followed these instructions in order to achieve that.
But now I'm forced to reboot the phone to see the changes take effect. If I don't reboot, the values applied are the ones defined by default on the module's code.
More than that, every time I change anything on a PreferenceFragment (which has another options but nothing related to user's progress bars customization), the behavior is the same.
After rebooting, everything becomes as it should be. That's odd.
Since I'm fairly new to android programming, I really could use some help in order to understand this.
Can anyone help me?
I'm sorry for double posting.
I've just realized that this issue has nothing to do with fragments.
The problem exists even if I convert everything back to activities.
So this means that this started to happen immediately after I've implemented a navigation drawer. What could be wrong?
Any ideas?
Sorry once again.
I've solved my issue.
Discovered that the problem resided on NavigationDrawerFragment.java.
Somewhere along the code this happens:
Code:
/**
* Per the design guidelines, you should show the drawer on launch until the user manually
* expands it. This shared preference tracks this.
*/
private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
--- some more code ---
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Read in the flag indicating whether or not the user has demonstrated awareness of the
// drawer. See PREF_USER_LEARNED_DRAWER for details.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
if (savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
// Select either the default item (0) or the last selected item.
selectItem(mCurrentSelectedPosition);
}
So, the problem is, in order to use that small feature (make the user aware of the drawer) the default AOSP code uses this:
Code:
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
And that, my friends, compromises any of your SharedPreferences and/or XSharedPreferences.
I can live well without that small feature...deleted it from my module.
Everything is ok now.
:victory: