Problem:
Want to run my build .so file with android runtime.exec or processbuilder
C side code: example.cpp
#include
using namespace std;
int main( int argc, char* argv[])
{
cout << "Count: " << argc << endl;
for (int i = 0; i < argc; i++) {
cout << "Command: " << argv[i] << endl;
}
}
Android side code(kotlin):
try{
val rt = Runtime.getRuntime()
val command = arrayOf(applicationContext.applicationInfo.nativeLibraryDir+"/libexample.so","-c","Hello world")
val proc = rt.exec(command)
val br = BufferedReader(InputStreamReader(proc.errorStream))
var line = ""
while(br.readLine().also { line = it } != null){
Log.e("TEST",line)
}
proc.waitFor()
val exitvalue = proc.exitValue()
Log.e("TEST","Exitvalue: ${exitvalue}")
}catch (ex:Exception){
Log.e("TEST",ex.toString())
}
Errors: Exit value = 139
Note: CPP code is working on console and there are no errors in cpp code. and i am using NDK.)
Question: May I execute .so file like this without using JNI?
Related
I'm testing Rust with JNI async execution. I want to do execute requests in Rust and return the result to Android asynchronously with callback. I'm testing code to execute the request in the command line and it works fine.
That is how it works on command line:
Callback struck:
struct Processor {
pub(crate) callback: Box<dyn FnMut(String)>,
}
impl Processor {
fn set_callback(&mut self, c: impl FnMut(String) + 'static) {
self.callback = Box::new(c);
}
fn process_events(&mut self, result: String) {
(self.callback)(result);
}
}
Tokio/reqwest:
const DATA_URL: &str = "https://pokeapi.co/api/v2/pokemon/1/";
#[tokio::main]
pub async fn load_swapi_async_with_cb(callback: Box<dyn FnMut(String)>) -> Result<(), Box<dyn std::error::Error>> {
println!("load_swload_swapi_async_with_cbapi_async started");
let mut cb = Processor {
callback: Box::new(callback),
};
let body = reqwest::get(DATA_URL)
.await?
.json::<HashMap<String, String>>()
.await?;
//println!("{:#?}", body);
let name = match body.get("name") {
Some(name) => name,
None => "Failed to parse"
}.to_string();
println!("Name is: {} ", name);
cb.process_events(name);
Ok(())
}
And JNI part:
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn Java_com_omg_app_greetings_MainActivity_callback(env: JNIEnv,
_class: JClass,
callback: JObject) {
static callback: dyn FnMut(String) + 'static = |name| {
let response = env.new_string(&name).expect("Couldn't create java string!");
env.call_method(callback, "rustCallbackResult", "(Ljava/lang/String;)V",
&[JValue::from(JObject::from(response))]).unwrap();
};
pokemon_api(callback);
}
And pokemon API method:
#[no_mangle]
pub extern fn pokemon_api(callback: impl FnMut(String) + 'static) {
let cb_box = Box::new(callback);
swapi::load_swapi_async_with_cb(cb_box);
}
The error I'm facing:
JNI ENV env non-constant value:
let response = env.new_string(&name).expect("Couldn't create java string!");
| ^^^ non-constant value
callback - doesn't have a size known at compile-time:
static callback: dyn FnMut(String) + 'static = |name| {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
I was checking how this working, but example seems to be out of date:
* https://github.com/mozilla/rust-android-gradle/blob/master/samples/rust/src/lib.rs
I fixed with my problem with the usage of the https://github.com/Dushistov/rust_swig
After you integrate it, it will autogenerate code and you can check how it does it.
I was trying to run a code that is built successfully but when I try to run it an error appears! Similar errors are already asked in StackOverflow but lot of them not answered.
Here is the error:
Build command failed.
Error while executing process C:\AndroidStudio\Local\Android\SDK\ndk-bundle \ndk-build.cmd with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=D:\SuperAdventure\app\build\intermediates\ndk\debug\Android.mk APP_ABI=armeabi-v7a NDK_ALL_ABIS=armeabi-v7a NDK_DEBUG=1 APP_PLATFORM=android-16 NDK_OUT=D:/SuperAdventure/app/build/intermediates/ndkBuild/debug/obj NDK_LIBS_OUT=D:\SuperAdventure\app\build\intermediates\ndkBuild\debug\lib D:/SuperAdventure/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a/libplayer_shared.so}
Android NDK: WARNING: Unsupported source file extensions in D:\SuperAdventure\app\build\intermediates\ndk\debug\Android.mk for module player_shared
Android NDK: D:\SuperAdventure\app\src\main\jni\Android.mk D:\SuperAdventure\app\src\main\jni\Application.mk D:\SuperAdventure\app\src\main\jni\list.sh
[armeabi-v7a] Compile++ thumb: player_shared <= main.cpp
D:\SuperAdventure\app\src\main\jni\main.cpp:1:10: fatal error: 'PTPAppDelegate.h' file not found
#include "PTPAppDelegate.h"
1 error generated.
make: *** [D:/SuperAdventure/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a/objs-debug/player_shared/D_\SuperAdventure\app\src\main\jni\main.o] Error 1
Here is my build.gradle (module:app)
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion "28.0.3"
defaultConfig {
applicationId "com.sggame.superadventure"
minSdkVersion 14
targetSdkVersion 26
multiDexEnabled true
ndk {
moduleName "player_shared"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
externalNativeBuild {
ndkBuild {
path file('build/intermediates/ndk/debug/Android.mk')
}
}
}
dependencies {
implementation 'com.google.android.gms:play-services:+'
implementation files('libs/dagger-1.2.2.jar')
implementation files('libs/javax.inject-1.jar')
implementation files('libs/nineoldandroids-2.4.0.jar')
implementation files('libs/support-v4-19.0.1.jar')
implementation 'com.android.support:appcompat-v7:26.0.0'
}
The main.cpp file is full of errors:
#include "PTPAppDelegate.h"
#include "cocos2d.h"
#include "PTPConfig.h"
#include "models/PTModelController.h"
#include "PTPSettingsController.h"
#include "platform/android/jni/JniHelper.h"
#include <jni.h>
#include <android/log.h>
#include "models/PTModelScreen.h"
#include "models/PTModelAtlas.h"
#include "models/PTModelGeneralSettings.h"
#include "models/objects/PTModelAssetCharacter.h"
#include "models/objects/PTModelObjectAssetTrail.h"
#include "models/objects/PTModelObjectAssetFlag.h"
#include "models/objects/PTModelObjectButtonPurchase.h"
#define LOG_TAG "main"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
using namespace cocos2d;
extern "C"
{
jint JNI_OnLoad(JavaVM *vm, void *reserved){
JniHelper::setJavaVM(vm);
return JNI_VERSION_1_4;
}
void Java_com_secrethq_utils_PTJniHelper_loadModelController(JNIEnv* env, jobject thiz){
PTLog("start laoding XML");
PTModelController *mc = PTModelController::shared();
while (!mc->loadDirectory("data"));
PTLog("end loading XML");
}
jboolean Java_com_secrethq_utils_PTJniHelper_isAdNetworkActive(JNIEnv* env, jobject thiz, jstring adNetworkNameString ){
const char* adNetworkName = env->GetStringUTFChars(adNetworkNameString, 0);
std::string platformName = "Google Play Store";
PTModelController *mc = PTModelController::shared();
PTPSettingsController* sc = PTPSettingsController::shared();
std::vector<PTModel*> screensArray = mc->getModels("PTModelScreen");
if(screensArray.empty() || sc->removeAds()){
return false;
}
for(int i=0; i < screensArray.size(); i++){
PTModelScreen* model = (PTModelScreen*)screensArray.at( i );
if(model->adNetworkFullscreen().compare( adNetworkName ) == 0){
return true;
}
if(model->adNetworkBanner().compare( adNetworkName ) == 0){
return true;
}
}
// check if this network in backup list
// banner
std::list<std::string> bannerList = PTModelGeneralSettings::shared()->adBannersList( platformName );
std::list<std::string>::const_iterator bannerIterator;
for (bannerIterator = bannerList.begin(); bannerIterator != bannerList.end(); ++bannerIterator) {
if(strcmp((*bannerIterator).c_str(), adNetworkName) == 0){
PTLog("ad Network (%s) in backup list (banner)", adNetworkName);
return true;
}
}
// interstitials
std::list<std::string> interstitialList = PTModelGeneralSettings::shared()->adInterstitialsList( platformName );
std::list<std::string>::const_iterator interstittialsIterator;
for (interstittialsIterator = interstitialList.begin(); interstittialsIterator != interstitialList.end(); ++interstittialsIterator) {
if(strcmp((*interstittialsIterator).c_str(), adNetworkName) == 0){
PTLog("ad Network (%s) in backup list (interstitials)", adNetworkName);
return true;
}
}
// check if network is used as reward video
std::vector<PTModel*> buttonsArray = mc->getModels("PTModelObjectButtonPurchase");
if ( !buttonsArray.empty() ){
for(int i=0; i < buttonsArray.size(); i++){
PTModelObjectButtonPurchase* model = (PTModelObjectButtonPurchase*)buttonsArray.at( i );
if ( model->isRewardedVideo()
&& model->rewardedVideoAdNetwork().compare( adNetworkName ) == 0 ) {
return true;
}
}
}
// check if network is used as reward video
std::vector<PTModel*> charsArray = mc->getModels("PTModelAssetCharacter");
if ( !charsArray.empty() ){
for(int i=0; i < charsArray.size(); i++){
PTModelAssetCharacter* model = (PTModelAssetCharacter*)charsArray.at( i );
if ( model->purchaseMethod().compare("kRewardedVideos") == 0
&& model->rewardedVideoAdNetwork().compare( adNetworkName ) == 0 ) {
return true;
}
}
}
return false;
}
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h){
PTModelController *mc = PTModelController::shared();
if (!CCDirector::sharedDirector()->getOpenGLView()){
CCEGLView *view = CCEGLView::sharedOpenGLView();
view->setFrameSize(w, h);
//loading general info
mc->clean();
mc->loadFile( "data/PTModelGeneralSettings.0.attributes.xml", PTModelController::Attributes );
mc->loadFile( "data/PTModelFont.0.attributes.xml", PTModelController::Attributes );
mc->loadFile( "data/PTModelScreen.0.attributes.xml", PTModelController::Attributes );
mc->loadFile( "data/PTModelObjectLabel.0.attributes.xml", PTModelController::Attributes );
mc->loadFile( "data/PTModelObjectLoadingBar.0.attributes.xml", PTModelController::Attributes );
mc->loadFile( "data/PTModelScreen.0.connections.xml", PTModelController::Connections );
PTPAppDelegate *pAppDelegate = new PTPAppDelegate();
CCApplication::sharedApplication()->run();
//clean up main model controller before starting loading Objects form XML files
mc->clean();
}
else {
PTLog("NATIVE RE INIT");
ccGLInvalidateStateCache();
CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
ccDrawInit();
CCTextureCache::reloadAllTextures();
CCNotificationCenter::sharedNotificationCenter()->postNotification(EVNET_COME_TO_FOREGROUND, NULL);
CCDirector::sharedDirector()->setGLDefaultValues();
}
}
}
All the #includes are red!
Do you please have any idea about how to resolve this problem?!
I'm getting this error on Android:
I have found that line of code 'Sn[e]' in 'index.android.bundle' which I have pasted below (ctrl/command + F):
for (var An in Sn) xn[An] = Sn[An];
for (var Dn in wn) Pt(!Sn[Dn], "Event cannot be both direct and bubbling: %s", Dn), xn[Dn] = wn[Dn];
var kn = {
eventTypes: En({}, Sn, wn),
extractEvents: function(e, t, n, o) {
var r = Sn[e],
i = wn[e],
a = Pn.getPooled(r || i, t, n, o);
if (r) fn.accumulateTwoPhaseDispatches(a);
else {
if (!i) return null;
fn.accumulateDirectDispatches(a)
}
return a
}
},
jn = kn,
On = {
handleTopLevel: function(e, t, n, o) {
G(sn.extractEvents(e, t, n, o))
}
},
Mn = On,
Hn = 1,
Un = {
tagsStartAt: Hn,
tagCount: Hn,
allocateTag: function() {
for (; this.reactTagIsNativeTopRootID(Un.tagCount);) Un.tagCount++;
var e = Un.tagCount;
return Un.tagCount++, e
},
assertRootTag: function(e) {
It(this.reactTagIsNativeTopRootID(e), "Expect a native root tag, instead got %s", e)
},
reactTagIsNativeTopRootID: function(e) {
return e % 10 == 1
}
},
Fn = Un,
Wn = null,
Ln = {
injectFiberControlledHostComponent: function(e) {
Wn = e
}
},
Bn = null,
Yn = null,
Vn = {
injection: Ln,
enqueueStateRestore: function(e) {
Bn ? Yn ? Yn.push(e) : Yn = [e] : Bn = e
},
Looks like a React piece of code because it has injectFiberControlledHostComponent which seems like React Native Fiber. Any idea how I can fix this?
I started the app in android studio and no errors because the app builds and installs fine. I did see this in the android studio gradle console but it's probably not the issue:
Note:
/Users/Ben/Development/Projects/vepo/frontend/android/app/src/main/java/com/vepo/MainApplication.java
uses or overrides a deprecated API. Note: Recompile with
-Xlint:deprecation for details.
I faced the same problem and fixed by changing app/build.gradle as:
compile "com.facebook.react:react-native:+"
to
compile ("com.facebook.react:react-native:+") {
force = true;
}
See also this: https://github.com/facebook/react-native/issues/17840
I have create a hotspot/wifi-direct on an android device.And connect this wifi with iOS devices.
Now i want to create a iOS App which will be able to send and receive the data over wifi.
Is it possible if yes then how I can do this ?
yes it is possible, you can run local server on android, I recommend https://github.com/NanoHttpd/nanohttpd
then you must get ip address on iOS device to do http requests, there is c method to get route ip address
#include "IpHelper.h" // my header file
#include <stdio.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <string.h>
#include <arpa/inet.h>
#if TARGET_IPHONE_SIMULATOR
#include <net/route.h>
#else
#include "route.h"
#endif
#define CTL_NET 4 /* network, see socket.h */
#if defined(BSD) || defined(__APPLE__)
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
int getdefaultgateway(in_addr_t * addr)
{
int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
NET_RT_FLAGS, RTF_GATEWAY};
size_t l;
char * buf, * p;
struct rt_msghdr * rt;
struct sockaddr * sa;
struct sockaddr * sa_tab[RTAX_MAX];
int i;
int r = -1;
if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) {
return -1;
}
if(l>0) {
buf = malloc(l);
if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) {
return -1;
}
for(p=buf; p<buf+l; p+=rt->rtm_msglen) {
rt = (struct rt_msghdr *)p;
sa = (struct sockaddr *)(rt + 1);
for(i=0; i<RTAX_MAX; i++) {
if(rt->rtm_addrs & (1 << i)) {
sa_tab[i] = sa;
sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len));
} else {
sa_tab[i] = NULL;
}
}
if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY))
&& sa_tab[RTAX_DST]->sa_family == AF_INET
&& sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) {
if(((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) {
char ifName[128];
if_indextoname(rt->rtm_index,ifName);
if(strcmp("en0",ifName)==0){
*addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr;
r = 0;
}
}
}
}
free(buf);
}
return r;
}
#endif
also you need to download and import route.h from apple open-sources from here https://opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/net/route.h
And at the end you are able to get local http url http://+'ip you get before'+ :'port of server you lunched on android'
so, now you are ready to do http request via ALamofire(or other) to local server.
EDIT 1:
I found this code in my old projects you can do data transfer with CocoaAsyncSocket, it is written in swift 3, I know that you want some code written on objC, but can not find such , sorry if i can't fully answer your question.
import CocoaAsyncSocket
import UIKit
enum TAG: Int {
case header = 1
case body = 2
}
class ViewController: UIViewController, NetServiceDelegate, NetServiceBrowserDelegate, GCDAsyncSocketDelegate {
var service : NetService!
var socket : GCDAsyncSocket!
var newSocket: GCDAsyncSocket!
var serviceBrowser = NetServiceBrowser()
var adresses: [Data]?
override func viewDidLoad() {
super.viewDidLoad()
startTalking()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func parseHeader(data: NSData) -> UInt {
var out: UInt = 0
data.getBytes(&out, length: MemoryLayout<UInt>.size)
return out
}
func handleResponseBody(data: NSData) {
if let message = NSString(data: data as Data, encoding: String.Encoding.utf8.rawValue) {
print(message)
}
}
func sendText() {
if let data = "aaaaa".data(using: String.Encoding.utf8) {
var header = data.count
let headerData = NSData(bytes: &header, length: MemoryLayout<UInt>.size)
self.socket.write(headerData as Data, withTimeout: -1.0, tag: TAG.header.rawValue)
self.socket.write(data, withTimeout: -1.0, tag: TAG.body.rawValue)
}
}
func startTalking () {
self.socket = GCDAsyncSocket(delegate: self, delegateQueue: DispatchQueue.main)
self.socket.isIPv4PreferredOverIPv6 = false
do {
try self.socket.connect(toHost: "localhost", onPort: UInt16(8080), withTimeout: -1)
} catch let err {
print(err)
}
}
/*
* Delegates of NSNetService
**/
func netServiceBrowser(_ browser: NetServiceBrowser, didFindDomain domainString: String, moreComing: Bool) {
print(111)
}
func netService(_ sender: NetService, didNotResolve errorDict: [String : NSNumber]) {
print("aaaaaaa")
}
func netServiceDidPublish(_ sender: NetService) {
print("Bonjour service published. domain: \(sender.domain), type: \(sender.type), name: \(sender.name), port: \(sender.port)")
}
func netService(_ sender: NetService, didNotPublish errorDict: [String : NSNumber]) {
print("Unable to create socket. domain: \(sender.domain), type: \(sender.type), name: \(sender.name), port: \(sender.port), Error \(errorDict)")
}
func netService(_ sender: NetService, didAcceptConnectionWith inputStream: InputStream, outputStream: OutputStream) {
print("4")
}
/*
* END OF Delegates
**/
/*
* Delegates of GCDAsyncSokcket
**/
func socketDidSecure(_ sock: GCDAsyncSocket) {
print("3")
}
func socket(_ sock: GCDAsyncSocket, didConnectToHost host: String, port: UInt16) {
print("connected")
self.socket.readData(toLength: UInt(MemoryLayout<UInt64>.size), withTimeout: -1, tag: 0)
}
func socket(_ sock: GCDAsyncSocket, didAcceptNewSocket newSocket: GCDAsyncSocket) {
print("Did accept new socket")
self.newSocket = newSocket
self.newSocket.readData(toLength: UInt(MemoryLayout<UInt64>.size), withTimeout: -1.0, tag: 0)
print("Connected to " + self.service.name)
}
func socketDidDisconnect(_ sock: GCDAsyncSocket, withError err: Error?) {
print("Socket disconnected: error \(err)")
if self.socket == socket {
// print("Disconnected from " + self.service.name)
}
}
func socket(_ sock: GCDAsyncSocket, didRead data: Data, withTag tag: Int) {
if data.count == MemoryLayout<UInt>.size {
let bodyLength: UInt = self.parseHeader(data: data as NSData)
sock.readData(toLength: bodyLength, withTimeout: -1, tag: TAG.body.rawValue)
} else {
self.handleResponseBody(data: data as NSData)
sock.readData(toLength: UInt(MemoryLayout<UInt>.size), withTimeout: -1, tag: TAG.header.rawValue)
}
}
func socket(_ sock: GCDAsyncSocket, didWriteDataWithTag tag: Int) {
print("Write data with tag of \(tag)")
}
func socket(_ sock: GCDAsyncSocket, didReceive trust: SecTrust, completionHandler: #escaping (Bool) -> Void) {
completionHandler(true)
}
/*
* END OF Delegates
**/
}
EDIT 2:
To parse ip to human readable string here is Objc method for it
+ (NSString *)getGatewayIP {
NSString *ipString = nil;
struct in_addr gatewayaddr;
int r = getdefaultgateway(&(gatewayaddr.s_addr));
if(r >= 0) {
ipString = [NSString stringWithFormat: #"%s",inet_ntoa(gatewayaddr)];
NSLog(#"default gateway : %#", ipString );
} else {
NSLog(#"getdefaultgateway() failed");
}
return ipString;
}
I’m experimenting with Qt Positioning in Qt 5.3 RC on Android.
This is sample of my code, where I create sources of position and satellites:
QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(this);
if (source) {
QStringList posSourcesList = QGeoPositionInfoSource::availableSources();
qDebug() << "Position sources count: " << posSourcesList.count();
foreach (const QString &src, posSourcesList) {
qDebug() << "pos source in list: " << src;
}
source->startUpdates();
connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)),
this, SLOT(positionUpdated(QGeoPositionInfo)));
}
//----------------------------------------------------------------------------------
QGeoSatelliteInfoSource *satelliteSource = QGeoSatelliteInfoSource::createDefaultSource(this);
if(satelliteSource)
{
QStringList sourcesList = QGeoSatelliteInfoSource::availableSources();
qDebug() << "Satellites sources count: " << sourcesList.count();
foreach (const QString &src, sourcesList) {
qDebug() << "source in list: " << src;
}
satelliteSource->startUpdates();
connect(satelliteSource, SIGNAL(satellitesInViewUpdated(QList<QGeoSatelliteInfo>)),
this, SLOT(satellitesInViewUpdated(QList<QGeoSatelliteInfo>)));
}
I get segmentation with the output:
D/Qt (16403): ../test_GPS/gpshandler.cpp:14 (GPSHandler::GPSHandler(QObject*)): Position sources count: 1
D/Qt (16403): ../test_GPS/gpshandler.cpp:16 (GPSHandler::GPSHandler(QObject*)): pos source in list: "android"
D/QtPositioning(16403): Regular updates using GPS
D/QtPositioning(16403): Regular updates using network
D/Qt (16403): ../test_GPS/gpshandler.cpp:37 (GPSHandler::GPSHandler(QObject*)): Satellites sources count: 1
D/Qt (16403): ../test_GPS/gpshandler.cpp:39 (GPSHandler::GPSHandler(QObject*)): source in list: "android"
F/Qt (16403): jnipositioning.cpp:496 (void satelliteUpdated(JNIEnv*, jobject, jobjectArray, jint, jboolean)): satelliteUpdated: source == 0
Here is the backtrace:
0 ?? /home/qtproj/build-test_GPS-Android_for_armeabi_v7a_GCC_4_8_Qt_5_3_0-Debug/libc.so 0x4010a8e8
1 abort /home/qtproj/build-test_GPS-Android_for_armeabi_v7a_GCC_4_8_Qt_5_3_0-Debug/libc.so 0x40108948
2 QMessageLogger::fatal(char const*, ...) const /opt/Qt-5.3.0_rc/5.3/android_armv7/lib/libQt5Core.so 0x75357ff6
3 satelliteUpdated(_JNIEnv*, _jobject*, _jobjectArray*, int, unsigned char) /opt/Qt-5.3.0_rc/5.3/android_armv7/plugins/position/libqtposition_android.so 0x751a8c08
4 ?? 0x40b3a910
5 ?? 0x40b3a910
When I’m creating only QGeoPositionInfoSource or only QGeoSatelliteInfoSource, this error doesn’t occur.
Any suggestions?
The same error is still present in 5.3.1. I don't have an explanation to offer, but the workaround here is to change the order of initialization of the sources.
QGeoSatelliteInfoSource
QGeoPositionInfoSource
So in your code that would be
QGeoSatelliteInfoSource *satelliteSource = QGeoSatelliteInfoSource::createDefaultSource(this);
if(satelliteSource) {
QStringList sourcesList = QGeoSatelliteInfoSource::availableSources();
qDebug() << "Satellites sources count: " << sourcesList.count();
foreach (const QString &src, sourcesList) {
qDebug() << "source in list: " << src;
}
satelliteSource->startUpdates();
connect(satelliteSource, SIGNAL(satellitesInViewUpdated(QList<QGeoSatelliteInfo>)),
this, SLOT(satellitesInViewUpdated(QList<QGeoSatelliteInfo>)));
}
QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(this);
if (source) {
QStringList posSourcesList = QGeoPositionInfoSource::availableSources();
qDebug() << "Position sources count: " << posSourcesList.count();
foreach (const QString &src, posSourcesList) {
qDebug() << "pos source in list: " << src;
}
source->startUpdates();
connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)),
this, SLOT(positionUpdated(QGeoPositionInfo)));
}