Categories
discuss

Android activity cannot resolve symbol ACCESS_BACKGROUND_LOCATION

I am trying to check permission for access to background location.

I have already visited this Cannot resolve Manifest.permission.ACCESS_FINE_LOCATION and I have examined all the provided solutions. None of them solved my issue.

Here is my code in Manifest file:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

and here is how I am trying to check the permission:

boolean backgroundLocationPermissionApproved =
       ActivityCompat.checkSelfPermission(this,
           permission.ACCESS_BACKGROUND_LOCATION)
           == PackageManager.PERMISSION_GRANTED;

I am getting this error:

error: cannot find symbol static checkBackGroundLocationPermissions

Any thoughts would be appreciated.

Answer

I found the answer to my own question. So I am posting it here in case somebody else has the same problem.

Basically I was trying to ask permission for a background location tracking. It turned out that asking for permission is a requirement only if you have upgraded your app to work with Android 10 (Android Q). To check if your app needs permission, simply go to build.gradle file and check your targetSdkVersion. If it is anything below 29, like in my case which is 27, then you don’t need to check permission for background location tracking. However, it is a good practice to upgrade your app to work with Android 10 by setting your targetSdkVersion to 29 and upgrading all your dependencies.

To some up this answer, I couldn’t get ACCESS_BACKGROUND_LOCATION simply because the android.Manifest doesn’t support that permission if you have not upgraded your app to sdk 29. For more information consider visiting the following page: https://developer.android.com/about/versions/10/privacy/changes

NOTE: As indicated by @LordParsley’s comment:

  • Changing compileSdkVersion (not just targetSdkVersion) is needed.
Categories
discuss

Cypress expect element to contain one string or another string

I’m trying to do some Cypress assertions to see whether or not it contains one or another string. It can be in English or Spanish, so either one should pass the test.

cy.get(el).should('contain', 'submit').or('contain', 'enviar')

obviously doesnt work.

  const runout = ['submit', 'enviar']
  const el = '[data-test=btn-submit]'
  function checkArray(arr, el) {
    for(let i = 0; i < arr.length; i++) {
      if(cy.get(el).contains(arr[i])) {
        return true
      } else {
        if (i === arr.length) {
          return false
        }
      }
    }
  }
  cy.expect(checkArray(runout,el)).to.be.true

fails the test, still checking both strings.

Answer

You can try a regular expression, see contains#Regular-Expression.

See this question Regular expression containing one word or another for some formats

I think something as simple as this will do it,

cy.get(el).contains(/submit|enviar/g)

Experiment first on Regex101 or similar online tester.

Maybe build it with

const runout = ['submit', 'enviar']
const regex = new RegExp(`${runout.join('|')}`, 'g')
cy.get(el).contains(regex)
Categories
discuss

Testing Spring Boot Library Modules

I got a multi module project where not every module is actually an application but a lot of them are libs. Those libs are doing the major work and I want to test them where they are implemented. The current dependencies of the libs:

implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'

In the main source is a class with @Configuration and a single bean:

@Bean public String testString() { return "A Test String"; }

I got 2 test classes:

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles({"default", "test"}) 
public class Test1 {  

    @Test
    public void conextLoaded() {
    }
}

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles({"default", "test"}) 
public class Test2 {  
    @Autowired
    private String testString; 

    @Test
    public void conextLoaded() {
    }
}

The first test works. The second does not. There is not @SpringBootApplication anywhere in that project so in the same package as the Tests I added a test configuration:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.to.config") 
public class LibTestConfiguration {
}

And it does not work. Same for classes that are @Service. They are not in the context. How can I make it behave like a normal Spring boot application without it actually beeing one and load the configs and contexts from the configurations files I need? The default and test profile share most of their properties (for now) and I want them to be loaded like I would start a tomcat.

Answer

I switched to JUnit 5 and made it kinda work… So if you want to test Database stuff:

@DataMongoTest
@ExtendWith(SpringExtension.class)
@ActiveProfiles({"default", "test"})
class BasicMongoTest { ... }
  • Lets you autowire all repositories and mongo template
  • Initializes with apllicaton.yml config
  • Does NOT initialize or configure interceptors

Full application context test if you have a class with @SpringBootApplication in your classpath (Can be an empty test main in your test context)

@SpringBootTest
@ExtendWith(SpringExtension.class)
@ActiveProfiles({"default", "test"})
public class FullContextTest { ... }
  • Initializes the full context with all configs and beans
  • Should not be done if not necessary as it loads all the application context and kinda defeats the purpose of unit tests to only activate whats needed.

Test only specific components and configs:

@SpringBootTest(classes = {Config1.class, Component1.class})
@EnableConfigurationProperties
@ExtendWith(SpringExtension.class)
@ActiveProfiles({"default", "test"})
public class SpecificComponentsTest { ... }
  • Initializes the context with only the Config1 and Component1 classes. Component1 and all beans in Config1 can be autowired.
Categories
discuss

Android Studio does not have write access

I am using android studio 3.4.2. When I try to update
the android studio it says

“Studio does not have write access to /app/extra. Please Run it by a privileged user to update”

How to solve it?

enter image description here

Answer

Navigate to your Android studio folder via terminal then run android studio with administrator privileges, using sudo or su. If you provide more information, like which OS you are using, maybe I’ll be able to tell you the exactly command line you should use.

Edit:

  1. Open terminal application, then type de following :
    cd ~/android-studio/bin *

  2. Now we must run Android Studio script file studio.sh as administrator:

sudo ./studio.sh

If doesn’t work try : sudo sh studio.sh

  1. (Optional) To prevent this problem every time you want update android studio, see https://stackoverflow.com/a/37704528/8513494

And is it.

  • I’m assuming that your android studio is located on your user folder, if there’s a problem with this step, you should check /opt/ directory and look out for android studio installation folder or see https://superuser.com/a/1080329
Categories
discuss

Use external JavaScript library in Angular 8 application

I am new to Angular and i want to develop a funnel-graph. i like the funnel-graph-js library. i tried a lot but haven’t succeed.

here is my funnel-graph-directive.ts

import { Directive, ElementRef } from '@angular/core';

// import * as graph from '../../../assets/js/funnel-graph.js';
import * as graph from 'funnel-graph-js/dist/js/funnel-graph.js';
var graph = new FunnelGraph({
  container: '.funnel',
  gradientDirection: 'horizontal',
  data: {
    labels: ['Impressions', 'Add To Cart', 'Buy'],
    subLabels: ['Direct', 'Social Media', 'Ads'],
    colors: [
      ['#FFB178', '#FF78B1', '#FF3C8E'],
      ['#A0BBFF', '#EC77FF'],
      ['#A0F9FF', '#7795FF']
    ],
    values: [
      [3500, 2500, 6500],
      [3300, 1400, 1000],
      [600, 200, 130]
    ]
  },
  displayPercent: true,
  direction: 'horizontal'
});

graph.draw();
@Directive({
  selector: '[appFunnelGraph]'
})
export class FunnelGraphDirective {
  style: any;
  constructor(el: ElementRef) {
    el.nativeElement.style.backgroundColor = 'yellow';
  }
}

I have added these lines in my angular.json

"styles": [
  "src/styles.scss",
  "./node_modules/funnel-graph-js/dist/css/main.css",
  "./node_modules/funnel-graph-js/dist/css/theme.css"
],
"scripts": [
  "./node_modules/funnel-graph-js/dist/js/funnel-graph.js"
]

Here is the error i am getting enter image description here

Answer

I ended up by creating service instead of using directive approach.

  • First i generated a service called dynamic-script-loader-service in my dashboard module.

dynamic-service-loader.service.service.ts

import { Injectable } from '@angular/core';

interface Scripts {
  name: string;
  src: string;
}

export const ScriptStore: Scripts[] = [
  { name: 'chartjs', src: 'https://unpkg.com/funnel-graph-js@1.3.9/dist/js/funnel-graph.min.js' },
];

declare var document: any;

@Injectable()
export class DynamicScriptLoaderServiceService {

  private scripts: any = {};

  constructor() {
    ScriptStore.forEach((script: any) => {
      this.scripts[script.name] = {
        loaded: false,
        src: script.src
      };
    });
  }

  load(...scripts: string[]) {
    const promises: any[] = [];
    scripts.forEach((script) => promises.push(this.loadScript(script)));
    return Promise.all(promises);
  }

  loadScript(name: string) {
    return new Promise((resolve, reject) => {
      if (!this.scripts[name].loaded) {
        //load script
        let script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = this.scripts[name].src;
        if (script.readyState) {  //IE
          script.onreadystatechange = () => {
            if (script.readyState === 'loaded' || script.readyState === 'complete') {
              script.onreadystatechange = null;
              this.scripts[name].loaded = true;
              resolve({ script: name, loaded: true, status: 'Loaded' });
            }
          };
        } else {  //Others
          script.onload = () => {
            this.scripts[name].loaded = true;
            resolve({ script: name, loaded: true, status: 'Loaded' });
          };
        }
        script.onerror = (error: any) => resolve({ script: name, loaded: false, status: 'Loaded' });
        document.getElementsByTagName('head')[0].appendChild(script);
      } else {
        resolve({ script: name, loaded: true, status: 'Already Loaded' });
      }
    });
  }

}

dashboard.component.ts

import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { DynamicScriptLoaderServiceService } from '../dynamic-script-loader-service.service';
import * as FunnelGraph from 'funnel-graph-js';

function dashboardFunnel() {
  const graph = new FunnelGraph({
    container: '.funnel',
    // gradientDirection: 'horizontal',
    data: {
      labels: ['Label 7', 'Label 1', 'Label 2', 'Label 3', 'Label 4', 'Label 5', 'Label 6'],
      colors: ['#00A8FF', '#00A8FF', '#00A8FF', '#00A8FF', '#00A8FF', '#00A8FF', '#00A8FF'],
      // color: '#00A8FF',
      values: [12000, 11000, 10000, 9000, 8000, 7000, 6000]
    },
    displayPercent: true,
    direction: 'horizontal',
  });

  graph.draw();
}

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class DashboardComponent implements OnInit {

  constructor(
    private dynamicScriptLoader: DynamicScriptLoaderServiceService
  ) {}


  ngOnInit() {
    this.loadScripts();
    dashboardFunnel();
  }

  private loadScripts() {
    // You can load multiple scripts by just providing the key as argument into load method of the service
    this.dynamicScriptLoader.load('chartjs', 'random-num').then(data => {
      // Script Loaded Successfully
    }).catch(error => console.log(error));
  }

}

added providers in my dashboard.module.ts

providers: [DynamicScriptLoaderServiceService],

added css in my angular.json

"styles": [
              "src/styles.scss",
              "./node_modules/funnel-graph-js/dist/css/main.css",
              "./node_modules/funnel-graph-js/dist/css/theme.css"
            ],

added div with class funnel in dashboard.component.html

<div class="funnel"></div>
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..