Gluon Mobile - Android:访问位置时要求位置许可

时间:2018-05-18 22:58:36

标签: android gluon-mobile runtime-permissions

我们在基于Gluon的应用中在地图上显示用户位置。只要用户打开“位置”,这样就可以正常工作(我们还需要调整一些较小的东西)。但是,当它没有打开时,应用程序崩溃。 “AndroidManifest.xml”包含所需的权限行。我们尝试了几个Android版本,从5.1.1到6.0.1再到7.1.1,检查它是否与Android版本本身有关。

另一方面,当我们在iPhone上使用我们的应用程序时,系统会处理此请求并提示用户允许访问该位置。即使用户拒绝,该应用也会崩溃。

有没有办法为Android实现相同的行为?

编辑以便更好地理解: jfxmobile版本1.3.10

的AndroidManifest.xml:

    <?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ch" android:versionCode="1"
          android:versionName="0.9.6 Beta">
    <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="21" android:targetSdkVersion="23"/>

    <application android:label="BodenDok" android:name="android.support.multidex.MultiDexApplication"
                 android:icon="@mipmap/ic_launcher"
                 android:largeHeap="true">
        <activity android:name="javafxports.android.FXActivity" android:label="BodenDok"
                  android:screenOrientation="portrait"
                  android:configChanges="orientation|screenSize">
            <meta-data android:name="main.class" android:value="ch.BodenDok"/>
            <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>
        <!-- Permission request, Android 23+ -->
        <activity android:name="com.gluonhq.impl.charm.down.plugins.android.PermissionRequestActivity" />

        <activity android:name="com.gluonhq.impl.charm.down.plugins.android.NotificationActivity"
                  android:parentActivityName="javafxports.android.FXActivity">
            <meta-data android:name="android.support.PARENT_ACTIVITY"
                       android:value="javafxports.android.FXActivity"/>
        </activity>
        <receiver android:name="com.gluonhq.impl.charm.down.plugins.android.AlarmReceiver" />
    </application>
</manifest>

的build.gradle:

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

apply plugin: 'org.javafxports.jfxmobile'
apply plugin: 'checkstyle'

ext.checkstyleVersion    = '8.3'

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

mainClassName = 'ch.BodenDok'

dependencies {
    compile 'com.gluonhq:charm:5.0.0'
    // https://mvnrepository.com/artifact/org.controlsfx/controlsfx
    compile group: 'org.controlsfx', name: 'controlsfx', version: '8.40.14'

    testCompile 'junit:junit:4.12'
}

jfxmobile {
    downConfig {
        version = '3.8.0'
        // Do not edit the line below. Use Gluon Mobile Settings in your project context menu instead
        plugins 'compass', 'display', 'lifecycle', 'local-notifications', 'magnetometer', 'pictures', 'position', 'runtime-args', 'settings', 'share', 'statusbar', 'storage'
    }
    android {
        manifest = 'src/android/AndroidManifest.xml'
        compileSdkVersion = 25
    }
    ios {
        infoPList = file('src/ios/Default-Info.plist')
        forceLinkClasses = [
                'com.gluonhq.**.*',
                'javax.annotations.**.*',
                'javax.inject.**.*',
                'javax.json.**.*',
                'org.glassfish.json.**.*'
        ]
    }
}

checkstyle {
    toolVersion ="${checkstyleVersion}"
    configFile = project(':').file('config/checkstyle/checkstyle.xml')
    configProperties = [ "suppressionFile" : project(':').file('config/checkstyle/suppressions.xml')]
}
编辑:看起来像是行

 <activity android:name="com.gluonhq.impl.charm.down.plugins.android.PermissionRequestActivity" />
JoséPereda建议的

不在申请标签内。现在Android 7.1.2直接显示位置屏幕,Android 5.1.1仍然会崩溃应用程序。有什么方法可以询问运行哪个Android版本?例如。 “Platform.Android.version”或“MobileApplication.Android.version”以便我们可以相应地捕获错误?

1 个答案:

答案 0 :(得分:0)

嗯,Trick是在这里使用显式广播接收器。在此代码中,当GPS未连接或关闭时,将显示一个对话框提醒您关于NO Gps连接,单击“重试”将转到设置页面,您可以在此处打开GPS。

广播接收器的显式方法

 private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) {
      if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
          checkGPS();
      }

  }  };

用于询问用户的权限(运行时权限)

  public boolean checkLocationpermission() {
  if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
      if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
          ActivityCompat.requestPermissions(this, new String[] {
              Manifest.permission.ACCESS_FINE_LOCATION
          }, 1001);
      } else {
          ActivityCompat.requestPermissions(this, new String[] {
              Manifest.permission.ACCESS_FINE_LOCATION
          }, 1003);

      }
      return false;
  } else
      return true;  }

CheckGps方法

 public void checkGPS() {
 builder = new AlertDialog.Builder(this);
 builder.setTitle("NO GPS");
 if (isGPSready()) {
     System.out.println("GPs Connected");
 } else {
     builder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
         @Override
         public void onClick(DialogInterface dialogInterface, int i) {
             if (!isGPSready()) {
                 startActivityForResult(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS), 1001);

                 builder.show();
             } else if (isGPSready()) {
                 System.out.println("the connection is succsful");

             }
         }
     }).setNegativeButton("No", new DialogInterface.OnClickListener() {
         @Override
         public void onClick(DialogInterface dialogInterface, int i) {
             finish();
         }
     });
     builder.show();
 } }

onActivityResult方法

 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
   if (requestCode == 1001) {
       if (mLocationManager == null) {
           mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
       } else if (!mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
           checkGPS();
       }

   }
   super.onActivityResult(requestCode, resultCode, data);   }

以下是完整代码

公共类MainActivity扩展了AppCompatActivity {

AlertDialog.Builder builder;
LocationManager mLocationManager;

private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
            //isGPSready();
            checkGPS();
        }

    }
};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    checkLocationpermission();
    checkGPS();
    registerReceiver(broadcastReceiver, new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION));
}
public boolean isGPSready() {
    mLocationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
    return mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}

public void checkGPS() {
    builder = new AlertDialog.Builder(this);
    builder.setTitle("NO GPS");
    builder.setMessage("Click on Retry to get connected to GPS");
    if (isGPSready()) {
        System.out.println("GPs Connected");
    } else {
        builder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                if (!isGPSready()) {
                    startActivityForResult(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS), 1001);
                    builder.show();
                } else if (isGPSready()) {
                    System.out.println("the connection is succsful");

                }
            }
        }).setNegativeButton("No", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                finish();
            }
        });
        builder.show();
    }

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 1001) {
        if (mLocationManager == null) {
            mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        } else if (!mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            checkGPS();
        }

    }
    super.onActivityResult(requestCode, resultCode, data);

}

public boolean checkLocationpermission() {
    if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
            ActivityCompat.requestPermissions(this, new String[] {
                Manifest.permission.ACCESS_FINE_LOCATION
            }, 1001);
        } else {
            ActivityCompat.requestPermissions(this, new String[] {
                Manifest.permission.ACCESS_FINE_LOCATION
            }, 1003);
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
        }
        return false;
    } else
        return true;
}}