I've been trying to figure this out for a while. I'm trying to store a value in a custom property variable using property_set and retrieve it in another module using property_get but it's just not working. I made some changes to the property_service.c file to add permissions to the custom property but it's still not reading what's stored and there are no errors either. Are there any other files that needs to be changed to get this working?
property_service.c looks like this. I added my custom property (dm) at the end.
/* White list of permissions for setting property services. */
struct {
const char *prefix;
unsigned int uid;
unsigned int gid;
} property_perms[] = {
{ "net.rmnet0.", AID_RADIO, 0 },
...
{ "service.adb.tcp.port", AID_SHELL, 0 },
{ "persist.sys.", AID_SYSTEM, 0 },
{ "persist.service.", AID_SYSTEM, 0 },
{ "persist.security.", AID_SYSTEM, 0 },
{ "dm.", AID_SYSTEM, 0},
{ NULL, 0, 0 }
};
It can be permission problem, in general case user/group permissions (are you running as root?).
Second thing that can cause permissions denial is SELinux rules - grep logcat and dmesg logs for "avc" denials. There should be some messages about your efforts in this case. Of course this case is possible if SELinux (e.g. SEAndroid) is running in enforced mode.
Otherwise you should provide more details, like errno, retval and so on
Related
I am working on a personal project and I am using flutter to develop an app (cross platform) that reads in the user's health data from google fit (Android) or Apple Health. I am using this package and even the EXACT same code like in the documentation (I am currently only testing on Android):
Future fetchStepData() async {
int? steps;
// get steps for today (i.e., since midnight)
final now = DateTime.now();
final midnight = DateTime(now.year, now.month, now.day);
bool requested = await health.requestAuthorization([HealthDataType.STEPS]);
if (requested) {
try {
steps = await health.getTotalStepsInInterval(midnight, now);
} catch (error) {
print("Caught exception in getTotalStepsInInterval: $error");
}
print('Total number of steps: $steps');
setState(() {
_nofSteps = (steps == null) ? 0 : steps;
_state = (steps == null) ? AppState.NO_DATA : AppState.STEPS_READY;
});
} else {
print("Authorization not granted - error in authorization");
setState(() => _state = AppState.DATA_NOT_FETCHED);
}
}
Then I am calling this function with await and I also have inserted the correct permission in all Android Manifest files:
Also I set up an OAuth2 Client ID for the project and added my google account as a test user.
BUT THE FUNCTION SETS THE VARIABLE STEPS ALWAYS TO NULL? The boolean variable "requested" is true, so it seems like the actual connection is working?
I am really disappointed by myself guys and I really need help - THANK YOU!
I tried adding the correct android permissions, asking for permissions explicitly, different time intervalls but nothing worked for me, I always got a null value back.
I have a Node js API written in express framework.
I am sending some data over all my api does is calculate number of Packages to make For example :- 100/10 = 10 packages to make.
Loops and creates packages in sales force and firebase one by one.
Works fine from postman.
Problem:
When i try to hit the api from my app it works fine when the package count is <= 10. when > 10 ,Lets say 25 it calculates packages and run a loop of 25 and creates packages,crashes after 11th iteration and restarts the route, calculate again 25 packages to create and resulting in "Over weight error".
1- thought it was from android error may be i was hitting two request one after an other ( this was not the case ).
2- Tried sending header "Connection" "Keep-Alive" ( as Postman does ) not working.
3- tried to put up the timeout in the below code it did not work either ( tried variations of time out like 0, 50,000 ms )
else {
console.log('=====By Item=============');
const supplierFinishedGood = {
Name: parentBatchDoc['itemName'],
Supplier_Product__c: parentBatchDoc['id'],
Package_Size__c: 'a090S000001ZQ5kQAG', // Hard coded PackageSize in 'Gram' as per SALESFORCE
On_Hand_Amount__c: childBatch['batchWeight']
}
console.log('=====By Item============= 2');
const SupplierFinishedProductID = await createSupplierFinishedProduct(supplierFinishedGood, bearerToken);
const Quantity_Packaged__c = Math.floor((childBatch['batchWeight'] - childBatch['batchTestAmount']) / noOfPackage);
console.log('=====By Item============= 3');
//console.log('Quantity_Packaged__c ==== Remaining_Grams_Available_for_Packaging__c', Quantity_Packaged__c, parentBatchSalesforce['Remaining_Grams_Available_for_Packaging__c']);
for (let index = 0; index < noOfPackage; index++) {
if (parentBatchSalesforce['Remaining_Grams_Available_for_Packaging__c'] > Quantity_Packaged__c) {
let package = {
Batch__c: childId,
Product__c: SupplierFinishedProductID,
Inventory_Location__c: 'a030S000003x7M7QAI', //Hard coded InventoryLocation 'StorageFinished' as per SALESFORCE
Number_Of_Items__c: noOfItemInPackage,
Quantity_Packaged__c: Quantity_Packaged__c,
Date_Packaged__c: datePackaged,
Expiration_Date__c: expirationDate
};
console.log('Before creating apcaktge ', index);
const packageID = await createPackage(package, bearerToken);
console.log('After creating package ', index, parentBatchSalesforce['Remaining_Grams_Available_for_Packaging__c']);
package['parentBatchId'] = parentId;
package['status'] = 'Ready to checkout';
package['uid'] = packageID;
const packageFBResponse = await db.collection('packages').doc(packageID).set(package, { merge: true });
reponseBody.push(packageID);
} else {
console.log('======Over
Weight====');
}
Above code is what produces the error.
There is a If condition before this it works fine i have tested it
as it has some other scenario.
End result should not be a timeout error.
API should create all the packages and return the result.
I have found a workaround. I am Playing around batch status and my code returns me the IDs which i need and packages are created.
This is not the ultimated best solution it is a work around. i am still open to know what the actual problem is.
parentBatchDoc['childBatches'][childId]['batchStatus'] = "In Processing";
const parentBatchDocResponse = await db.collection('batches').doc(parentId).set(parentBatchDoc, { merge: true });
if(parentBatchDoc['childBatches'][childId]['batchStatus'] !== "In Processing"){
===================Rest of the case of =======================
}
As i see now, when eslint show error on console window. App keep continue update new code. I want to force it stop update latest code until no error appear and i dont want use VS Code Extension apply on project.
Really appriciate when any one provide some clues.
Regard
There is no supported eslint parameter to treat warnings as errors, but you can do something like this:
// .eslintrc.js
function isTruthy(value) {
if (!value) return false;
return ['1', 'true'].indexOf(value.toLowerCase()) >= 0;
}
// Warnings are errors in CI
var OFF = 'off';
var ERROR = 'error';
var WARNING = isTruthy(process.env.CI) ? ERROR : 'warn';
module.exports = {
// ...
"rules": {
"comma-dangle": OFF,
"eqeqeq": [WARNING, "allow-null"],
"import/imports-first": OFF,
"indent": [WARNING, 2, {"SwitchCase": 1}],
"max-len": [WARNING, 100, 2],
"no-console": [WARNING, {"allow": ["warn", "error"]}],
"no-debugger": WARNING,
"no-fallthrough": WARNING,
"no-unreachable": WARNING,
"no-unused-vars": [WARNING, {"vars": "all", "args": "none"}],
"no-var": ERROR,
"prefer-const": WARNING,
"react/prop-types": [WARNING, {"ignore": ["className"]}],
"semi": [WARNING, "never"],
},
// ...
}
The error that I receive in my Chrome: Inspect log is as below:
"Error: Uncaught (in promise): TypeError: undefined is not a function↵TypeError: undefined is not a function↵ at file:///android_asset/www/build/main.js:101314:24↵ at t.invoke (file:///android_asset/www/build/polyfills.js:3:11562)↵ at Object.inner.inner.fork.onInvoke (file:///android_asset/www/build/main.js:4403:37)↵ at t.invoke (file:///android_asset/www/build/polyfills.js:3:11532)↵ at n.run (file:///android_asset/www/build/polyfills.js:3:6468)↵ at file:///android_asset/www/build/polyfills.js:3:3767↵ at t.invokeTask (file:///android_asset/www/build/polyfills.js:3:12256)↵ at Object.inner.inner.fork.onInvokeTask (file:///android_asset/www/build/main.js:4394:37)↵ at t.invokeTask (file:///android_asset/www/build/polyfills.js:3:12215)↵ at n.runTask (file:///android_asset/www/build/polyfills.js:3:7153)↵ at a (file:///android_asset/www/build/polyfills.js:3:2312)↵ at XMLHttpRequest.invoke (file:///android_asset/www/build/polyfills.js:3:13253)↵ at new Error (native)↵ at Error.d (file:///android_asset/www/build/polyfills.js:3:3991)↵ at l (file:///android_asset/www/build/polyfills.js:3:3244)↵ at file:///android_asset/www/build/polyfills.js:3:3798↵ at t.invokeTask (file:///android_asset/www/build/polyfills.js:3:12256)↵ at Object.inner.inner.fork.onInvokeTask (file:///android_asset/www/build/main.js:4394:37)↵ at t.invokeTask (file:///android_asset/www/build/polyfills.js:3:12215)↵ at n.runTask (file:///android_asset/www/build/polyfills.js:3:7153)↵ at a (file:///android_asset/www/build/polyfills.js:3:2312)↵ at XMLHttpRequest.invoke (file:///android_asset/www/build/polyfills.js:3:13253)"
This happens when I try to run the following
(res) => {
console.log(res);
if (res.receiver) {
///Check if msisdn exists
///If it does, select that item
var found = false;
(<any>Object).values(this.approvedBenifs).forEach(element => {
if (element.msisdn == res.receiver.FlashMsisdn) {
this.selectedBenif = this.approvedBenifs.indexOf(element);
found = true;
}
});
}
However, running this code in Chrome through my Ionic emulator works fine.
The line that seems fishy to me is obviously the one involving (<any>Object). Is the (<any>Object).values() method the problem here, and if so, what strategy can I use to get a collection of values from a specified array?
Edit
I've rewritten the code to be less weird, and it works:
var found = false;
for (let element of this.approvedBenifs) {
if (element.msisdn == res.receiver.FlashMsisdn) {
this.selectedBenif = this.approvedBenifs.indexOf(element);
found = true;
}
}
However, I'd still be interested to know why the (<any>Object).values() method seems to fail on Android.
Perhaps you could try removing the
(<any>Object).values
(I'm asssuming this.approvedBenifs is an array) and just directly iterate through the array.
this.approvedBenifs.forEach(element => {
if (element.msisdn == res.receiver.FlashMsisdn) {
this.selectedBenif = this.approvedBenifs.indexOf(element);
found = true;
}
});
To get a collection of keys just use Object.keys(ARRAY_NAME) which will return an array of keys on the array or object. You're currently fetching the values.
Status: not solved yet
Problem
Once I build and install an app with GearVR it asks by default:
XXX is requesting permission to access photos, media and files on your device. Allow?
Allow / Deny
I don't need my app to access any of those above. How can I get rid of this programmatically?
Edit 1
It seems that Unity automatically adds READ_EXTERNAL_STORAGE to any build for some reason. Stripping out the permission doesn't help in newer versions of Unity as the build fails with the message:
Unable to merge android manifests...
Edit 2
The OVRPlugin causes this issue and at the moment.
https://forum.unity3d.com/threads/how-to-remove-android-permission-read_external_storage.429369/
Unity forums say it is unlikely to fix. Maybe there are still some workarounds?
Edit 3
Oculus is working on it, we should receive a fix in February
https://forums.oculus.com/developer/discussion/42465/is-android-permission-read-external-storage-a-must-when-using-unity#latest
I stumble upon this some time ago and still not sure why Unity builds ask for those permissions. Anyway to get rid of them you can use an editor script as a workaround:
protected void BuildAPKCustom(string buildPath)
{
bool manifestFileExists = false;
if(File.Exists(Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml")))
{
manifestFileExists = true;
File.Copy(Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml"), Path.Combine(Application.dataPath, "Plugins/Android/tmpManifestFile.xml"));
File.Delete(Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml"));
}
string[] levels = new string[EditorSceneManager.sceneCount];
for (int i = 0; i < levels.Length; i++)
{
levels[i] = EditorSceneManager.GetSceneAt(i).path;
}
BuildPipeline.BuildPlayer(levels, buildPath, BuildTarget.Android, BuildOptions.None);
XNamespace android = "http://schemas.android.com/apk/res/android";
string generatedXMLFilePath = Path.Combine(Application.dataPath, "../Temp/StagingArea/AndroidManifest.xml");
XDocument doc = XDocument.Load(generatedXMLFilePath);
IEnumerable<XElement> permissionElements = doc.Root.Elements("uses-permission");
foreach(XElement permission in permissionElements)
{
int potentialIndex = PERMISSIONS_NAMES_TO_DELETE.IndexOf(permission.Attribute(android + "name").Value.Replace("android.permission.", ""));
if(potentialIndex >= 0)
{
UnityEngine.Debug.Log("Permission deleted : " + PERMISSIONS_NAMES_TO_DELETE[potentialIndex]);
permission.Remove();
}
}
XElement overwritenPermission;
for(int i = 0; i < PERMISSIONS_NAMES_TO_DELETE.Length; i++)
{
overwritenPermission = new XElement("uses-permission");
overwritenPermission.Add(new XAttribute(android + "name", "android.permission." + PERMISSIONS_NAMES_TO_DELETE[i]));
overwritenPermission.Add(new XAttribute(android + "maxSdkVersion", "18"));
doc.Element("manifest").Add(overwritenPermission);
}
if(!Directory.Exists(Path.Combine(Application.dataPath, "Plugins/Android")))
{
Directory.CreateDirectory(Path.Combine(Application.dataPath, "Plugins/Android"));
}
doc.Save(Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml"));
BuildPipeline.BuildPlayer(levels, buildPath, BuildTarget.Android, BuildOptions.None);
if(manifestFileExists)
{
File.Delete(Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml"));
File.Copy(Path.Combine(Application.dataPath, "Plugins/Android/tmpManifestFile.xml"), Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml"));
File.Delete(Path.Combine(Application.dataPath, "Plugins/Android/tmpManifestFile.xml"));
}
Process.Start(Path.GetDirectoryName(buildPath));
}
(PERMISSIONS_NAMES_TO_DELETE being a string[] of the permissions names to delete. To get the permissions names list you can look here)
What it does is:
get the previous AndroidManifest.xml file (if it exists) in /Android/Plugins/ folder, copy it to a temporary one and delete it
perform a first build to let Unity generate an AndroidManifest.xml file on his own
edit the manifest to "delete" unnecessary permissions
save the edited manifest to /Android/Plugins/
perform a second build with a correctly set manifest
The idea behind the permission deletion is to set the maximum API level to such a lower level, the permissions will not be usable (please note the permission MUST exists at this API level).
Hope this helps,