Android 图书馆后台服务

Android 图书馆后台服务,android,ibeacon,altbeacon,Android,Ibeacon,Altbeacon,下面是我用来检测enter region事件的示例代码: public class BeaconApplication extends android.app.Application implements BootstrapNotifier { private static final String TAG = "TAGTAG"; @Override public void onCreate() { super.onCreate()

下面是我用来检测enter region事件的示例代码:

public class BeaconApplication extends android.app.Application implements BootstrapNotifier {

    private static final String TAG = "TAGTAG";
    
    @Override public void onCreate() {
        super.onCreate();
        Log.d(TAG, "App started up");
        new BackgroundPowerSaver(this);
        new RegionBootstrap(this, new Region(getPackageName(), null, null, null));
    }

    @Override public void didDetermineStateForRegion(int arg0, Region arg1) {
        Log.d(TAG, "didDetermineStateForRegion");
    }

    @Override public void didEnterRegion(Region arg0) {
        Log.d(TAG, "didEnterRegion");
    }

    @Override public void didExitRegion(Region arg0) {
        Log.d(TAG, "didExitRegion");
    }
}
问题在于,如果我使用下面的build.gradle配置,那么一切都会像预期的那样工作

compileSdkVersion 21
    buildToolsVersion "21.0.0"
    defaultConfig {
        applicationId "com.test"
        minSdkVersion 18
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
日志:

D/TAGTAG:应用程序已启动

D/TAGTAG:DidDeterministateForRegion

D/TAGTAG:didEnterRegion

但是,如果我将compileSdkVersion更改为实际版本,则没有任何效果

compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
    applicationId "com.test"
    minSdkVersion 18
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
}
日志:

D/TAGTAG:应用程序已启动

从安卓6.0棉花糖开始,扫描蓝牙设备(包括信标)的应用程序必须获得动态定位权限,才能这样做。出于传统目的,在API 23之前的旧Android SDK上运行的应用程序仍然可以扫描蓝牙LE设备,但只能在前台运行。这就是如果你的目标是SDK 21,而不是SDK 23,那么你的应用程序可以工作的原因

要在以SDK 23为目标时解决此问题,只需添加动态权限请求

  private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
  ...
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      ...
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {   
          // Android M Permission check    
          if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {        
              final AlertDialog.Builder builder = new AlertDialog.Builder(this);
              builder.setTitle("This app needs location access");
              builder.setMessage("Please grant location access so this app can detect beacons.");
              builder.setPositiveButton(android.R.string.ok, null);
              builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                      @Override?
                      public void onDismiss(DialogInterface dialog) {
                              requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);?            
                      }
              });
              builder.show();  
          }
      }   
  }

  @Override
  public void onRequestPermissionsResult(int requestCode,
                                             String permissions[], int[] grantResults) {
      switch (requestCode) {
          case PERMISSION_REQUEST_COARSE_LOCATION: {
              if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                  Log.d(TAG, "coarse location permission granted");
              } else {
                  final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                  builder.setTitle("Functionality limited");
                  builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
                  builder.setPositiveButton(android.R.string.ok, null);
                  builder.setOnDismissListener(new DialogInterface.OnDismissListener() {

                      @Override
                      public void onDismiss(DialogInterface dialog) {
                      }

                  });
                  builder.show();
              }
              return;
          }
      }
  }
有关如何执行此操作的详细说明,请参见:

我在这里写了一篇关于这个话题的博文:

编辑:正如@Near1999在下面的评论中所指出的,一些安卓5+版本也不会检测到可移动设备,除非在设置中打开位置服务。显然,此限制也仅适用于针对SDK 23+的情况。请参见此处了解更多信息:

从Android 6.0棉花糖开始,扫描蓝牙LE设备(包括信标)的应用程序必须获得动态位置权限,然后才允许这样做。出于传统目的,在API 23之前的旧Android SDK上运行的应用程序仍然可以扫描蓝牙LE设备,但只能在前台运行。这就是如果你的目标是SDK 21,而不是SDK 23,那么你的应用程序可以工作的原因

要在以SDK 23为目标时解决此问题,只需添加动态权限请求

  private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
  ...
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      ...
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {   
          // Android M Permission check    
          if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {        
              final AlertDialog.Builder builder = new AlertDialog.Builder(this);
              builder.setTitle("This app needs location access");
              builder.setMessage("Please grant location access so this app can detect beacons.");
              builder.setPositiveButton(android.R.string.ok, null);
              builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                      @Override?
                      public void onDismiss(DialogInterface dialog) {
                              requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);?            
                      }
              });
              builder.show();  
          }
      }   
  }

  @Override
  public void onRequestPermissionsResult(int requestCode,
                                             String permissions[], int[] grantResults) {
      switch (requestCode) {
          case PERMISSION_REQUEST_COARSE_LOCATION: {
              if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                  Log.d(TAG, "coarse location permission granted");
              } else {
                  final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                  builder.setTitle("Functionality limited");
                  builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
                  builder.setPositiveButton(android.R.string.ok, null);
                  builder.setOnDismissListener(new DialogInterface.OnDismissListener() {

                      @Override
                      public void onDismiss(DialogInterface dialog) {
                      }

                  });
                  builder.show();
              }
              return;
          }
      }
  }
有关如何执行此操作的详细说明,请参见:

我在这里写了一篇关于这个话题的博文:


编辑:正如@Near1999在下面的评论中所指出的,一些安卓5+版本也不会检测到可移动设备,除非在设置中打开位置服务。显然,此限制也仅适用于针对SDK 23+的情况。有关更多信息,请参见此处:

对于测试,我通过app info允许位置权限。动态权限和app info->permissions之间有什么区别吗?我不确定您使用什么工具来设置app info->permissions,但我怀疑它只设置AndroidManifest.xml中声明的权限。你也必须这样做,但从Android 6.0开始这还不够。某些权限在运行时也需要动态请求。我在菜单中按住应用程序图标,将其拖到应用程序信息的顶部,然后选择权限并在那里启用位置权限如果没有该权限,我的LogCat中有错误,这意味着我需要获得位置权限。如果我用上面描述的方法启用它,这个错误就消失了。与您编写相同情况时具有运行时权限。因此,启用权限的方式没有区别。问题仍然没有解决哇,在我的手机上启用位置共享GPS后,我开始寻找信标…为了测试,我通过应用程序信息允许位置权限。动态权限和app info->permissions之间有什么区别吗?我不确定您使用什么工具来设置app info->permissions,但我怀疑它只设置AndroidManifest.xml中声明的权限。你也必须这样做,但从Android 6.0开始这还不够。某些权限在运行时也需要动态请求。我在菜单中按住应用程序图标,将其拖到应用程序信息的顶部,然后选择权限并在那里启用位置权限如果没有该权限,我的LogCat中有错误,这意味着我需要获得位置权限。如果我用上面描述的方法启用它,这个错误就消失了。与您编写相同情况时具有运行时权限。因此,启用权限的方式没有区别。问题还没有解决哇,在我的手机上启用位置共享GPS后,我开始寻找信标。。。