Replace a void method with XC_MethodReplace? - Xposed General

I'm trying to replace a method that looks like this
Code:
public static void updateAlwaysOnState(Context context, int userId) {
String str = TAG;
boolean z = true;
if (!mMotionAwakeOn || !isSupportAlwaysOn() || Secure.getIntForUser(context.getContentResolver(), KEY_AOD_DISPLAY_MODE, 0, userId) != 1) {
z = false;
}
mIsAlwaysOnModeEnabled = z;
try {
SystemProperties.set("sys.aod.disable", mIsAlwaysOnModeEnabled ? "0" : "1");
} catch (Exception e) {
StringBuilder sb = new StringBuilder();
sb.append("Exception e = ");
sb.append(e.toString());
Log.d(str, sb.toString());
}
StringBuilder sb2 = new StringBuilder();
sb2.append("updateAlwaysOnState: ");
sb2.append(mIsAlwaysOnModeEnabled);
sb2.append(", user = ");
sb2.append(userId);
Log.d(str, sb2.toString());
}
to make mIsAlwaysOnEnabled always equal true
How can I remove the if statement that causes z to become false, since this statement doesn't actually return anything?

Related

[APP] Netflix from LG ROM Dump

http://www.androidcentral.com/leaked-lg-revolution-system-dump-has-netflix
I was able to login and browse/manage queue.
I tried on my xoom, able to login and manage queue. Looks like it is gonna start streaming and then gives unable to connect to netflix error.
Sent from my Xoom using XDA App
wgarrido said:
http://www.androidcentral.com/leaked-lg-revolution-system-dump-has-netflix
I was able to login and browse/manage queue.
Click to expand...
Click to collapse
Pffft...I can already do that using Movela Netflix from Market.
skullvet said:
I tried on my xoom, able to login and manage queue. Looks like it is gonna start streaming and then gives unable to connect to netflix error.
Sent from my Xoom using XDA App
Click to expand...
Click to collapse
Same here.
Miami_Son said:
Pffft...I can already do that using Movela Netflix from Market.
Click to expand...
Click to collapse
Yeah but this app is official and is setup to stream. Just doesn't work yet. Plus I feel safer entering my login than a 3rd party app.
Read on a thread that it was a drm issue. He had posted a log.
Sent from my Xoom using XDA App
skullvet said:
Read on a thread that it was a drm issue. He had posted a log.
Sent from my Xoom using XDA App
Click to expand...
Click to collapse
Which mean it might be something that can be "fixed".
so my Java script isn't that great, but as far as I can tell, the nrdp.js file might lead us in the right direction.
In the script it is grabbing a lot of information about the device and passing across.
Pulled from the file
Code:
if (typeof nrdp != 'undefined')
{
return;
}
nrdp = new Object();
nrdp.debug = ##NRDP_DEBUG##;
nrdp.exit = function()
{
n_device_api.exit();
};
nrdp.device = new Object();
nrdp.device.getSoftwareVersion = function()
{
return String(n_device_api.getSoftwareVersion());
};
nrdp.device.getCertificationVersion = function()
{
return String(n_device_api.getCertificationVersion());
};
nrdp.device.getESN = function()
{
return String(n_device_api.getESN());
};
nrdp.device.getESNPrefix = function()
{
return String(n_device_api.getESNPrefix());
};
nrdp.device.setUIVersion = function(version)
{
n_device_api.setUIVersion(version);
};
nrdp.device.isScreensaverOn = function()
{
return (n_device_api.isScreensaverOn() == 'true');
};
nrdp.device.hasPointer = function()
{
return (n_device_api.hasPointer() == 'true');
};
nrdp.device.hasKeyboard = function()
{
return (n_device_api.hasKeyboard() == 'true');
};
nrdp.device.hasOnScreenKeyboard = function()
{
return (n_device_api.hasOnScreenKeyboard() == 'true');
};
nrdp.device.getLanguage = function()
{
return String(n_device_api.getLanguage());
};
nrdp.device.launchUrl = function(url)
{
n_device_api.launchUrl(url);
};
nrdp.device.notifyOnLogin = function()
{
n_device_api.notifyOnLogin();
};
nrdp.device.notifyOnLogout = function()
{
n_device_api.notifyOnLogout();
};
nrdp.device.injectKey = function(keyCode)
{
n_device_api.injectKey(keyCode);
};
nrdp.device.isConnected = function()
{
return (n_device_api.isConnected() == 'true');
};
nrdp.webapi = new Object();
nrdp.webapi.getConsumerKey = function()
{
return n_web_api.getConsumerKey();
};
nrdp.webapi.getConsumerSecret = function()
{
return String(n_web_api.getConsumerSecret());
};
nrdp.webapi.hmacSha1 = function(key, plaintext, handler)
{
try
{
if (typeof(handler) !== 'undefined' && handler !== null)
{
var encValue = n_web_api.hmacSha1(key, plaintext);
handler(encValue);
}
}
catch (e)
{
console.log('ERROR: ' + e);
}
};
nrdp.video = new Object();
nrdp.video.setGlobalEventListener = function(listener)
{
var events = String(n_video_api.getEvents());
var eventArray = events.split(" ");
if(typeof(listener) != 'undefined' && listener != null)
{
for(i = 0; i < eventArray.length; i++){
document.addEventListener(eventArray[i], listener, false);
}
} else {
for(i = 0; i < eventArray.length; i++){
document.removeEventListener(eventArray[i], nrdp.video._globalEventListener, false);
}
}
nrdp.video._globalEventListener = listener;
};
nrdp.video.addEventListener = function(type, listener, useCapture)
{
document.addEventListener(type, listener, useCapture);
};
nrdp.video.removeEventListener = function(type, listener, useCapture)
{
document.removeEventListener(type, listener, useCapture);
};
nrdp.video.dispatchEvent = function(evt)
{
document.dispatchEvent(evt);
};
nrdp.video._dispatchEvent = function(evt_type, evt_name)
{
var evt = document.createEvent(evt_type);
evt.initEvent(evt_name, true, true);
nrdp.video.dispatchEvent(evt);
};
nrdp.video._dispatchProgressEvent = function(evt_type, evt_name, loaded, total)
{
var evt = document.createEvent(evt_type);
evt.initEvent(evt_name, false, false);
evt.loaded = loaded;
evt.total = total;
evt.lengthComputable = true;
evt.loadedItems = 0;
evt.totalItems = 0;
nrdp.video.dispatchEvent(evt);
};
nrdp.video.getLastPlayedMovieData = function()
{
return eval('(' + String(n_video_api.getLastPlayedMovieData()) + ')');
};
nrdp.debug = new Object();
nrdp.debug.console = new Object();
nrdp.debug.console.log = function(message)
{
console.log(message);
};
nrdp.debug.console.warn = function(message)
{
console.log('WARN: ' + message);
};
nrdp.debug.console.error = function(message)
{
console.log('ERROR: ' + message);
};
Theres probably a device check in there somewhere. The app was made to work on Snapdragon processors.
caleb4992 said:
Theres probably a device check in there somewhere. The app was made to work on Snapdragon processors.
Click to expand...
Click to collapse
But not all snapdragon's. Only ones that support DRM, which would be the newer ones.

[APP] Netflix APK

Just leaked. Whether it works or not seems to be hit or miss.
See 2 posts down for apk.
Just leaked where? This thread is useless without a link.
Where is it?
Sorry...here is the actual apk
Thank you....checking it out now.
It let me log in and could view my queue but when tried to play 3 different movies it said could not reach the netflix service. Good find though. Maybe it will start working soon.
Just tested, no dice. streaming doesn't seem to be working correctly
Sent from my Captivate
I just get either an endless loading screen or an error regarding not reaching the netflix server...
I heard someone has it working on their Fascinate.
I tried it on my captivate running cognition 4.1.1 but it didn't work
Sent from my SAMSUNG-SGH-I897 using XDA Premium App
Its the foot print the phone leaves. I logged into my account and it showed sgh-i897 as an obsolete device on my account. Any chance we can get the binary embedded in the app for a compatible device?
Sent from my SAMSUNG-SGH-I897 using XDA Premium App
didnt work for me :/
Doesn't work. Dammit.
jferg5 said:
Its the foot print the phone leaves. I logged into my account and it showed sgh-i897 as an obsolete device on my account. Any chance we can get the binary embedded in the app for a compatible device?
Sent from my SAMSUNG-SGH-I897 using XDA Premium App
Click to expand...
Click to collapse
Yeah, it seems to be a drm issue, maybe we can find a possible work around?
Sent from my Galaxy S Captivate with Serendipity
wont even let me sign in:/
Just found this thread with the DRM files and Revolution system dump (full):
http://forum.xda-developers.com/showthread.php?t=994768
so my Java script isn't that great, but as far as I can tell, the nrdp.js file might lead us in the right direction.
In the script it is grabbing a lot of information about the device and passing across.
Pulled from the file
Code:
if (typeof nrdp != 'undefined')
{
return;
}
nrdp = new Object();
nrdp.debug = ##NRDP_DEBUG##;
nrdp.exit = function()
{
n_device_api.exit();
};
nrdp.device = new Object();
nrdp.device.getSoftwareVersion = function()
{
return String(n_device_api.getSoftwareVersion());
};
nrdp.device.getCertificationVersion = function()
{
return String(n_device_api.getCertificationVersion());
};
nrdp.device.getESN = function()
{
return String(n_device_api.getESN());
};
nrdp.device.getESNPrefix = function()
{
return String(n_device_api.getESNPrefix());
};
nrdp.device.setUIVersion = function(version)
{
n_device_api.setUIVersion(version);
};
nrdp.device.isScreensaverOn = function()
{
return (n_device_api.isScreensaverOn() == 'true');
};
nrdp.device.hasPointer = function()
{
return (n_device_api.hasPointer() == 'true');
};
nrdp.device.hasKeyboard = function()
{
return (n_device_api.hasKeyboard() == 'true');
};
nrdp.device.hasOnScreenKeyboard = function()
{
return (n_device_api.hasOnScreenKeyboard() == 'true');
};
nrdp.device.getLanguage = function()
{
return String(n_device_api.getLanguage());
};
nrdp.device.launchUrl = function(url)
{
n_device_api.launchUrl(url);
};
nrdp.device.notifyOnLogin = function()
{
n_device_api.notifyOnLogin();
};
nrdp.device.notifyOnLogout = function()
{
n_device_api.notifyOnLogout();
};
nrdp.device.injectKey = function(keyCode)
{
n_device_api.injectKey(keyCode);
};
nrdp.device.isConnected = function()
{
return (n_device_api.isConnected() == 'true');
};
nrdp.webapi = new Object();
nrdp.webapi.getConsumerKey = function()
{
return n_web_api.getConsumerKey();
};
nrdp.webapi.getConsumerSecret = function()
{
return String(n_web_api.getConsumerSecret());
};
nrdp.webapi.hmacSha1 = function(key, plaintext, handler)
{
try
{
if (typeof(handler) !== 'undefined' && handler !== null)
{
var encValue = n_web_api.hmacSha1(key, plaintext);
handler(encValue);
}
}
catch (e)
{
console.log('ERROR: ' + e);
}
};
nrdp.video = new Object();
nrdp.video.setGlobalEventListener = function(listener)
{
var events = String(n_video_api.getEvents());
var eventArray = events.split(" ");
if(typeof(listener) != 'undefined' && listener != null)
{
for(i = 0; i < eventArray.length; i++){
document.addEventListener(eventArray[i], listener, false);
}
} else {
for(i = 0; i < eventArray.length; i++){
document.removeEventListener(eventArray[i], nrdp.video._globalEventListener, false);
}
}
nrdp.video._globalEventListener = listener;
};
nrdp.video.addEventListener = function(type, listener, useCapture)
{
document.addEventListener(type, listener, useCapture);
};
nrdp.video.removeEventListener = function(type, listener, useCapture)
{
document.removeEventListener(type, listener, useCapture);
};
nrdp.video.dispatchEvent = function(evt)
{
document.dispatchEvent(evt);
};
nrdp.video._dispatchEvent = function(evt_type, evt_name)
{
var evt = document.createEvent(evt_type);
evt.initEvent(evt_name, true, true);
nrdp.video.dispatchEvent(evt);
};
nrdp.video._dispatchProgressEvent = function(evt_type, evt_name, loaded, total)
{
var evt = document.createEvent(evt_type);
evt.initEvent(evt_name, false, false);
evt.loaded = loaded;
evt.total = total;
evt.lengthComputable = true;
evt.loadedItems = 0;
evt.totalItems = 0;
nrdp.video.dispatchEvent(evt);
};
nrdp.video.getLastPlayedMovieData = function()
{
return eval('(' + String(n_video_api.getLastPlayedMovieData()) + ')');
};
nrdp.debug = new Object();
nrdp.debug.console = new Object();
nrdp.debug.console.log = function(message)
{
console.log(message);
};
nrdp.debug.console.warn = function(message)
{
console.log('WARN: ' + message);
};
nrdp.debug.console.error = function(message)
{
console.log('ERROR: ' + message);
};
The day this is hacked is the day netflix removes it from the list of allowable streaming apps.
Did some packet sniffing and found references to this XML:
http://uiboot.netflix.com/apps/android/config
Code:
<config>
<current_version>1</current_version>
<min_version>1</min_version>
<mandatory>true</mandatory>
<current_version_url>http://mcdn.netflix.com/us/mobile/android/01/netflix-01-release.apk</current_version_url>
<size>2943920</size>
</config>
The "current_version_url" is not found though.. Looks like they pulled it after the leak or something.
It's probably due to the fact that they intially released the Netflix APK to run only on Phones with a Snapdragon Processor, not a hummingbird.
At least that's what I read in the news a week or two ago.
id10terror said:
Did some packet sniffing and found references to this XML:
http://uiboot.netflix.com/apps/android/config
Code:
<config>
<current_version>1</current_version>
<min_version>1</min_version>
<mandatory>true</mandatory>
<current_version_url>http://mcdn.netflix.com/us/mobile/android/01/netflix-01-release.apk</current_version_url>
<size>2943920</size>
</config>
The "current_version_url" is not found though.. Looks like they pulled it after the leak or something.
Click to expand...
Click to collapse
So, I toyed around with the 'current_version_url' you mentioned and changed the end to the following "...android/02/netflix-02-release.apk" and it downloaded.
I loaded it on my cappy...I can browse around and whatnot but still no watch instantly. It just sits there...doesn't even say loading.

Java maze solver HELP

I've been working on trying to create a maze solver method using an enum, but it has not been going so well.
This is the enum class:
Code:
public enum Direction {
N, NE, E, SE, S, SW, W, NW, HERE;
/**
* Returns the X/column change on the screen that is associated with
* this direction: -1 for W, 0 for N/S, and +1 for E.
*/
public int getColModifier() {
int mod;
switch (this) {
case NW:
case W:
case SW:
mod = -1;
break;
case NE:
case E:
case SE:
mod = +1;
break;
default:
mod = 0;
break;
}
return mod;
}
/**
* Returns the Y/row change on the screen that is associated with
* this direction: -1 for N, 0 for E/W, and +1 for south.
*/
public int getRowModifier() {
int mod;
switch (this) {
case N:
case NE:
case NW:
mod = -1;
break;
case S:
case SE:
case SW:
mod = +1;
break;
default:
mod = 0;
break;
}
return mod;
}
/** As {@link #getColModifier()} */
public int getXModifier() {
return this.getColModifier();
}
/** As {@link #getRowModifier()} */
public int getYModifier() {
return this.getRowModifier();
}
/**
* Returns the direction that is the opposite of this one.
* For example, <code>Direction.NE.reverse() == Direction.SW</code>.
* (The opposite of HERE is still HERE though.)
*/
public Direction reverse() {
if (this == HERE) {
return this;
}else {
int reversed = (this.ordinal() + 4) % 8;
Direction[] dirs = Direction.values();
return dirs[reversed];
}
}
}
and this is the method that I have been trying to write:
Code:
public java.util.ArrayList<Direction> getPathToExit(){
for (int x=0; x<map.length; x++){
for (int y=0; y<map[x].length; y++){
if (map[x][y]=='S'){
this.startRow=x;
this.startCol=y;
}
}
}
System.out.println("start "+startRow+", "+startCol);
return getPathToExit(this.startRow, this.startCol);
}
private java.util.ArrayList<Direction> getPathToExit(int row, int col){
Direction [] dirs = Direction.values();
ArrayList<Direction> path = new ArrayList<Direction>();
getPathToExit(row, col);
if (row < 0 || col < 0 || row > map.length || col > map[row].length){
return path;
}
else if (map[row][col] != ' '){
return path;
}
else if (map[row][col] == 'E'){
path.add(Direction.HERE);
return path;
}
else {
for (int x=0; x<dirs.length-1; x++){
map[row][col]='x';
int nextRow = row + dirs[x].getRowModifier();
int nextCol = col + dirs[x].getColModifier();
path = getPathToExit(nextRow, nextCol);
}
}
return path;
}
The problem I am having is that I keep getting stackoverflowerrors or the piece does not move (tested this by printing what row/col it is on), it would stay on the same tile then crash.
Thanks in advance.

Help on appending to a file

Hi guys. I am trying to save sensor data to a file and figured out how to do it. Only thing is how do I keep updating the file and append new data without over writing?
I created two functions, one for saving and one for appending:
Code:
public void saveToFile(String accelLine, String gyroLine) throws IOException {
File root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File Dir = new File(root.getAbsolutePath());
if(!Dir.exists()) {
Dir.mkdir();
}
senLine = accelLine + gyroLine;
File file = new File(Dir, "senData.txt");
FileOutputStream fos = new FileOutputStream(file);
fos.write(senLine.getBytes());
fos.write('\n');
fos.close();
Toast.makeText(getApplicationContext(), "Initial Data Saved!", Toast.LENGTH_LONG).show();
newFile = 0;
senLine = "";
}
Code:
public void appendToFile(String accelLine, String gyroLine) throws IOException {
senLine = accelLine + gyroLine;
FileOutputStream fos = openFileOutput("senData.txt", Context.MODE_APPEND);
OutputStreamWriter osw = new OutputStreamWriter(fos);
osw.write(senLine);
osw.write('\n');
osw.flush();
osw.close();
Toast.makeText(getApplicationContext(), "More Data Saved!", Toast.LENGTH_LONG).show();
newFile = 0;
senLine = "";
}
Maybe my implementation is wrong? Could someone tell me what did I do wrong? Its my first time with Android and Java. Sorry!

[Xposed][For Devs] How to dynamically declare permissions for a target app without altering its manifest and changing its signature

Have you ever tried to extend your favorite app with new features using Xposed, but were shocked halfway that your hooked app doesn't declare a permission in AndroidManifest ? And then you spent infinite hours on the internet trying to solve this frustrating problem, you decided to use services and an external intent, but you found out that it was not convenient, and finally you gave up...
So you are like me, who wasted hours looking for a solution, until I figured out how to do it myself. Here's a snippet to save time for future Xposed enthusiasts. Put this code snippet in handleLoadPackage
Java:
// Hook will only patch System Framework
if (!lpparam.packageName.equals("android")) return;
String targetPkgName = "com.example.app"; // Replace this with the target app package name
String[] newPermissions = new String[] { // Put the new permissions here
"android.permission.INTERNET",
"android.permission.ACCESS_NETWORK_STATE"
};
String grantPermissionsMethod = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
grantPermissionsMethod = "restorePermissionState";
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S_V2) {
XposedBridge.log("[WARNING] THIS HOOK IS NOT GUARANTEED TO WORK ON ANDROID VERSIONS NEWER THAN ANDROID 12");
}
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P) {
grantPermissionsMethod = "grantPermissions";
}
else {
grantPermissionsMethod = "grantPermissionsLPw";
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
XposedBridge.log("[WARNING] THIS HOOK IS NOT GUARANTEED TO WORK ON ANDROID VERSIONS PRIOR TO JELLYBEAN");
}
}
XposedBridge.hookAllMethods(XposedHelpers.findClass("com.android.server.pm.permission.PermissionManagerService", lpparam.classLoader),
grantPermissionsMethod, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// on Android R and above, param.args[0] is an instance of android.content.pm.parsing.ParsingPackageImpl
// on Android Q and older, param.args[0] is an instance of android.content.pm.PackageParser$Package
// However, they both declare the same fields we need, so no need to check for class type
String pkgName = (String) XposedHelpers.getObjectField(param.args[0], "packageName");
XposedBridge.log("Package " + pkgName + " is requesting permissions");
if (pkgName.equals(targetPkgName)) {
List<String> permissions = (List<String>) XposedHelpers.getObjectField(param.args[0], "requestedPermissions");
for (String newPermission: newPermissions) {
if (!permissions.contains(newPermission)) {
permissions.add(newPermission);
XposedBridge.log("Added " + newPermission + " permission to " + pkgName);
}
}
}
}
});
Notes:
You must check System Framework in LSposed Manager
A reboot is required after adding the target permissions
You still need to prompt the user to accept sensitive permissions (ie android.permission.READ_CONTACTS), even if you have added them using this method
Wow, thx. Great for the install permissions!
I wrote a class to grant install and runtime/sensitive permissions (without prompting users).
Android 12 and 13 implementation:
Java:
public class Grant_Package_Permissions {
private static final int sdk = android.os.Build.VERSION.SDK_INT;
public static void hook(LoadPackageParam lpparam) {
try {
Class<?> PermissionManagerService = XposedHelpers.findClass(
sdk >= 33 /* android 13+ */ ?
"com.android.server.pm.permission.PermissionManagerServiceImpl" :
"com.android.server.pm.permission.PermissionManagerService", lpparam.classLoader);
Class<?> AndroidPackage = XposedHelpers.findClass(
"com.android.server.pm.parsing.pkg.AndroidPackage", lpparam.classLoader);
Class<?> PermissionCallback = XposedHelpers.findClass(
sdk >= 33 /* android 13+ */ ?
"com.android.server.pm.permission.PermissionManagerServiceImpl$PermissionCallback" :
"com.android.server.pm.permission.PermissionManagerService$PermissionCallback", lpparam.classLoader);
// PermissionManagerService(Impl) - restorePermissionState
XposedHelpers.findAndHookMethod(PermissionManagerService, "restorePermissionState",
AndroidPackage, boolean.class, String.class, PermissionCallback, int.class, new XC_MethodHook() {
@SuppressWarnings("unchecked")
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// params
Object pkg = param.args[0];
int filterUserId = (int) param.args[4];
// obtém os campos
Object mState = XposedHelpers.getObjectField(param.thisObject, "mState");
Object mRegistry = XposedHelpers.getObjectField(param.thisObject, "mRegistry");
Object mPackageManagerInt = XposedHelpers.getObjectField(param.thisObject, "mPackageManagerInt");
// Continua ?
String packageName = (String) XposedHelpers.callMethod(pkg, "getPackageName");
Object ps = XposedHelpers.callMethod(mPackageManagerInt,
sdk >= 33 /* android 13+ */ ?
"getPackageStateInternal" :
"getPackageSetting", packageName);
if (ps == null)
return;
int[] getAllUserIds = (int[]) XposedHelpers.callMethod(param.thisObject, "getAllUserIds");
int userHandle_USER_ALL = XposedHelpers.getStaticIntField(Class.forName("android.os.UserHandle"), "USER_ALL");
final int[] userIds = filterUserId == userHandle_USER_ALL ? getAllUserIds : new int[]{filterUserId};
for (int userId : userIds) {
List<String> requestedPermissions;
Object userState = XposedHelpers.callMethod(mState, "getOrCreateUserState", userId);
int appId = (int) XposedHelpers.callMethod(ps, "getAppId");
Object uidState = XposedHelpers.callMethod(userState, "getOrCreateUidState", appId);
// package 1
if (packageName.equals("PACKAGE_1")) {
requestedPermissions = (List<String>) XposedHelpers.callMethod(pkg, "getRequestedPermissions");
grantInstallOrRuntimePermission(requestedPermissions, uidState, mRegistry,
Manifest.permission.RECORD_AUDIO);
grantInstallOrRuntimePermission(requestedPermissions, uidState, mRegistry,
Manifest.permission.MODIFY_AUDIO_SETTINGS);
}
// package 2
if (packageName.equals("PACKAGE_2")) {
requestedPermissions = (List<String>) XposedHelpers.callMethod(pkg, "getRequestedPermissions");
grantInstallOrRuntimePermission(requestedPermissions, uidState, mRegistry,
Manifest.permission.READ_CONTACTS);
}
}
}
});
} catch (Exception e) {
XposedBridge.log(e);
}
}
private static void grantInstallOrRuntimePermission(List<String> requestedPermissions, Object uidState,
Object registry, String permission) {
if (!requestedPermissions.contains(permission))
XposedHelpers.callMethod(uidState, "grantPermission",
XposedHelpers.callMethod(registry, "getPermission", permission));
}
}
Edit: Android 12 and 13 implementation!
this looks promising. how to use this in xposed ? is there a module available?

Categories

Resources