I have recently tried to intergrate the new Google Maps capacitor plugin:
https://ionicframework.com/blog/announcing-the-capacitor-google-maps-plugin/
My app is a Ionic Capacitor application (Angular) and runs on android and iOS
This is my implementation:
.html:
<ion-content [fullscreen]="true">
<div id="map" #map></div>
</ion-content>
.ts:
import {AfterViewInit, Component} from '#angular/core';
import {GoogleMap} from '#capacitor/google-maps';
#Component({
selector: 'app-testpage',
templateUrl: './testpage.page.html',
styleUrls: ['./testpage.page.scss'],
})
export class TestPage implements AfterViewInit {
constructor() {
}
ngAfterViewInit(): void {
}
public async showMap() {
const apiKey = "myapikey";
const mapElement = document.getElementById('map');
const mapConfig = {
center: {
lat: 33.6,
lng: -117.9,
},
zoom: 8,
androidLiteMode: false,
}
const mapOptions = {
id: "my-map",
apiKey: apiKey,
config: mapConfig,
element: mapElement,
}
const map = await GoogleMap.create(mapOptions)
}
}
in my android manifest file:
<meta-data android:name="com.google.android.geo.API_KEY" android:value="myapikey"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
However when I open the page I get the following errors in the console:
W/DynamiteModule: Local module descriptor class for com.google.android.gms.googlecertificates not found.
W/SnapshotHandler: Unable to retrieve flag snapshot for com.google.android.libraries.consentverifier#com.mypackagename, using defaults.
java.io.FileNotFoundException:/data/user/0/com.gmail.mypackagename/files/phenotype/shared/com.google.android.libraries.consentverifier#com.mypackagename.pb: open failed: ENOENT (No such file or directory)
W/MobStoreFlagStore: Unable to update local snapshot for com.google.android.libraries.consentverifier#com.mypackagename, may result in stale flags.
java.util.concurrent.ExecutionException: java.lang.SecurityException: GoogleCertificatesRslt: not allowed: pkg=com.mypackagename, sha256=[...], atk=false, ver=221514044.true (go/gsrlt)
I am wondering if anyone knows how to solve this?
I am using image picker in react native but an error occurs:
file:///storage/emulated exposed beyond app through clipdata.item
On ios, the camera opens normally. and in android i can pick an image from gallery normally.
My code:
const selectFile = (itemI,inputValue) => {
let options = {
title: 'Select Image',
maxWidth:800,
maxHeight:800,
quality:0.2,
storageOptions: {
skipBackup: true,
path: 'images',
},
includeBase64: true,
saveToPhotos:true
};
ImagePicker.showImagePicker(options, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled image picker');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else if (response.customButton) {
console.log(
'User tapped custom button: ',
response.customButton
);
alert(response.customButton);
} else {
//let source = response;
// You can also display the image using data:
let source = {
uri: 'data:image/jpeg;base64,' + response.data
};
filePath[itemI]=source;
addItemCustom(" ");
}
});
};
I tried to add:
<uses-feature android:name="android.hardware.camera.any" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
....
android:requestLegacyExternalStorage="true"
...>
but the error is the same.
my name is Leo, I'm a newbie in Reactnative
I'm trying to make a login to my app and i met a problem with fetch API.
i recieved [TypeError: Network request failed]. I run on device API 30
here is my code:
const loginHadle = async(email, password)=>{
await fetch ('http://127.0.0.1:8000/login/',{
method:'POST',
headers:{
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({"email": email, "password":password})
}).then(response=>{
if(response.status==200)
{
response.json().then(data=>{
signIn(data.email, data.tokens);
})
}
})
.then(res => {
console.log("reponse :", res);
}).catch(error => {
console.error(error);
return { name: "network error", description: "" };
});
}
and I've already add this line to AndroidManifest.xml
android:usesCleartextTraffic="true"
here is what i receive on postman
Thank you very much!
On Android 9 because of the "http" and issue resolved by just adding android:usesCleartextTraffic="true" in AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:usesCleartextTraffic="true"> . . . </application>
I use geolocation to get the current location of users in my project. but I get the Timed Out Error error.
{TIMEOUT: 3, POSITION_UNAVAILABLE: 2, PERMISSION_DENIED: 1, message: "Location request timed out", code: 3}
API 28 android phone success,
API 21 android phone success,
API 23 android phone time out error.
All permission granted.
try{
Geolocation.getCurrentPosition(
position => {
const initialPosition = JSON.stringify(position);
this.setState({
firstLat: position.coords.latitude,
firstLng: position.coords.longitude,
});
this.getLocation(position.coords.latitude, position.coords.longitude);
this.setState({
isLoading:true
})
},
error => console.log(error),
{enableHighAccuracy: true, timeout:10000, maximumAge:1000},
);
}catch (e) {
console.log(e)
}
AndroidManifest.xml
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
thank you.
The Problem
Okay so I have a Phonegap (2.3.0) android application with Pushwoosh to manage the push notifications. I followed the instructions, and got an app with only a few wording errors working. The app itself seems to run perfectly fine, however it doesn't seem like Pushwoosh is pushing anything to GCM (Google Cloud Messanger), which it turn isn't pushing anything to the app. Now that is what I think is wrong, however this is my first time using GCM and Pushwoosh.
On the Pushwoosh console page it shows each "push" as completed with no errors, but then on my GCM console it doesn't show any requests, nor do any notification pop up on my phone.
I have the GCM API key (server key) in my XML and my Pushwoosh is the correct XXXXX-XXXXX key. Here is my code to better outline how my code is setup (and maybe someone can see what I'm missing).
The Code
Here is the AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:resizeable="true"
android:anyDensity="true"
/>
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--library-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<!--
Creates a custom permission so only this app can receive its messages.
NOTE: the permission *must* be called PACKAGE.permission.C2D_MESSAGE,
where PACKAGE is the application's package name.
-->
<permission
android:name="com.springmobile.employee.permission.C2D_MESSAGE"
android:protectionLevel="signature"/>
<uses-permission
android:name="com.springmobile.employee.permission.C2D_MESSAGE"/>
<!-- This app has permission to register and receive data message. -->
<uses-permission
android:name="com.google.android.c2dm.permission.RECEIVE"/>
<application android:icon="#drawable/ic_launcher" android:label="#string/app_name" android:allowBackup="true">
<!--
Service for sending location updates
-->
<service android:name="com.arellomobile.android.push.GeoLocationService"/>
<intent-filter>
<action android:name="com.springmobile.employee.MESSAGE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<activity android:name="com.arellomobile.android.push.PushWebview"/>
<activity android:name="com.arellomobile.android.push.MessageActivity"/>
<activity android:name="com.arellomobile.android.push.PushHandlerActivity"/>
<!--
BroadcastReceiver that will receive intents from GCM
services and handle them to the custom IntentService.
The com.google.android.c2dm.permission.SEND permission is necessary
so only GCM services can send data messages for the app.
-->
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
<category android:name="com.springmobile.employee"/>
</intent-filter>
</receiver>
<!--
Application-specific subclass of PushGCMIntentService that will
handle received messages.
-->
<service android:name="com.arellomobile.android.push.PushGCMIntentService"/>
<activity android:name="org.apache.cordova.example.cordovaExample" android:label="#string/app_name"
android:theme="#android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Here is my Phonegap plugin config.XML
<plugins>
<plugin name="PushNotification" value="com.pushwoosh.plugin.pushnotifications.PushNotifications" onload="true"/>
</plugins>
Here is the JS for my Phonegap page to initialize and listen for the Pushwoosh Notification.
function initPushwoosh()
{
var pushNotification = window.plugins.pushNotification;
pushNotification.onDeviceReady();
pushNotification.registerDevice({ projectid: "I_HAVE_MY_PROJECT_ID_HERE", appid : "THIS_IS_MY_PUSHWOOSH_ID" },
function(status) {
var pushToken = status;
console.warn('push token: ' + pushToken);
},
function(status) {
console.warn(JSON.stringify(['failed to register ', status]));
}
);
document.addEventListener('push-notification', function(event) {
var title = event.notification.title;
var userData = event.notification.userdata;
if(typeof(userData) != "undefined") {
console.warn('user data: ' + JSON.stringify(userData));
}
navigator.notification.alert(title);
});
}
function init() {
document.addEventListener("deviceready", initPushwoosh, true);
//rest of the code
document.addEventListener('push-notification', function(event) {
var title = event.notification.title;
var userData = event.notification.userdata;
console.warn('user data: ' + JSON.stringify(userData));
navigator.notification.alert(title);
});
}
function initPushwoosh()
{
var pushNotification = window.plugins.pushNotification;
pushNotification.onDeviceReady();
document.addEventListener('push-notification', function(event) {
var title = event.notification.title;
var userData = event.notification.userdata;
if(typeof(userData) != "undefined") {
console.warn('user data: ' + JSON.stringify(userData));
}
navigator.notification.alert(title);
pushNotification.stopGeoPushes();
});
}
function registerPushwoosh()
{
var pushNotification = window.plugins.pushNotification;
//projectid: "GOOGLE_PROJECT_ID", appid : "PUSHWOOSH_APP_ID"
pushNotification.registerDevice({ projectid: "1039894503284", appid : "EE861-B95A3" },
function(token) {
alert(token);
onPushwooshInitialized(token);
},
function(status) {
alert("failed to register: " + status);
console.warn(JSON.stringify(['failed to register ', status]));
});
}
function unregisterPushwoosh()
{
var pushNotification = window.plugins.pushNotification;
pushNotification.unregisterDevice(function(token) {
alert("unregistered, old token " + token);
},
function(status) {
alert("failed to unregister: " + status);
console.warn(JSON.stringify(['failed to unregister ', status]));
});
}
//set the settings for Pushwoosh or set tags, this must be called only after successful registration
function onPushwooshInitialized(pushToken)
{
//output the token to the console
console.warn('push token: ' + pushToken);
var pushNotification = window.plugins.pushNotification;
//set multi notificaiton mode
//pushNotification.setMultiNotificationMode();
//set single notification mode
//pushNotification.setSingleNotificationMode();
//disable sound and vibration
//pushNotification.setSoundType(1);
//pushNotification.setVibrateType(1);
pushNotification.setLightScreenOnNotification(false);
//goal with count
//pushNotification.sendGoalAchieved({goal:'purchase', count:3});
//goal with no count
//pushNotification.sendGoalAchieved({goal:'registration'});
//setting list tags
//pushNotification.setTags({"MyTag":["hello", "world"]});
//settings tags
pushNotification.setTags({deviceName:"hello", deviceId:10},
function(status) {
console.warn('setTags success');
},
function(status) {
console.warn('setTags failed');
});
function geolocationSuccess(position) {
pushNotification.sendLocation({lat:position.coords.latitude, lon:position.coords.longitude},
function(status) {
console.warn('sendLocation success');
},
function(status) {
console.warn('sendLocation failed');
});
};
// onError Callback receives a PositionError object
//
function geolocationError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
function getCurrentPosition() {
navigator.geolocation.getCurrentPosition(geolocationSuccess, geolocationError);
}
//greedy method to get user position every 3 second. works well for demo.
// setInterval(getCurrentPosition, 3000);
//this method just gives the position once
// navigator.geolocation.getCurrentPosition(geolocationSuccess, geolocationError);
//this method should track the user position as per Phonegap docs.
// navigator.geolocation.watchPosition(geolocationSuccess, geolocationError, { maximumAge: 3000, enableHighAccuracy: true });
//Pushwoosh Android specific method that cares for the battery
pushNotification.startGeoPushes();
}
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicity call 'app.receivedEvent(...);'
onDeviceReady: function() {
initPushwoosh();
app.receivedEvent('deviceready');
//optional: create local notification alert
//var pushNotification = window.plugins.pushNotification;
//pushNotification.clearLocalNotification();
//pushNotification.createLocalNotification({"msg":"message", "seconds":30, "userData":"optional"});
},
// Update DOM on a Received Event
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
}
};
Here is the PushWoosh.js code
(function(cordova) {
function PushNotification() {}
// Call this to register for push notifications and retreive a deviceToken
PushNotification.prototype.registerDevice = function(config, success, fail) {
cordova.exec(success, fail, "PushNotification", "registerDevice", config ? [config] : []);
};
// Call this to set tags for the device
PushNotification.prototype.setTags = function(config, success, fail) {
cordova.exec(success, fail, "PushNotification", "setTags", config ? [config] : []);
};
// Call this to send geo location for the device
PushNotification.prototype.sendLocation = function(config, success, fail) {
cordova.exec(success, fail, "PushNotification", "sendLocation", config ? [config] : []);
};
//Android Only----
PushNotification.prototype.unregisterDevice = function(success, fail) {
cordova.exec(success, fail, "PushNotification", "unregisterDevice", []);
};
//config params: {msg:"message", seconds:30, userData:"optional"}
PushNotification.prototype.createLocalNotification = function(config, success, fail) {
cordova.exec(success, fail, "PushNotification", "createLocalNotification", config ? [config] : []);
};
PushNotification.prototype.clearLocalNotification = function() {
cordova.exec(null, null, "PushNotification", "clearLocalNotification", []);
};
//advanced background task to track device position and not drain the battery
PushNotification.prototype.startGeoPushes = function(success, fail) {
cordova.exec(success, fail, "PushNotification", "startGeoPushes", []);
};
PushNotification.prototype.stopGeoPushes = function(success, fail) {
cordova.exec(success, fail, "PushNotification", "stopGeoPushes", []);
};
//sets multi notification mode on
PushNotification.prototype.setMultiNotificationMode = function(success, fail) {
cordova.exec(success, fail, "PushNotification", "setMultiNotificationMode", []);
};
//sets single notification mode
PushNotification.prototype.setSingleNotificationMode = function(success, fail) {
cordova.exec(success, fail, "PushNotification", "setSingleNotificationMode", []);
};
//type: 0 default, 1 no sound, 2 always
PushNotification.prototype.setSoundType = function(type, success, fail) {
cordova.exec(success, fail, "PushNotification", "setSoundType", [type]);
};
//type: 0 default, 1 no vibration, 2 always
PushNotification.prototype.setVibrateType = function(type, success, fail) {
cordova.exec(success, fail, "PushNotification", "setVibrateType", [type]);
};
PushNotification.prototype.setLightScreenOnNotification = function(on, success, fail) {
cordova.exec(success, fail, "PushNotification", "setLightScreenOnNotification", [on]);
};
//set to enable led blinking when notification arrives and display is off
PushNotification.prototype.setEnableLED = function(on, success, fail) {
cordova.exec(success, fail, "PushNotification", "setEnableLED", [on]);
};
//{goal:'name', count:3} (count is optional)
PushNotification.prototype.sendGoalAchieved = function(config, success, fail) {
cordova.exec(success, fail, "PushNotification", "sendGoalAchieved", config ? [config] : []);
};
//Android End----
//iOS only----
PushNotification.prototype.onDeviceReady = function() {
cordova.exec(null, null, "PushNotification", "onDeviceReady", []);
};
// Call this to get a detailed status of remoteNotifications
PushNotification.prototype.getRemoteNotificationStatus = function(callback) {
cordova.exec(callback, callback, "PushNotification", "getRemoteNotificationStatus", []);
};
// Call this to set the application icon badge
PushNotification.prototype.setApplicationIconBadgeNumber = function(badge, callback) {
cordova.exec(callback, callback, "PushNotification", "setApplicationIconBadgeNumber", [{badge: badge}]);
};
// Call this to clear all notifications from the notification center
PushNotification.prototype.cancelAllLocalNotifications = function(callback) {
cordova.exec(callback, callback, "PushNotification", "cancelAllLocalNotifications", []);
};
//iOS End----
// Event spawned when a notification is received while the application is active
PushNotification.prototype.notificationCallback = function(notification) {
var ev = document.createEvent('HTMLEvents');
ev.notification = notification;
ev.initEvent('push-notification', true, true, arguments);
document.dispatchEvent(ev);
};
cordova.addConstructor(function() {
if(!window.plugins) window.plugins = {};
window.plugins.pushNotification = new PushNotification();
});
})(window.cordova || window.Cordova || window.PhoneGap);
Screenshots of GCM, Pushwoosh and Eclipse
Sorry this is lengthy but I want to make sure I have everything here. Also not enough rep to post images so links below.
GCM API server key, Pushwoosh Control Panel, and Eclipse setup
Thanks!
lets check your configuration and setup is proper for push woosh notification .Other Push notification service is also work in phone-gap you can check it out.You can find phone gap code(zip),proper documentation for configuration and setup and how to use their API using Java script
The Pushwoosh version is very important while configuring it with a phonegap application, so you need to be sure that your Pushwoosh script is compatible with Phonegap 2.3.0. If the Pushwoosh script is not correct, it will not work with your Phonegap version and I think that they only support the latest Phonegap available right now.
The GCM API key must be for Android Application, not server
I had this issue because my bundle id wasn't correct.
Be sure that your app name and the bundle id are the same in xcode and your iOS app Indentifier in https://developer.apple.com/account/ios/identifiers.