GeofencingClient take lot of time in adding the geofences - android

I have a feature that depends on GeoFencing Technology There is a weird problem. On adding a Geofence, the client takes a lot of time to add (Have a look at logs). This is weird as it works pretty well earlier (no code change related to location and all afaik) without any delay.
I am using the following dependency:
'com.google.android.gms:play-services-location:16.0.0'
#RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION)
fun addGeoFences(
geoFences: ArrayList<Geofence>,
onSuccess: () -> Unit = {},
onFailure: (Exception) -> Unit = {}
): Boolean {
if (isAddingGeofence) {
GlobalLoggerUtils.showLog(TAG, "isAddingGeofence: $isAddingGeofence")
return false
}
GlobalLoggerUtils.showLog(TAG, "addGeoFences()")
if (geoFences.size == 0) {
return false
}
isAddingGeofence = true
geoFencingClient
.addGeofences(
getGeoFencingRequest(geoFences),
geoFencePendingIntent
).addOnSuccessListener { result ->
isAddingGeofence = false
}
.addOnFailureListener { exception ->
isAddingGeofence = false
}
.addOnCanceledListener {
isAddingGeofence = false
}
return true
}
2019-05-30 12:43:29.716 I/: addGeoFences()
2019-05-30 12:44:00.602 I/: isAddingGeofence: true
2019-05-30 12:44:02.424 I/: isAddingGeofence: true
2019-05-30 12:44:03.525 I/: isAddingGeofence: true
2019-05-30 12:44:04.975 I/: isAddingGeofence: true
2019-05-30 12:44:06.541 I/: isAddingGeofence: true
2019-05-30 12:48:18.384 I/: add success >>> result: null
2019-05-30 12:48:18.393 I/: add success >>> requestIds: XYZ
Let me know if there anything required to add in context to this problem. Adding the Geofence is as per the official Android documentation.
Edit #1: 05 June 2019
Looks like this happen in development build only. Works fine in
release build installed from play store.

If it's Android 8.0+, be aware that there is a background location restriction that also applies to the Geofencing APIenter link description here

Related

onbeforeinstallprompt fails to fire

I'm building a PWA and have the following hooked event
let isCompat = "onbeforeinstallprompt" in window,
isSamsung = /Samsung/i.test(_ua)
if (!window.matchMedia('(display-mode: fullscreen)').matches
&& !window.matchMedia('(display-mode: standalone)').matches
&& !screenfull.isFullscreen
) {
console.log(isCompat, isSamsung, screenfull)
if(isCompat) {
window.addEventListener('beforeinstallprompt', (event) => {
...
btn.addEventListener('click', () => {
let s = invite.prompt()
if(invite.userChoice) ...
}, { once: true })
event.preventDefault()
invite = event
})
} else {
if(isIDevice) {
....
} else if(screenfull.isEnabled) {
...
}
}
The logic executes successful on latest chrome for android on a Samsung J5 1st generation. But not on the latest updated of Samsung Internet Browser 16.2.1.56 regardless of the fact that isCompat and isSamsung is true
My research so far shows that is should be firing so I am not sure why. Is there a shim that can be implemented to make it work on Samsung Internet?
an example and be viewed at https://622f59ba2b54ab2a844cf515--goofy-jackson-e12a89.netlify.app/

Flutter Virgil E3 Kit not working in release mode but working in debug

I am trying to implement Virgil e3 Kit into my flutter app for end to end encryption. When running the code and signing up in debug mode the EThree Kit is working perfectly however when I try and run in release mode I get an exception when registering the user with EThree Kit.
This is the package: https://github.com/cardoso/virgil-e3kit-flutter
This is the error:
Failed to register user for encryption system: PlatformException(unknown_error, Http response: 400 : Bad Request Service response: 40200 : Identity search parameter cannot be empty., null, null)
I thought that this was something to do with cleartext traffic so I enabled that in my androidManifest but it still did not work
This is the code I am calling:
Signup
final firebaseUser = await _firebaseAuth.createUserWithEmailAndPassword(
email: email, password: password);
await EncryptionUtils.initialize(_firebaseAuth.currentUser.uid);
await EncryptionUtils.register();
await EncryptionUtils.backupPrivateKey(
'${_firebaseAuth.currentUser.uid}...$password');
Initialize
static Future<void> initialize(String uid) async {
if (_eThree != null) return;
final tokenCallback = () async {
final response = (await FirebaseFunctions.instance
.httpsCallable('getVirgilJwt')
.call())
.data;
final Map<String, dynamic> data = Map<String, dynamic>.from(response);
print('[encryption tokenCallback] - ${data['token']}');
return data['token'];
};
try {
if (uid == null || uid.isEmpty) {
throw Exception('user-id not valid');
}
_eThree = await EThree.init(uid, tokenCallback);
print('[ENCRYPTION UTILS] - (initialize) initialized successfully');
} catch (err) {
print('[ENCRYPTION UTILS] - Failed initializing: $err');
throw Exception('Failed to intialize end to end encryption system');
}
}
Register
static Future<void> register() async {
try {
await _eThree.cleanUp();
print('[ENCRYPTION UTILS] - (Register) cleaned up successfully');
} catch (err) {
print('[ENCRYPTION UTILS] - (Register) failed to cleanup');
}
try {
print(
'[encryption register] - trying to register ${await _eThree.identity}');
await _eThree.register();
print('[ENCRYPTION UTILS] - registered successfully');
} on PlatformException catch (err) {
if (err.code == 'user_is_already_registered') {
await _eThree.rotatePrivateKey();
print('Rotated private key instead');
}
print('Failed to register user for encryption system: $err');
throw Exception('Failed to register user for encryption system: $err');
}
}
Thank you in advance!
I know this is an old question, but I ran into the same problem and wanted to share my solution. I added the following lines in the Android app's build.gradle file to prevent bundle size optimization. You can find the same configuration in the Virgil Android SDK sample apps.
buildTypes {
release {
...
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

React Native check if app notification enabled on Android

User is able to turn off app notification on Android. Is there a way to check if the user did so?
The React Native doc did not mention Notification permission as it's not a permission that requires prompting the user.
Android docs did mention the ability to access notification policy.
I have used this one in previous experiences with good results:
https://github.com/jigaryadav/react-native-check-notification-enable
Basically what I ended up implementing as helpers were this two functions:
export const getNotificationStatus = async () => {
if (Platform.OS === 'ios') {
const status = await Permissions.check(PermissionRequested.NOTIFICATION)
if (status === PermissionsStatus.AUTHORIZED) {
return true
} else {
return false
}
} else {
// This is where I am using the library
const status = await NotificationManager.areNotificationsEnabled()
return status
}
}
export const openNotificationsSettings = () => {
if (Platform.OS === 'ios') {
Linking.openURL('app-settings:')
} else {
AndroidOpenSettings.appNotificationSettings()
}
}
Just to explain a bit the whole snippet:
I am also using these libraries in conjunction to achieve all: Check if they are enabled and navigate to the settings page to revoke if needed
import AndroidOpenSettings from 'react-native-android-open-settings'
import NotificationManager from 'react-native-check-notification-enable'
import Permissions from 'react-native-permissions'
I have found one library called React-native-permission-settings
It is available for android only so if you need iOS support also i think you need to modify it.
You can follow installation guide from here
And implement it in your code
import NotificationSettings from 'react-native-permission-settings';
...
NotificationSettings.areNotificationsEnabled((isEnabled: boolean) => {
console.log(`Notifications are enabled: ${isEnabled}`);
});

Android Gradle Jacoco: offline instrumentation for integration tests

we are building an Android app which is tested by using Appium. Now I would like to see the test coverage of our Appium tests.
I think this is possible, because Jacoco supports offline instrumentation (http://www.eclemma.org/jacoco/trunk/doc/offline.html).
And even the documentation of the jacoco gradle plugin says:
While all tasks of type Test are automatically enhanced to provide coverage information when the java plugin has been applied, any task that implements JavaForkOptions can be enhanced by the JaCoCo plugin. That is, any task that forks Java processes can be used to generate coverage information.
see https://docs.gradle.org/current/userguide/jacoco_plugin.html
But how do I have to write the build.gradle so our acceptance debug flavor is instrumented and the exec file is written to the Smartphone when the Appium tests are executed or even manual test cases are executed?
Because then I can extract the exec file and send it so SonarQube for further analysis.
Thanks
Ben
Finally I managed it to get it working and I want to share the solution with you:
enable instrumentation for your buildType and configure SonarQube accordingly
e.g.
...
apply plugin: 'jacoco'
...
android {
...
productFlavors {
acceptance {
applicationId packageName + ".acceptance"
buildTypes {
debug {
testCoverageEnabled true
}
}
}
}
}
sonarRunner {
sonarProperties {
property "sonar.host.url", "..."
property "sonar.jdbc.url", sonarDatabaseUrl
property "sonar.jdbc.driverClassName", sonarDatabaseDriverClassName
property "sonar.jdbc.username", sonarDatabaseUsername
property "sonar.jdbc.password", sonarDatabasePassword
property "sonar.sourceEncoding", "UTF-8"
property "sonar.sources", "src/main"
property "sonar.tests", "src/test"
property "sonar.inclusions", "**/*.java,**/*.xml"
property "sonar.import_unknown_files", "true"
property "sonar.java.binaries", "build/intermediates/classes/acceptance/debug"
property "sonar.junit.reportsPath", "build/test-results/acceptanceDebug"
property "sonar.android.lint.report", "build/outputs/lint-results.xml"
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.jacoco.reportPath", "build/jacoco/testAcceptanceDebugUnitTest.exec"
// see steps below on how to get that file:
property "sonar.jacoco.itReportPath", "build/jacoco/jacoco-it.exec"
property "sonar.projectKey", projectKey
property "sonar.projectName", projectName
property "sonar.projectVersion", appVersionName
}
}
add the following to your AndroidManifest.xml
<receiver
android:name=".util.CoverageDataDumper"
tools:ignore="ExportedReceiver">
<intent-filter>
<action android:name="org.example.DUMP_COVERAGE_DATA"/>
</intent-filter>
</receiver>
CoverageDataDumper should look like that:
public class CoverageDataDumper extends BroadcastReceiver {
private static final Logger LOG = LoggerFactory.getLogger( CoverageDataDumper.class );
#Override
public void onReceive( Context context, Intent intent ) {
try {
Class
.forName( "com.vladium.emma.rt.RT" )
.getMethod( "dumpCoverageData", File.class, boolean.class, boolean.class )
.invoke( null,
new File( App.getContext().getExternalFilesDir( null ) + "/coverage.ec" ),
true, // merge
false // stopDataCollection
);
}
catch ( Exception e ) {
LOG.error( "Error when writing coverage data", e );
}
}
}
Then run your Appium test cases with the acceptance flavor app (with instrumented classes). Before you call "Reset App" or "Close Application" make sure to call the following methods (just a draft, but I think you get the idea):
// intent is "org.example.DUMP_COVERAGE_DATA"
public void endTestCoverage( String intent ) {
if ( driver instanceof AndroidDriver ) {
((AndroidDriver) driver).endTestCoverage( intent, "" );
}
}
public void pullCoverageData( String outputPath ) {
String coverageFilePath = (String) appiumDriver.getCapabilities().getCapability( "coverageFilePath" );
if ( coverageFilePath != null ) {
byte[] log = appiumDriver.pullFile( coverageFilePath );
MobileAppLog.writeLog( new File( outputPath ), log );
}
else {
throw new AppiumLibraryNonFatalException(
"Tried to pull the coverage data, but the coverageFilePath wasn't specified." );
}
}
outputPath could be for example: /sdcard/Android/data/org.example.acceptance/files/coverage.ec
Now the Jacoco data is written to the Smartphone. Next we need to download that file. You can use
appiumDriver.pullFile( logFilePath );
Now you need to copy the file "jacoco-it.exec" (which should always be appended when you pull the file) into build/jacoco/jacoco-it.exec see gradle.build above and run
gradlew sonarRunner
In SonarQube add the Integration Test Coverage Widget and you should see now some values...
Unfortunately code coverage won't work if you are using retrolambda (as we do). Retrolambda will generate anonymous classes which are not part of the source files - so SonarQube cannot match them correctly and displays a much lower code coverage than it actually is. If someone finds a solution for that, I would be very happy :-)
I solved this problem by adding broadcast receiver to the application you test! (you can add the receiver only to debug folder cause no need it for to exist in main source)
public class CoverageReceiver extends BroadcastReceiver {
private static final String EXEC_FILE_PATH = "/mnt/sdcard/coverage.exec";
private static final String TAG = "CoverageJacoco";
private static final String BROADCAST_RECEIVED_MESSAGE = "EndJacocoBroadcast broadcast received!";
private static final String EMMA_CLASS = "com.vladium.emma.rt.RT";
private static final String EMMA_DUMP_METHOD = "dumpCoverageData";
#Override
public void onReceive(Context context, Intent intent) {
try {
Log.d(TAG, BROADCAST_RECEIVED_MESSAGE);
Class.forName(EMMA_CLASS)
.getMethod(EMMA_DUMP_METHOD, File.class, boolean.class,
boolean.class)
.invoke(null, new File(EXEC_FILE_PATH), true,
false);
} catch (Exception e) {
Log.d(TAG, e.getMessage());
}
}
}
In manefist add (you can add this debug folder so it won't exist in main source)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application>
<receiver android:name=".CoverageReceiver">
<intent-filter>
<action android:name="com.example.action" />
</intent-filter>
</receiver>
</application>
In the build.gradle of the application I added
apply plugin: 'jacoco'
jacoco {
toolVersion = "0.7.4+"
}
model {
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.example.app"
minSdkVersion.apiLevel 23
targetSdkVersion.apiLevel 23
versionCode 12
versionName "1.11"
}
buildTypes {
debug {
testCoverageEnabled true
}
}
you build your application as debug, than install and run it.
send broadcast through ADB "adb shell am broadcast -a com.example.action" to create coverage.exec
pull coverage from device - adb pull /mnt/sdcard/coverage.exec
after you run this you need to create the coverage from the file
**
* This task is used to create a code coverage report via the Jcoco tool.
*/
task jacocoTestReport(type: JacocoReport) {
def coverageSourceDirs = [
'src/main/java',
]
group = "Reporting"
description = "Generates Jacoco coverage reports"
reports {
csv.enabled false
xml{
enabled = true
destination "${buildDir}/jacoco/jacoco.xml"
}
html{
enabled true
destination "${buildDir}/jacocoHtml"
}
}
classDirectories = fileTree(
dir: 'build/intermediates/classes',
excludes: ['**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Activity*.*',
'**/*Fragment*.*'
]
)
sourceDirectories = files(coverageSourceDirs)
executionData = files('build/coverage.exec')
}
this task is one way to create coverage files
in coverageSourceDirs add all the locations of your applicaiton source code, so it will know which code to take and create coverage based on them
executionData is the location where you put the coverage.exec you pulled from the device
Run the task
the files will created for html and xml you can also add csv (notice it will be create in the build folder of the application)!
Need to know, you must run the task against the same code you built your application debug version

Qt 5.1 Android program does not send keypresses

I am creating a program in Qt 5.1 and Qt Quick 2.0 for Android but my phone doesn't seem to send keypresses. The same code works when i run it on my desktop so the focus seems to be okay.
Both the Keys.onPressed and the Keys.onBackPressed don't work, the back key just closes the program. I am debugging on a Android 4.2 device via ADB.
Main.qml
Rectangle {
id: container
focus: true
Keys.onPressed: {
console.log(event.key)
if (event.key === Qt.Key_Backspace) {
if (rectangleDetails.visible === true) {
console.log("Left key pressed")
rectangleDetails.visible = false
listViewIndex.visible = true
event.accepted = true
} else {
Qt.quit()
}
}
}
Keys.onBackPressed: {
console.log("Back key pressed")
if (rectangleDetails.visible === true) {
rectangleDetails.visible = false
listViewIndex.visible = true
event.accepted = true
} else {
Qt.quit()
}
}
Thanks in advance
Try Keys.onReleased. This should solve your issue. See here for more information http://qt-project.org/forums/viewthread/29366

Categories

Resources