Expo IntentLauncher can't open Application_Details_Settings - javascript

I want to open the details settings of my application from the app itself.
I use the IntentLauncher from Expo itself: https://docs.expo.io/versions/latest/sdk/intent-launcher
The code I use that I assume should work is:
IntentLauncher.startActivityAsync(IntentLauncher.ACTION_APPLICATION_DETAILS_SETTINGS)
But this gives me this error:
[Unhandled promise rejection: Error: Encountered an exception while calling native method: Exception occurred while executing exported method startActivity on module ExpoIntentLauncher: null]
I'm not sure if I should give some kind of parameter with it so it links to my app?
Opening all other settings does work, ex:
IntentLauncher.startActivityAsync(IntentLauncher.ACTION_APPLICATION_SETTINGS)
This does open a list off all apps, I just need to get the detailed screen of the app itself, not the list.

I found this solution by bodolsog working.
Complete solution
import * as IntentLauncher from "expo-intent-launcher";
import Constants from "expo-constants";
const pkg = Constants.manifest.releaseChannel
? Constants.manifest.android.package // When published, considered as using standalone build
: "host.exp.exponent"; // In expo client mode
IntentLauncherAndroid.startActivityAsync(
IntentLauncherAndroid.ACTION_APPLICATION_DETAILS_SETTINGS,
{ data: 'package:' + pkg },
)

Hope this helps someone
import { startActivityAsync, ActivityAction } from 'expo-intent-launcher';
import * as Linking from 'expo-linking';
import Constants from 'expo-constants';
const pkg = Constants.manifest.releaseChannel
? Constants.manifest.android.package // When published, considered as using standalone build
: 'host.exp.exponent'; // In expo client mode
openSettings = async () => {
try {
if (Platform.OS === 'android') {
// console.log(Constants);
startActivityAsync(ActivityAction.APPLICATION_DETAILS_SETTINGS, {
data: 'package:' + pkg,
});
}
if (Platform.OS === 'ios') {
Linking.openSettings();
}
} catch (error) {
console.log(error);
}
};

Related

SvelteKit Maintenance Mode

Is there a good way to do display a maintenance page when visiting any route of my SvelteKit website?
My app is hosted on Vercel, for those who want to know.
What I've tried so far:
Set an environment variable called MAINTENANCE_MODE with a value 1 in Vercel.
For development purposes I've set this in my .env file to VITE_MAINTENANCE_MODE and called with import.meta.env.VITE_MAINTENANCE_MODE.
Then inside +layout.server.js I have the following code to redirect to /maintenance route
import { redirect } from "#sveltejs/kit";
export async function load({ url }) {
const { pathname } = url;
// Replace import.meta.env.VITE_MAINTENANCE_MODE with process.env.MAINTENANCE_MODE in Production
if (import.meta.env.VITE_MAINTENANCE_MODE == 1) {
if (pathname == "/maintenance") return;
throw redirect(307, "/maintenance");
  } else {
if (pathname == "/maintenance") {
throw redirect(307, "/");
    };
  };
};
What I've also tried is just throwing an error in +layout.server.js with the following:
import { error } from "#sveltejs/kit";
export async function load() {
if (import.meta.env.VITE_MAINTENANCE_MODE == 1) {
throw error(503, "Scheduled for maintenance");
  };
};
However this just uses SvelteKit's static fallback error page and not +error.svelte. I've tried creating src/error.html in the hope to create a custom error page for +layout.svelte but couldn't get it to work.
I would like to use a custom page to display "Down for maintenance", but I don't want to create an endpoint for every route in my app to check if the MAINTENANCE_MODE is set to 1.
Any help is appreciated
You could use a handle server hook, e.g. src/hooks.server.ts:
import { env } from '$env/dynamic/private';
import type { Handle } from '#sveltejs/kit';
export const handle: Handle = async ({ event, resolve }) => {
if (env.MAINTENANCE_MODE == '1' && event.routeId != '/maintenance')
return new Response(undefined, { status: 302, headers: { location: '/maintenance' } });
// <other logic>
// Default response
return await resolve(event);
}
And on the maintenance page you can prevent all further navigation:
import { beforeNavigate } from '$app/navigation';
beforeNavigate(async ({ cancel }) => {
cancel();
});
(Possibly add some periodic checks via fetch calls to navigate elsewhere once the site is back online.)
You can also use +layout.ts to hook up for the maintenance mode. You can even make this conditional for some parts of the site (have frontpage still up and running).
Here is the trick we use:
import type { LayoutLoad } from './$types';
import { chainsUnderMaintenance } from '$lib/config';
import { error } from '#sveltejs/kit';
export const load: LayoutLoad = ({ params }) => {
// Check chain maintenance status; if under maintenance, trigger error (see +error.svelte)
const chainName = chainsUnderMaintenance[<string>params.chain];
if (chainName) {
throw error(503, `Chain under maintenance: ${chainName}`);
}
};

'X Is not a function' in CommonJS

I've got the following code I transformed from a Trypescript, ESM-syntax based file to a Javascript, CJS-syntax file.
const apiClientFactory = require("#vue-storefront/core");
function onCreate(settings) {
return {
config: settings,
client: {},
};
}
const getPrice = () => {
console.log("$55,98")
}
const { createApiClient } = apiClientFactory({
onCreate,
api: {
getPrice,
},
});
module.exports = {
createApiClient,
};
I can not seem to find if the error "apiClientFactory is not a function" originates from old ESM-based code. Or that the function isn't called properly. However, apiClientFactory is correctly imported (ESM syntax)
What are you trying to achieve with this?
Because the whole Vue Storefront project uses TypeScript, so I recommend you to use it and follow the procedures and code standards that we are using.
To find a good example on the API please check the code for the integrations of Magento or Vendure.

React Native (Android) Accessing foreground location updates triggers "Not Authorized to use background location services" error

Background
Hey everyone,
I am building a group bicycle riding app that shows users where they are in a map in real time.
Short app explanation is: You go out with friends for hiking, cycling, etc, and you want to know where you and your friends are in real time.
The only requirement is a foreground location access when the app is in use, no more. Then, I want to update each member's location using Location.startLocationUpdatesAsync().
Sample Code
import React from 'react'
import { Text, TouchableOpacity } from 'react-native'
import * as Location from 'expo-location';
import * as TaskManager from 'expo-task-manager';
const LOCATION_TASK_NAME = 'background-location-task';
TaskManager.defineTask(LOCATION_TASK_NAME, ({ data, error }) => {
if (error) {
console.log(error);
return;
}
if (data) {
const { locations } = data;
console.log(data);
}
});
const requestPermissions = async () => {
const { status } = await Location.requestForegroundPermissionsAsync();
if (status === 'granted') {
await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
accuracy: Location.Accuracy.Balanced,
});
}
};
const HomeScreen = () => {
return (
<TouchableOpacity onPress={requestPermissions}>
<Text>Enable Location</Text>
</TouchableOpacity>
)
}
export default HomeScreen
Problem
Foreground permission (Location.requestForegroundPermissionsAsync()) popup appears on the screen with no problem. Access is granted. When run, this error comes up:
Error: Not authorized to use background location services.
The problem is I need a background permission to be able to update location information in real time. When I try to request for background permission with requestBackgroundPermissionsAsync(), this error comes up:
Error: You need to add `ACCESS_BACKGROUND_LOCATION` to the AndroidManifest.
I don't know if AndroidManifest file should be changed with expo apps, but I added permissions key to android inside app.json file like so:
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#FFFFFF"
},
"permissions":[
"ACCESS_FINE_LOCATION",
"ACCESS_BACKGROUND_LOCATION",
"ACCESS_COARSE_LOCATION"
]
}
I have looked into an open issue on expo's github repo. It does not seem to help. I have 0 intention of putting my app on Play Store.
Questions
Do I need to go through google's verification process by filling up the form, taking video of my app which is under development and won't ever be put on Play Store?
Am I even allowed to test the feature before even thinking about releasing it?
What approach should I take to just get location updates?
Is there any workaround?
What I tried
requesting for Background Location acess by Location.requestBackgroundPermissionsAsync()
putting permissions key inside app.json:
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#FFFFFF"
},
"permissions":[
"ACCESS_FINE_LOCATION",
"ACCESS_BACKGROUND_LOCATION",
"ACCESS_COARSE_LOCATION"
]
}
checking for background permission and asking for it if not granted:
const { fr_status } = await Location.requestBackgroundPermissionsAsync();
if (fr_status === 'granted' && await Location.isBackgroundLocationAvailableAsync()) {
await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
accuracy: Location.Accuracy.Balanced,
});
} else {
const {bg_status} = await Location.requestBackgroundPermissionsAsync();
if (bg_status === 'granted') {
await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
accuracy: Location.Accuracy.Balanced,
});
}
}
Development environment
Managed app built with expo 4.13.0.
Android Emulator 31.1.4
Android SDK Platform Tools 31.0.3
Android 10.0 Q, API level 29, revision 5
Node.js v16.13.0
npm version 8.1.0
react-native version 0.64.3
Windows 10 Pro version 20H2

API client in Javascript

I need a little help to solve a problem in my project.
Scenario:
First: I have a SPA web site that is being developed in Vue.js.
Second: I also have a Web API spec in Swagger that I want to use to generate my client code in Javascript.
Lastly: I'm using swagger-codegen-cli.jar for that.
What I've done until now
1 - Download the last swagger-codegen-cli.jar stable version with javascript support:
curl http://central.maven.org/maven2/io/swagger/swagger-codegen-cli/2.4.7/swagger-codegen-cli-2.4.7.jar -o swagger-codegen-cli.jar
2 - Generate the client code using:
java -jar swagger-codegen-cli.jar generate -i http://192.168.0.85:32839/api/swagger/v1/swagger.json -l javascript -o ./web_api_client/
3 - Add the generated module to my project:
"dependencies": {
// ...
"vue": "^2.6.10",
"vue-router": "^3.0.3",
"web_api_client": "file:./web_api_client"
},
4 - Execute npm install. Apparently, it's working fine.
5 - At this moment I faced the problem. For some reason, the module generated isn't loaded completely.
export default {
name: 'home',
components: {
HelloWorld
},
mounted() {
var WebApiClient = require("web_api_client");
var defaultClient = WebApiClient.ApiClient.instance;
var oauth2 = defaultClient.authentications["oauth2"];
oauth2.accessToken = "YOUR ACCESS TOKEN";
var apiInstance = new WebApiClient.VersaoApi();
var callback = function(error, data, response) {
if (error) {
console.error(error);
} else {
console.log('API called successfully. Returned data: ' + data);
}
};
apiInstance.apiVersaoGet(callback);
}
}
6 - The line var WebApiClient = require("web_api_client"); is working without any error, however, not working 100%. The instance of the module has been created but empty. For instance, WebApiClient.ApiClient is always undefined.
7 - I took a look at the generated code and I think the problem is related with the way the module is being loaded.
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['ApiClient', 'api/VersaoApi'], factory);
} else if (typeof module === 'object' && module.exports) {
// CommonJS-like environments that support module.exports, like Node.
module.exports = factory(require('./ApiClient'), require('./api/VersaoApi'));
}
}(function(ApiClient, VersaoApi) {
'use strict';
// ...
In this code, neither of ifs blocks are executed.
Has someone faced a problem like that?
Some advice?
Many thanks, folks.
Solution
After a while trying to fix the problem with require("web_api_client"); I decided to use ES6 instead ES5.
I found an option in swagger-codegen-cli.jar to generate the client code using ES6 as shown below:
java -jar swagger-codegen-cli.jar generate -i http://192.168.0.85:32839/api/swagger/v1/swagger.json -l javascript --additional-properties useES6=true -o ./web_api_client/
Using ES6 I was able to import the javascript module direct from the generated source as shown in the code below.
import WebApiClient from "./web_api_client/src/index";
let defaultClient = WebApiClient.ApiClient.instance;
defaultClient.basePath = 'http://192.168.0.85:32839';
// Configure OAuth2 access token for authorization: oauth2
let oauth2 = defaultClient.authentications["oauth2"];
oauth2.accessToken = "YOUR ACCESS TOKEN";
let apiInstance = new WebApiClient.VersaoApi();
apiInstance.apiVersaoGet((error, data, response) => {
if (error) {
console.error(error);
} else {
console.log("API called successfully. Returned data: " + data + response);
}
});
When I first ran the code I got an error because the module WebApiClient generated didn't have the keyword default in the export block.
Original generated code
export {
/**
* The ApiClient constructor.
* #property {module:ApiClient}
*/
ApiClient,
// ...
Alter changed
export default {
/**
* The ApiClient constructor.
* #property {module:ApiClient}
*/
ApiClient,
// ...
Now everything is working fine.

master-atul/react-native-exception-handler - does not capture errors in node_modules

I am only able to get this to work for issues at the application level, if an error is thrown from any package in the node_modules, it is not captured.
below is my GlobalErrorHandler, i have imported this into my app.js file at the top of my application so was expecting it to capture any exception in the application.
the expected behaviour would be for the this.test() exception to be thrown and from node_modules/AnotherUIDependency and captured by the globalErrorHandler
app.js
...
import { GlobalErrorHandler } from 'MASKED/globalErrorHandler'
...
globalErrorHandler.js
import { Alert } from 'react-native'
import { GlobalStrings } from 'MASKED'
import RNExitApp from 'react-native-exit-app'
import {
setJSExceptionHandler,
setNativeExceptionHandler
} from 'react-native-exception-handler'
errorHandler = (e, isFatal) => {
Alert.alert(
GlobalStrings.globalErrorHandler.title,
// eslint-disable-next-line no-undef
errorMessage(e, isFatal, __DEV__),
[
{
text: GlobalStrings.globalErrorHandler.exit,
onPress: () => {
RNExitApp.exitApp()
}
}
],
{ cancelable: false }
)
}
errorMessage = (e, isFatal, isDev) => {
let val = null
if (isDev) {
val =
GlobalStrings.globalErrorHandler.error +
`: ${isFatal ? GlobalStrings.globalErrorHandler.fatal : ''}` +
'\n\n' +
e.name +
':' +
e.message
} else {
if (!isFatal) {
val = GlobalStrings.globalErrorHandler.exceptionMessage
} else {
val = GlobalStrings.globalErrorHandler.nonFatal + ': ' + e
}
}
return val
}
setJSExceptionHandler(errorHandler, true)
setNativeExceptionHandler(errorString => {
Alert.alert(
GlobalStrings.globalErrorHandler.nativeExceptionMessage + ': ' + errorString
)
})
node_modules/AnotherUIDependency
...
export default class myComponent extends Component {
render(
return{
this.test() // expected globalErrorHandler capture
...
}
)
}
I think it may be my usage, however, i found that i had to import my globalErrorHandler at the top of the index file of each package in my project.
I found that even if i implemented it as the docs suggest, it was not truly global as it still would not capture node_module level exceptions. I would seem that the handler only picks up exceptions where it can follow the imports to the file where the exception occurs.
In my case, we have some weird referencing going on which i think is preventiung this. I have the same issue even if i use the React-Native ErrorUtils global
You're wrong about how to get the module in.
Usage
To catch JS_Exceptions
import {setJSExceptionHandler, getJSExceptionHandler} from 'react-native-exception-handler';
.
.
// For most use cases:
// registering the error handler (maybe u can do this in the index.android.js or index.ios.js)
setJSExceptionHandler((error, isFatal) => {
// This is your custom global error handler
// You do stuff like show an error dialog
// or hit google analytics to track crashes
// or hit a custom api to inform the dev team.
});
//=================================================
// ADVANCED use case:
const exceptionhandler = (error, isFatal) => {
// your error handler function
};
setJSExceptionHandler(exceptionhandler, allowInDevMode);
// - exceptionhandler is the exception handler function
// - allowInDevMode is an optional parameter is a boolean.
// If set to true the handler to be called in place of RED screen
// in development mode also.
// getJSExceptionHandler gives the currently set JS exception handler
const currentHandler = getJSExceptionHandler();
To catch Native_Exceptions
import { setNativeExceptionHandler } from "react-native-exception-handler";
//For most use cases:
setNativeExceptionHandler(exceptionString => {
// This is your custom global error handler
// You do stuff likehit google analytics to track crashes.
// or hit a custom api to inform the dev team.
//NOTE: alert or showing any UI change via JS
//WILL NOT WORK in case of NATIVE ERRORS.
});
//====================================================
// ADVANCED use case:
const exceptionhandler = exceptionString => {
// your exception handler code here
};
setNativeExceptionHandler(
exceptionhandler,
forceAppQuit,
executeDefaultHandler
);
// - exceptionhandler is the exception handler function
// - forceAppQuit is an optional ANDROID specific parameter that defines
// if the app should be force quit on error. default value is true.
// To see usecase check the common issues section.
// - executeDefaultHandler is an optional boolean (both IOS, ANDROID)
// It executes previous exception handlers if set by some other module.
// It will come handy when you use any other crash analytics module along with this one
// Default value is set to false. Set to true if you are using other analytics modules.

Categories

Resources