Hello i have this function:
public void processPitch(float pitchInHz) {
TextView noteText = (TextView) findViewById(R.id.noteText) ;
TextView pitchText = (TextView) findViewById(R.id.pitchText) ;
pitchText.setText("" + pitchInHz);
if(pitchInHz >= 110 && pitchInHz < 123.47) {
//A
noteText.setText("A");
}
else if(pitchInHz >= 123.47 && pitchInHz < 130.81) {
//B
noteText.setText("B");
}
else if(pitchInHz >= 130.81 && pitchInHz < 146.83) {
//C
noteText.setText("C");
}
else if(pitchInHz >= 146.83 && pitchInHz < 164.81) {
//D
noteText.setText("D");
}
else if(pitchInHz >= 164.81 && pitchInHz <= 174.61) {
//E
noteText.setText("E");
}
else if(pitchInHz >= 174.61 && pitchInHz < 185) {
//F
noteText.setText("F");
}
else if(pitchInHz >= 185 && pitchInHz < 196) {
//G
noteText.setText("G");
}
}
and it gives me an error on the () of the function, that says "; expected. unexpected token".
Please give me a solution.
Related
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.
With the enhancement of D. Yeager for CM9, we can enable the Host Card Emulation functionality without any Secure Element.
by now, it can only change the SAK, ATQA, APP_DATA,... by modifying the CM9 source code. but when changing the uid, we'll get the lower-layer error: by logcating, it shows 'ANY_E_REG_ACCESS_DENIED' according to ETSI TS 102 622.
so, this operation must be blocked by the CLF's software stack, i guess - for i have no PN544/PN65N's manual.
but, i want to ask, is there any possible to change the rid to uid of host card emulation for nuxus s?
Reference:
Modifyed Code:
loc: android_external_libnfc-nxp.rar\src\phHciNfc_CE_A.c
Code:
NFCSTATUS
phHciNfc_CE_A_Initialise(
phHciNfc_sContext_t *psHciContext,
void *pHwRef
)
{
/*
1. Open Pipe,
2. Set all parameters
*/
NFCSTATUS status = NFCSTATUS_SUCCESS;
static uint8_t sak = 0x38; // HOST_CE_A_SAK_DEFAULT;
static uint8_t uid_info[] = { 0xE0U, 0x15U, 0x07U, 0x06U };
static uint8_t atqa_info[] = { NXP_CE_A_ATQA_LOW,
NXP_CE_A_ATQA_HIGH
};
if ((NULL == psHciContext) || (NULL == pHwRef))
{
status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
}
else if(NULL == psHciContext->p_ce_a_info)
{
status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
}
else
{
phHciNfc_CE_A_Info_t *ps_ce_a_info = ((phHciNfc_CE_A_Info_t *)
psHciContext->p_ce_a_info );
phHciNfc_Pipe_Info_t *ps_pipe_info = NULL;
ps_pipe_info = ps_ce_a_info->p_pipe_info;
if(NULL == ps_pipe_info )
{
status = PHNFCSTVAL(CID_NFC_HCI,
NFCSTATUS_INVALID_HCI_INFORMATION);
}
else
{
switch(ps_ce_a_info->current_seq)
{
case HOST_CE_A_PIPE_OPEN:
{
status = phHciNfc_Open_Pipe( psHciContext,
pHwRef, ps_pipe_info );
if(status == NFCSTATUS_SUCCESS)
{
//{----------------------------------- new for uid
ps_ce_a_info->next_seq = HOST_CE_A_UID_SEQ; // HOST_CE_A_SAK_SEQ;
//}----------------------------------- new for uid
status = NFCSTATUS_PENDING;
}
break;
}
//{----------------------------------- new for uid
case HOST_CE_A_UID_SEQ:
{
/* HOST Card Emulation A UID Configuration */
ps_pipe_info->reg_index = HOST_CE_A_UID_REG_INDEX;
/* Configure the UID of Host Card Emulation A */
ps_pipe_info->param_info = (void*)uid_info ;
ps_pipe_info->param_length = sizeof(uid_info) ;
status = phHciNfc_Send_Generic_Cmd(psHciContext,pHwRef,
ps_pipe_info->pipe.pipe_id,
(uint8_t)ANY_SET_PARAMETER);
if(status == NFCSTATUS_PENDING)
{
ps_ce_a_info->next_seq = HOST_CE_A_SAK_SEQ;
}
break;
}
//}----------------------------------- new for uid
case HOST_CE_A_SAK_SEQ:
{
/* HOST Card Emulation A SAK Configuration */
ps_pipe_info->reg_index = HOST_CE_A_SAK_INDEX;
/* Configure the SAK of Host Card Emulation A */
sak = (uint8_t)HOST_CE_A_SAK_DEFAULT;
ps_pipe_info->param_info =(void*)&sak ;
ps_pipe_info->param_length = sizeof(sak) ;
status = phHciNfc_Send_Generic_Cmd(psHciContext,pHwRef,
ps_pipe_info->pipe.pipe_id,
(uint8_t)ANY_SET_PARAMETER);
if(status == NFCSTATUS_PENDING)
{
ps_ce_a_info->next_seq = HOST_CE_A_ATQA_SEQ;
}
break;
}
case HOST_CE_A_ATQA_SEQ:
{
/* HOST Card Emulation A ATQA Configuration */
ps_pipe_info->reg_index = HOST_CE_A_ATQA_INDEX;
/* Configure the ATQA of Host Card Emulation A */
ps_pipe_info->param_info = (void*)atqa_info ;
ps_pipe_info->param_length = sizeof(atqa_info) ;
status = phHciNfc_Send_Generic_Cmd(psHciContext,pHwRef,
ps_pipe_info->pipe.pipe_id,
(uint8_t)ANY_SET_PARAMETER);
if(status == NFCSTATUS_PENDING)
{
ps_ce_a_info->next_seq = HOST_CE_A_ENABLE_SEQ;
}
break;
}
case HOST_CE_A_ENABLE_SEQ:
{
status = phHciNfc_CE_A_Mode( psHciContext,
pHwRef, HOST_CE_MODE_ENABLE );
if(status == NFCSTATUS_PENDING)
{
ps_ce_a_info->next_seq = HOST_CE_A_DISABLE_SEQ;
status = NFCSTATUS_SUCCESS;
}
break;
}
default :
{
break;
}
}
}
}
return status;
}
> sorry, i'm new to the xda, and cannot post externanl links with this thread.
if the reason is coming from the clf's software stack - the fireware, so, can we change it by disassamble it to unlock this block?
maybe there is an answer to this, thank u ^)^
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.
Yes. it's me again asking for help about another assignment...
Here is a link to the assignment:
http://www2.hawaii.edu/~ztomasze/teaching/ics211/2012fa/hw/A06b.html
I'm having trouble with the "add" method. The "tiny" variable will not update and keep track of the "tiny Meep".
Here is my code (note: all the println statements are there to let me know what process it is going through.):
Code:
public String add (Meep newcomer, boolean print){
Meep tinyMeep;
int move = 0;
int tiny = 0;
int shaft1 = 0;
int shaft2 = 0;
//Drops newcomer into center shaft
burrow.get(1).push(newcomer);
//Moves newcomer over to leftmost shaft if it is empty or it is smaller than current
if (burrow.get(0).size() == 0 || burrow.get(0).peek().compareTo(newcomer) >= 0){
burrow.get(0).push(burrow.get(1).pop());
tiny = 0;
System.out.println("Tiny Meep: "+newcomer.toString());
return "0 "+toString();
}
else {
if (burrow.get(tiny).countLessThan(newcomer) % 2 == 1 || burrow.get(tiny).countLessThan(newcomer) == 1){
//Flurry right
move = 1;
}
else if (burrow.get(tiny).countLessThan(newcomer) % 2 == 0) {
//Flurry left
move = -1;
}
while (burrow.get(1).size() > 0 || burrow.get(2).size() > 0){
Meep tinyMoved = burrow.get(tiny).pop();
tiny = (tiny + move + 3) % 3;
burrow.get(tiny).push(tinyMoved);
//Determines index of other two shafts
switch (tiny){
case 0 : shaft1 = 1;
shaft2 = 2;
break;
case 1 : shaft1 = 0;
shaft2 = 2;
break;
case 2 : shaft1 = 0;
shaft2 = 1;
break;
default: break;
}
System.out.println("teeny: "+tiny);
System.out.println("Shaft1: "+shaft1+" Shaft2: "+shaft2);
if (burrow.get(shaft1).size() > 0 || burrow.get(shaft2).size() > 0){
if (burrow.get(shaft1).size() == 0 && burrow.get(shaft2).peek().compareTo(newcomer) <= 0){
burrow.get(shaft1).push(burrow.get(shaft2).pop());
System.out.println("tiny1. "+tiny);
System.out.println("TM1: "+burrow.get(tiny).peek().toString());
System.out.println("\n1 "+toString());
}
else if (burrow.get(shaft2).size() == 0 && burrow.get(shaft1).peek().compareTo(newcomer) <= 0){
burrow.get(shaft2).push(burrow.get(shaft1).pop());
System.out.println("TM2: "+burrow.get(tiny).peek().toString());
System.out.println("tiny2. "+tiny);
System.out.println("\n2 "+toString());
}
else if (burrow.get(shaft1).size() > 0 || burrow.get(shaft2).size() > 0){
if (tiny == 0){
burrow.get(1).push(burrow.get(tiny).pop());
System.out.println("TM3: "+burrow.get(tiny).peek().toString());
System.out.println("tiny3. "+tiny);
System.out.println("\n3 "+toString());
}
else if (tiny == 1){
burrow.get(2).push(burrow.get(tiny).pop());
System.out.println("TM4: "+burrow.get(tiny).peek().toString());
System.out.println("tiny4. "+tiny);
System.out.println("\n4 "+toString());
}
else {
burrow.get(0).push(burrow.get(tiny).pop());
System.out.println("TM5: "+burrow.get(tiny).peek().toString());
System.out.println("tiny5. "+tiny);
System.out.println("\n5 "+toString());
}
}
}
}
}
return "last return "+toString();
}
Here is one of the sample output (notice where TM (tiny meep) it says M4 rather than M1):
Code:
=== ADDING: M1 ===
Tiny Meep: M1
0 { M1
{
{
=== ADDING: M5 ===
teeny: 1
Shaft1: 0 Shaft2: 2
teeny: 2
Shaft1: 0 Shaft2: 1
tiny1. 2
TM1: M1
1 { M5
{
{ M1
teeny: 0
Shaft1: 1 Shaft2: 2
last return { M5, M1
{
{
=== ADDING: M4 ===
teeny: 1
Shaft1: 0 Shaft2: 2
TM4: M4
tiny4. 1
4 { M5
{ M4
{ M1
Thanks in advance.
Please stop creating multiple threads for the same purpose. Use the existing one.
Thread closed.
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?