使用Gluon Mobile对Android错误测试图片服务和位置服务

问题描述 投票:1回答:1

我正在使用3个按钮在简单的BasicView中测试barcodescanservice,locationservice和pictureservice。 barcodescanservice没问题,但是picturePvice在AndroidPicturesService.java:132中产生了一个nullpointer错误。位置服务AndroidRuntimeException:从Activity上下文外部调用startActivity()需要FLAG_ACTIVITY_NEW_TASK标志。在这两个案例中,程序中断了。

我正在使用org.javafxports:jfxmobile-plugin:1.3.16和com.gluonhq:charm:5.0.2。在Android 4.4.4和Android 8.0中测试具有相同的结果。代码是从Api Doc复制的。

代码:

        Button butFoto = new Button("Photo");
        butFoto.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                Services.get(PicturesService.class).ifPresent(service -> {
                    service.takePhoto(false).ifPresent(image -> imageView.setImage(image));
                });

            }
        });

        Button butBarcode = new Button("Barcode");
        butBarcode.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                String barcodeValue = Services.get(BarcodeScanService.class)
                        .flatMap(service -> service
                        .scan("Scan Test", "Place a barcode under the camera", "Barcode found with value"))
                        .orElse("No barcode found");
                System.out.println("Scanned Bar Code: " + barcodeValue);
                label2.setText(barcodeValue);
            }
        });

        Button butGPS = new Button("Position");
        butGPS.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                Services.get(PositionService.class)
                        .ifPresent(positionService -> {
                            positionService.start();
                            ReadOnlyObjectProperty<Position> positionProperty = positionService.positionProperty();
                            Position position = positionProperty.get();
                            label2.setText("Lat=" + String.valueOf(position.getLatitude())
                                    + " Lon=" + String.valueOf(position.getLongitude()));
                        });
            }
        });

Android清单:

<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.cip.cipgesfx" android:versionCode="1" android:versionName="1.0">
    <supports-screens android:xlargeScreens="true"/>
    <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"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.FLASHLIGHT" />

    <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="21"/>

    <application android:label="cipmobile" android:name="android.support.multidex.MultiDexApplication" android:icon="@mipmap/cip_icono">
        <activity android:name="javafxports.android.FXActivity" android:label="CipMobile" android:configChanges="orientation|screenSize">
            <meta-data android:name="main.class" android:value="com.cipmobile.Cipmobile"/>
            <meta-data android:name="debug.port" android:value="0"/>
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <activity android:name="com.gluonhq.impl.charm.down.plugins.android.scan.zxing.CaptureActivity"
                  android:screenOrientation="sensorPortrait"
                  android:clearTaskOnLaunch="true"
                  android:stateNotNeeded="true"
                  android:windowSoftInputMode="stateAlwaysHidden">
            <intent-filter>
                <action android:name="com.gluonhq.charm.down.plugins.android.scan.SCAN"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>

        <activity android:name="com.gluonhq.impl.charm.down.plugins.android.PermissionRequestActivity" />

        <service android:name="com.gluonhq.impl.charm.down.plugins.android.AndroidPositionBackgroundService" 
                 android:process=":positionBackgroundService" />

    </application>
</manifest>

构建Gradle:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'org.javafxports:jfxmobile-plugin:1.3.16'
    }
}

apply plugin: 'org.javafxports.jfxmobile'

repositories {
    jcenter()
    maven {
        url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
    }
}

mainClassName = 'com.cip.cipgesfx.IniciarApli'

dependencies {
    compile 'com.gluonhq:charm:5.0.2'
    compile fileTree(dir: 'lib', include: ['*.jar'])
    //compile 'org.eclipse.persistence:org.eclipse.persistence.jpa:2.6.3'
    // https://mvnrepository.com/artifact/org.eclipse.persistence/org.eclipse.persistence.jpa
    compile group: 'org.eclipse.persistence', name: 'org.eclipse.persistence.jpa', version: '2.7.4'
    // https://mvnrepository.com/artifact/org.controlsfx/controlsfx
    compile group: 'org.controlsfx', name: 'controlsfx', version: '8.40.14'
    // https://mvnrepository.com/artifact/com.google.code.gson/gson
    compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
    // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.8'
}

jfxmobile {
    downConfig {
        version = '3.8.6'
        // Do not edit the line below. Use Gluon Mobile Settings in your project context menu instead
        plugins 'barcode-scan', 'display', 'lifecycle', 'pictures', 'position', 'statusbar', 'storage'
    }
    android {
        manifest = 'src/android/AndroidManifest.xml'
        dexOptions {
            javaMaxHeapSize '3g'
        }
        androidSdk='/home/cesar/Android/Sdk'
        packagingOptions {
            exclude 'META-INF/LICENSE.txt'
            exclude 'META-INF/NOTICE.txt'
            exclude 'META-INF/DEPENDENCIES.txt'
            exclude 'META-INF/LICENSE.txt'
            exclude 'META-INF/NOTICE.txt'
            exclude 'META-INF/NOTICE'
            exclude 'META-INF/LICENSE'
            exclude 'META-INF/DEPENDENCIES'
            exclude 'META-INF/notice.txt'
            exclude 'META-INF/license.txt'
            exclude 'META-INF/dependencies.txt'
            exclude 'META-INF/INDEX.LIST'
            exclude 'META-INF/LGPL2.1'
            exclude 'license.html'
            exclude 'readme.html'
            exclude 'LICENSE.txt'
            exclude 'NOTICE.txt'
            pickFirst 'META-INF/eclipse.inf'
        }
        compileSdkVersion=21
    }
    ios {
        infoPList = file('src/ios/Default-Info.plist')
        forceLinkClasses = [
                'com.gluonhq.**.*',
                'javax.annotations.**.*',
                'javax.inject.**.*',
                'javax.json.**.*',
                'org.glassfish.json.**.*'
        ]
    }
}

图片服务的Stacktrace错误:

04-21 19:31:13.678 5482-5514/com.cip.cipgesfx I/GLASS: Call InternalSurfaceView_onMultiTouchEventNative
04-21 19:31:13.678 5482-5514/com.cip.cipgesfx I/GLASS: Glass will pass multitouchevent to monocle with count = 1
04-21 19:31:13.678 5482-5514/com.cip.cipgesfx I/System.out: don't add points, primary = -1
04-21 19:31:13.688 5482-5514/com.cip.cipgesfx I/AndroidPicturesService: Picture file: file:/storage/emulated/0/Pictures/IMG_20190421_193113.jpg
04-21 19:31:13.708 5482-5514/com.cip.cipgesfx E/AndroidRuntime: FATAL EXCEPTION: JavaFX Application Thread
    Process: com.cip.cipgesfx, PID: 5482
    java.lang.NullPointerException
        at android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:584)
        at android.support.v4.content.FileProvider.getPathStrategy(FileProvider.java:558)
        at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:400)
        at com.gluonhq.charm.down.plugins.android.AndroidPicturesService.takePicture(AndroidPicturesService.java:132)
        at com.gluonhq.charm.down.plugins.android.AndroidPicturesService.takePhoto(AndroidPicturesService.java:95)
        at com.cipmobile.BasicView$2.lambda$handle$1(BasicView.java:50)
        at com.cipmobile.BasicView$2$$Lambda$1.accept(BasicView.java)
        at java.util.Optional.ifPresent(Optional.java:154)
        at com.cipmobile.BasicView$2.handle(BasicView.java:49)
        at com.cipmobile.BasicView$2.handle(BasicView.java:46)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.Node.fireEvent(Node.java:8411)
        at javafx.scene.control.Button.fire(Button.java:185)
        at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
        at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)

位置服务的Stacktrace错误:

04-21 19:33:28.648 5544-5568/com.cip.cipgesfx I/AndroidPositionService: Available location providers on this device: [passive, gps, network].
04-21 19:33:28.648 5544-5568/com.cip.cipgesfx I/AndroidPositionService: Picked network as best location provider.
04-21 19:33:28.648 5544-5568/com.cip.cipgesfx I/AndroidPositionService: Location provider network is not enabled, starting intent to ask user to activate the location provider.
04-21 19:33:28.668 5544-5568/com.cip.cipgesfx E/AndroidRuntime: FATAL EXCEPTION: JavaFX Application Thread
    Process: com.cip.cipgesfx, PID: 5544
    android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
        at android.app.ContextImpl.startActivity(ContextImpl.java:1112)
        at android.app.ContextImpl.startActivity(ContextImpl.java:1093)
        at android.content.ContextWrapper.startActivity(ContextWrapper.java:311)
        at com.gluonhq.charm.down.plugins.android.AndroidPositionService.initialize(AndroidPositionService.java:179)
        at com.gluonhq.charm.down.plugins.android.AndroidPositionService.start(AndroidPositionService.java:110)
        at com.gluonhq.charm.down.plugins.android.AndroidPositionService.start(AndroidPositionService.java:99)
        at com.cipmobile.BasicView$4.lambda$handle$0(BasicView.java:75)
        at com.cipmobile.BasicView$4$$Lambda$1.accept(BasicView.java)
        at java.util.Optional.ifPresent(Optional.java:154)
        at com.cipmobile.BasicView$4.handle(BasicView.java:74)
        at com.cipmobile.BasicView$4.handle(BasicView.java:70)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.Node.fireEvent(Node.java:8411)
        at javafx.scene.control.Button.fire(Button.java:185)
        at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
        at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)

我希望在单击照片按钮时打开相机,但会出现异常。单击GPS按钮时也是如此。

gluon-mobile javafxports
1个回答
0
投票

对于像我这样的所有新手,我写下了正确的代码和配置。它在Android 8上运行正常。

public class BasicView extends View {

    final Label lblPosition;

    public BasicView() {
        System.setProperty("com.gluonhq.charm.down.debug", "true"); //*********************** ATTENTION

        ImageView imageView = new ImageView();
        //setting the fit height and width of the image view 
        imageView.setFitHeight(200);
        imageView.setFitWidth(200);
        //Setting the preserve ratio of the image view 
        imageView.setPreserveRatio(true);

        lblPosition = new Label("Auto");

        Label lblBarcode = new Label("Barcode");
        Label lblManualPosition = new Label("Manual Position");

        Button butExit = new Button("Exit");
        butExit.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                Services.get(LifecycleService.class).ifPresent(lifecycle -> {
                    lifecycle.shutdown();
                });
            }
        });

        Button butPhoto = new Button("Photo");
        butPhoto.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                Services.get(PicturesService.class).ifPresent(service -> {
                    service.takePhoto(false).ifPresent(image -> imageView.setImage(image));
                });

            }
        });

        Button butBarcode = new Button("Barcode");
        butBarcode.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                String barcodeValue = Services.get(BarcodeScanService.class)
                        .flatMap(service -> service
                        .scan("Scan Test", "Place a barcode under the camera", "Barcode value:"))
                        .orElse("No barcode found");
                System.out.println("Scanned Bar Code: " + barcodeValue);
                lblBarcode.setText(barcodeValue);
            }
        });

        Button butGPS = new Button("Position");
        butGPS.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                Services.get(PositionService.class)
                        .ifPresent(service -> {
                            service.positionProperty().addListener(
                                    (obs, ov, nv)
                                    -> {
                                lblManualPosition.setText("Lat=" + String.valueOf(nv.getLatitude())
                                        + " Lon=" + String.valueOf(nv.getLongitude()));
                                //System.out.printf("Current position: %.5f, %.5f",nv.getLatitude(), nv.getLongitude()));
                            });
                            service.start();
                        });
            }
        });

        VBox controls = new VBox(5);
        controls.getChildren().addAll(imageView, lblPosition, lblBarcode, lblManualPosition, butExit, butPhoto, butBarcode, butGPS);
        controls.setAlignment(Pos.CENTER);
        setCenter(controls);

        if (!Services.get(PositionService.class).isPresent()) {
            lblPosition.setText("No GPS avalilable");
        } else {
            lblPosition.setText("Found GPS");
        }
    }

    @Override
    protected void updateAppBar(AppBar appBar) {
        appBar.setNavIcon(MaterialDesignIcon.MENU.button(e -> System.out.println("Menu")));
        appBar.setTitleText("Basic View");
        appBar.getActionItems().add(MaterialDesignIcon.SEARCH.button(e -> System.out.println("Search")));
    }

}

build.gradle文件:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'org.javafxports:jfxmobile-plugin:1.3.16'
    }
}

apply plugin: 'org.javafxports.jfxmobile'

repositories {
    jcenter()
    maven {
        url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
    }
}

mainClassName = 'com.prufx.Prufx'

dependencies {
    compile 'com.gluonhq:charm:5.0.2'
}

jfxmobile {
    downConfig {
        version = '3.8.6'
        // Do not edit the line below. Use Gluon Mobile Settings in your project context menu instead
        plugins 'barcode-scan', 'display', 'lifecycle', 'pictures', 'position', 'statusbar', 'storage'
    }
    android {
        manifest = 'src/android/AndroidManifest.xml'
        dexOptions {
            javaMaxHeapSize '3g'
        }
        compileSdkVersion=28
        androidSdk='/home/cesar/Android/Sdk'
    }
    ios {
        infoPList = file('src/ios/Default-Info.plist')
        forceLinkClasses = [
                'com.gluonhq.**.*',
                'javax.annotations.**.*',
                'javax.inject.**.*',
                'javax.json.**.*',
                'org.glassfish.json.**.*'
        ]
    }
}

然后是AndroidManifest.xml:

<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.prufx" android:versionCode="1" android:versionName="1.0">
    <supports-screens android:xlargeScreens="true"/>
    <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"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.CAMERA"/>

    <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="21"/>
    <application android:label="prufx" android:name="android.support.multidex.MultiDexApplication" android:icon="@mipmap/ic_launcher">
        <activity android:name="javafxports.android.FXActivity" android:label="prufx" android:configChanges="orientation|screenSize">
            <meta-data android:name="main.class" android:value="com.prufx.Prufx"/>
            <meta-data android:name="debug.port" android:value="0"/>
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <activity android:name="com.gluonhq.impl.charm.down.plugins.android.PermissionRequestActivity" />

        <activity android:name="com.gluonhq.impl.charm.down.plugins.android.scan.zxing.CaptureActivity"
                  android:screenOrientation="sensorPortrait"
                  android:clearTaskOnLaunch="true"
                  android:stateNotNeeded="true"
                  android:windowSoftInputMode="stateAlwaysHidden">
            <intent-filter>
                <action android:name="com.gluonhq.charm.down.plugins.android.scan.SCAN"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>

        <service android:name="com.gluonhq.impl.charm.down.plugins.android.AndroidPositionBackgroundService" 
                 android:process=":positionBackgroundService" />

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.prufx.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_provider_paths" />
        </provider>    

    </application>
</manifest>

© www.soinside.com 2019 - 2024. All rights reserved.