[SOLVED] help on activity - Nexus 5 Developer Discussion [Developers Only]

Hi to all,
I hope this is the correct place...I m sorry if I am wrong...
first, this is my project thread: http://forum.xda-developers.com/google-nexus-5/development/rom-boostpop-t2981990
this is the git: https://github.com/BoostPop
now, I want to: make long click on rotation tile opens a specific fragment on settings...so I made :this (plus cm stuff) and this
...but doesn't work...any ideas?
thanks

Rotation settings does not exists
it is under display settings...
if You remember in prelollipop android versions rotation tile opened display settings
an activity is a java file
with xml You define the layouts (the look and how elements are ordered)
https://github.com/android/platform_packages_apps_settings/tree/master/src/com/android/settings
You should try something like this:
Code:
@Override
protected boolean handleLongClick(Context context) {
Intent intent = new Intent("com.android.settings.DisplaySettings");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
return true;
}
I don't know if You can use
android.settings.DISPLAY_SETTINGS
android.settings.ACTION_DISPLAY_SETTINGS..
(Try if com.android.settings.DisplaySettings does not work)
but I'm not sure, maybe You need also to organise your imports
Code:
import android.view.View;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;

EnricoD said:
Rotation settings does not exists
it is under display settings...
if You remember in prelollipop android versions rotation tile opened display settings
an activity is a java file
with xml You define the layouts (the look and how elements are ordered)
https://github.com/android/platform_packages_apps_settings/tree/master/src/com/android/settings
You should try something like this:
Code:
@Override
protected boolean handleLongClick(Context context) {
Intent intent = new Intent("com.android.settings.DisplaySettings");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
return true;
}
I don't know if You can use
android.settings.DISPLAY_SETTINGS
android.settings.ACTION_DISPLAY_SETTINGS..
(Try if com.android.settings.DisplaySettings does not work)
but I'm not sure, maybe You need also to organise your imports
Code:
import android.view.View;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
Click to expand...
Click to collapse
first, thanks for the answer....
but I don't want display settings...I want my custom java :angel:
btw, the xml is the manifest...not a layout...
"To be of use with Context.startActivity(), all activity classes must have a corresponding <activity> declaration in their package's AndroidManifest.xml."
the problem is not the first commit (frameworks) but the declaration of the activity...I m forgotting something

Crostantin said:
first, thanks for the answer....
but I don't want display settings...I want my custom java :angel:
btw, the xml is the manifest...not a layout...
"To be of use with Context.startActivity(), all activity classes must have a corresponding <activity> declaration in their package's AndroidManifest.xml."
the problem is not the first commit (frameworks) but the declaration of the activity...I m forgotting something
Click to expand...
Click to collapse
Oopps sorry man
I thought it was a layout .. Ha ha .. Ok, I'll look into it asap and see if I can help

EnricoD said:
Oopps sorry man
I thought it was a layout .. Ha ha .. Ok, I'll look into it asap and see if I can help
Click to expand...
Click to collapse
solved....
It' necessary to define the activity in ActivityPicker and in the "pointed" java !!!!

Related

[Tutorial][Source code]Mods & Source code for ROM Developers

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

Applying changes without [soft-]rebooting

Hi, I've been gone for a long long time and just came back with a new module.
I have seen that some other modules can actually apply the changes immediately without the need of doing a soft-reboot or full reboot. That is new to me. Maybe I missed it during those times when I'm not around.
So I want to ask the masters about this technique. How do you implement it. Or is there a xposed method which is reponsible for this?
I'm trying to apply changes to resources of a package.
I hope someone can explain to me how to implement it.
Thanks in advance!
Usual scenario:
Code:
<load preferences>
<hook method>
<do something inside the method using the loaded preferences>
Dynamically:
Code:
<initialize XSharedPreferences>
<hook method>
<reload preferences using XSharedPreferences.reload() and getting the preferences directly>
<do something inside the method using the loaded preferences>
You can also use broadcasts, if possible.
GermainZ said:
Usual scenario:
Code:
<load preferences>
<hook method>
<do something inside the method using the loaded preferences>
Dynamically:
Code:
<initialize XSharedPreferences>
<hook method>
<reload preferences using XSharedPreferences.reload() and getting the preferences directly>
<do something inside the method using the loaded preferences>
You can also use broadcasts, if possible.
Click to expand...
Click to collapse
sorry but the idea really can't sink into my mind... maybe I need some actual code... but anyway sir, by using XSharedPreferences, does it mean that all inputs must be saved in a prefs file?
This module I've made does not actually utilize SharedPrreferences, but store them inside the files dir using getFilesDir() for some reason...
WisdomSky said:
sorry but the idea really can't sink into my mind... maybe I need some actual code... but anyway sir, by using XSharedPreferences, does it mean that all inputs must be saved in a prefs file?
This module I've made does not actually utilize SharedPrreferences, but store them inside the files dir using getFilesDir() for some reason...
Click to expand...
Click to collapse
Well in that case you'd just read the preferences before applying them. In some cases (resources replacements), I don't think it's possible, but if you're hooking a module to change a TextView's color for example:
Code:
beforeHookedMethod:
int textColor = getTextColor(); // load the preference inside the method
TextView textView = …;
textView.setTextColor(textColor); // apply the preference
I might be able to give you an actual example if you explain what you're doing exactly, but as I said I don't think it's possible for resource replacements (which I guess is what you're doing).
GermainZ said:
Well in that case you'd just read the preferences before applying them. In some cases (resources replacements), I don't think it's possible, but if you're hooking a module to change a TextView's color for example:
Code:
beforeHookedMethod:
int textColor = getTextColor(); // load the preference inside the method
TextView textView = …;
textView.setTextColor(textColor); // apply the preference
I might be able to give you an actual example if you explain what you're doing exactly, but as I said I don't think it's possible for resource replacements (which I guess is what you're doing).
Click to expand...
Click to collapse
When a user has selected a package, a new directory under its package name will be created inside the files dir of my app, and when the user has applied a replacement to a certain resource a new directory will be created inside the directory created a while ago. and then inside this directory is where a new file is created and the filename will be the resource name and the content of the file is just a single line plain text which is the replacement value.
so if you can see it, there is a heirarchy of directories...
under the files dir... it could look like this...
[dir]files
-----[dir]com.package.name
----------[dir]string
---------------[file]app_name
----------[dir]drawable
---------------[file]ic_launcher
by using this pattern, I can write something that will loop through the files dir... get the package name, then get the resource type, then get the resource name and finally get its value by reading the content. And now we all have the needed arguments to pass to the setReplacement method...
but since you said that it is not applicable to resource replacements, then there's really no hope.
WisdomSky said:
but since you said that it is not applicable to resource replacements, then there's really no hope.
Click to expand...
Click to collapse
I might be wrong as I'm not too familiar with replacing resources. Where are you replacing the resources? Also, can wee see a (simplified/pseudo-code, maybe) code snippet of you doing so?
The problem with resources is that the app/system will usually load resources just once, or at least only at certain spots of the code. So even if you set a new replacement, it won't come into effect immediately, but only when the app/system decides loads it again. Same for removed replacements.
WisdomSky said:
I hope someone can explain to me how to implement it.
Thanks in advance!
Click to expand...
Click to collapse
If you module hooks Activity, Service or any other context application, you can store settings not with Shared Preferences, but in system settings database and use ContextResolver to get information from database.
and of course use <uses-permission android:name="android.permission.WRITE_SETTINGS" />
Here is an example:
Code:
findAndHookMethod("com.android.phone.PhoneApp", paramLoadPackageParam.classLoader, "onCreate", new XC_MethodHook()
{
protected void beforeHookedMethod(MethodHookParam param) throws Throwable
{
ContentResolver cr = (ContentResolver) XposedHelpers.callMethod(param.thisObject, "getContentResolver");
Class <?> Features = XposedHelpers.findClass("com.android.phone.HtcFeatureList", paramLoadPackageParam.classLoader);
boolean CallRecording = Misc.toBoolean(Settings.System.getInt(cr, Const.TWEAK_CALL_REC, 0));
if (CallRecording)
{
XposedHelpers.setStaticBooleanField(Features, "FEATURE_SUPPORT_VOICE_RECORDING", true);
}
}
});
More look here https://github.com/Falseclock/HtcOneTweaker/blob/master/src/kz/virtex/htc/tweaker/mods/Recorder.java
It is possible also to implement for resources, but you have always lookup views by identifier, load your application resources, redraw drawables, strings, etc. AND THIS IS BATTERY COST EFFICIENT method.
Other way - store replaced drawables for example in static variables and do not redraw every time. But there will be a huge code if you are replacing a lot of resources.
here is another example
Code:
public static Drawable Background;
findAndHookMethod(packageName + ".ui.ConversationListBaseAdapter", paramLoadPackageParam.classLoader, "bind", "android.view.View", "android.content.Context", packageName + ".ui.ConversationHeader", new XC_MethodHook()
{
protected void afterHookedMethod(MethodHookParam param) throws Throwable
{
boolean isRead = (Boolean) XposedHelpers.callMethod(param.args[2], "isRead");
View row = (View) param.args[0];
if (Background == null)
{
Background = row.getBackground();
if (Background == null)
{
Background = new ColorDrawable(row.getContext().getResources().getColor(android.R.color.transparent));
}
}
if (isRead == false)
{
XModuleResources modRes = XModuleResources.createInstance(XMain.MODULE_PATH, null);
row.setBackgroundDrawable(modRes.getDrawable(R.drawable.list_background_unread));
} else
{
row.setBackgroundDrawable(Background);
}
}
});
Falseclock said:
If you module hooks Activity, Service or any other context application, you can store settings not with Shared Preferences, but in system settings database and use ContextResolver to get information from database.
and of course use <uses-permission android:name="android.permission.WRITE_SETTINGS" />
Here is an example:
Click to expand...
Click to collapse
Ideally, all traces of an Xposed module should be removed when it's uninstalled, IMO. This goes against that.
GermainZ said:
Ideally, all traces of an Xposed module should be removed when it's uninstalled, IMO. This goes against that.
Click to expand...
Click to collapse
Ideally yes, but there are some tweak/mods requires fast settings change and immediate apply without restart. Otherwise such mods are not usable.
I do such only for special mods. All other mods are stored in shared preferences.
Falseclock said:
Ideally yes, but there are some tweak/mods requires fast settings change and immediate apply without restart. Otherwise such mods are not usable.
I do such only for special mods. All other mods are stored in shared preferences.
Click to expand...
Click to collapse
Then get the app's context/system context and use your own settings, or register and use a BroadcastReceiver.
GermainZ said:
Then get the app's context/system context and use your own settings, or register and use a BroadcastReceiver.
Click to expand...
Click to collapse
you are completely right. I just took ready code from my old custom ROM and used as it is in Xposed mode.
time to refactor my code )))
Hi I want to blend in too so: I have charged the preferences in the initzigote and after I have method like this:
Code:
beforhookedmethod{
Pref.reload();
String[] A new string[2000];
Map<string,?> B = Pref.getall();
i=0;
for(Map.Entry<String,?> entry : a.entrySet()){
B[i] = entry.getValue().toString();
Xposedbridge.log(entry.getvalue());
i++;
}
//some code that set this array into a hooked field
}
Now the problem is:if I remove the reload pref,after a reboot all work but if I leave the reload nothing work;the method is still hooked because I see that doesn't do what it normally do,but doesn't do what I say in the hook and even no log.What could be the problem?
Thanks.
Massi-X said:
Hi I want to blend in too so: I have charged the preferences in the initzigote and after I have method like this:
Code:
beforhookedmethod{
Pref.reload();
String[] A new string[2000];
Map<string,?> B = Pref.getall();
i=0;
for(Map.Entry<String,?> entry : a.entrySet()){
B[i] = entry.getValue().toString();
Xposedbridge.log(entry.getvalue());
i++;
}
//some code that set this array into a hooked field
}
Now the problem is:if I remove the reload pref,after a reboot all work but if I leave the reload nothing work;the method is still hooked because I see that doesn't do what it normally do,but doesn't do what I say in the hook and even no log.What could be the problem?
Thanks.
Click to expand...
Click to collapse
Full code? what's Pref? How are you initializing it?
GermainZ said:
Full code? what's Pref? How are you initializing it?
Click to expand...
Click to collapse
This is the full code:
Code:
public String[] A = new String[2000];
Field B = null;
public XSharedPreferences Pref;
@Override
public void initZygote(StartupParam startupParam) throws Throwable {
Pref = new XSharedPreferences("com.android.xposed...", "Preferences");
}
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
if (lpparam.packageName.equals("com.android...")) {
de.robv.android.xposed.XposedHelpers.findAndHookMethod
("com.android...", lpparam.classLoader, "....", Operation.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
final Class<?> Constants = de.robv.android.xposed.XposedHelpers.findClass
("....", lpparam.classLoader);
Pref.reload();
Map<String,?> D = xPreferences.getAll();
int i=0;
for (Map.Entry<String, ?> entry: D.entrySet()) {
A[i] = entry.getKey();
de.robv.android.xposed.XposedBridge.log(entry.getKey());
i++;
}
B = de.robv.android.xposed.XposedHelpers.findField
(Constants, "ACCEPTABLE...");
final Object oldFieldAcc = B.get(Constants);
B.set
(oldFieldAcc, A);
});
}
}
}
I want to keep the secret so I obscured the name of variables and some string but all the code is exactly that!
Thanks!
Massi-X said:
This is the full code:
Click to expand...
Click to collapse
And it works fine when you remove .reload()? I'm not sure what's wrong, but if I had to guess, I'd say it's a permission issue. Do this when defining Pref instead:
Code:
Pref = new XSharedPreferences(…, …);
[COLOR="Red"]Pref.makeWorldReadable();[/COLOR]
GermainZ said:
And it works fine when you remove .reload()? I'm not sure what's wrong, but if I had to guess, I'd say it's a permission issue. Do this when defining Pref instead:
Code:
Pref = new XSharedPreferences(…, …);
[COLOR="Red"]Pref.makeWorldReadable();[/COLOR]
Click to expand...
Click to collapse
Yes works perfect when I remove to reload.I have yet tried this solution but not work.
I try to explain you what happens when I use the version with pref.reload:I select the option in my app and reboot and all work,also the log;when I change things on the go old preferences continue to work and the hook also but all new things aren't considered and the log stop to work.
I'm going crazy....
That's easy to explain: You write the settings from your own app, but read them from a different app. It doesn't matter that your code tries to read the settings, it's executed in the hooked app's process with the hooked app's UID. Android's security concept doesn't allow this by default, preferences are usually only readable for the app that created it. Pref.makeWorldReadable() will change this (as the name says), but Android automatically resets the permissions when you store the settings again. To fix this, try:
Code:
[B]getPreferenceManager().setSharedPreferencesMode(MODE_WORLD_READABLE);[/B]
addPreferencesFromResource(R.xml.preferences);
https://github.com/rovo89/PlayStore...d/mods/playstorefix/SettingsActivity.java#L29
rovo89 said:
That's easy to explain: You write the settings from your own app, but read them from a different app. It doesn't matter that your code tries to read the settings, it's executed in the hooked app's process with the hooked app's UID. Android's security concept doesn't allow this by default, preferences are usually only readable for the app that created it. Pref.makeWorldReadable() will change this (as the name says), but Android automatically resets the permissions when you store the settings again. To fix this, try:
Code:
[B]getPreferenceManager().setSharedPreferencesMode(MODE_WORLD_READABLE);[/B]
addPreferencesFromResource(R.xml.preferences);
https://github.com/rovo89/PlayStore...d/mods/playstorefix/SettingsActivity.java#L29
Click to expand...
Click to collapse
You won't believe it but i think this last night .And yes,this was the problem!Thanks to everyone have help me.I think that my module will online today or tomorrow. :good:

[Q] Still don't know how to reload prefs in realtime

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

How to take a screenshot from within an XPosed module?

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.

Can some PLEASE tell me how to display a dialog box with an OK button

Code:
alertDialog.setTitle("Bluetooth is not available!");
alertDialog.setMessage("Please install this app on a mobile phone with bluetooth...");
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", null);
alertDialog.show();
This does not compile and NONE of the examples I have found in stack overflow will work.
It is either DialogInterface is unresolved or call to setButton is ambiguous. It is just around and around in circles with the same compile errors.
For once and for all how do you friggin well do it?
The precise imports I need and the precise paramaters I must pass to setButton
gregaryb said:
Code:
alertDialog.setTitle("Bluetooth is not available!");
alertDialog.setMessage("Please install this app on a mobile phone with bluetooth...");
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", null);
alertDialog.show();
This does not compile and NONE of the examples I have found in stack overflow will work.
It is either DialogInterface is unresolved or call to setButton is ambiguous. It is just around and around in circles with the same compile errors.
For once and for all how do you friggin well do it?
The precise imports I need and the precise paramaters I must pass to setButton
Click to expand...
Click to collapse
Hi, i use this method for alertdialog :
Code:
new AlertDialog.Builder(context)
.setTitle("Delete entry")
.setMessage("Are you sure you want to delete this entry?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// continue with delete
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
Goodbye
Cris

Categories

Resources