- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当我第一次启动我的 Android 应用程序时,它会触发一个对话框来询问位置权限。问题是 onRequestPermissionsResult
在我有机会按下允许或拒绝之前已经被触发。因此,应用程序在第一次启动时没有权限,也没有设置地理围栏。当然,当我重新启动应用程序时,所有权限都被授予并且地理围栏正常工作。我如何在第一次启动时解决这个问题?
public class MainActivity extends BaseActivity implements OnRetailerClickListener, NetworkListener, GoogleApiClient.ConnectionCallbacks {
public final int REQUEST_LOCATION_PERMISSION = 2222;
private GoogleApiClient googleApiClient;
private ViewPager mViewPager;
private PagerAdapter mPagerAdapter;
private OnBackPressedListener onBackPressedListener;
private List<Geofence> geofenceList;
private Intent intent;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Setup custom toolbar for viewpager layout */
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Overview");
setSupportActionBar(toolbar);
/* Setup TabLayout for viewpager tabs */
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_products));
tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_map));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
/* register to the geofence observer */
AppClassWiring.geofenceDao().registerObserver(this);
/* build up GoogleApiClient and connect, used to set the geofences */
googleApiClient = new GoogleApiClient
.Builder(this)
.addConnectionCallbacks(this)
.addApi(LocationServices.API).build();
googleApiClient.connect();
/* create a viewpager for the fragments */
mViewPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
mViewPager.setPageTransformer(true, new ZoomOutPageTransformer());
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setOffscreenPageLimit(mPagerAdapter.getCount()); // all fragments are kept in memory because there are only 3
initViewPagerListeners(mViewPager, tabLayout);
}
@Override
protected void onResume() {
super.onResume();
if(!DeviceUtils.checkBluetooth())
askBluetooth();
}
/**
* The OnClickListener in the fragment will trigger this method.
* This way the app can switch to the correct page in the viewpager
*
* @param retailer object received from fragment
*/
@Override
public void onRetailerClick(Retailer retailer) {
mViewPager.setCurrentItem(PagerAdapter.FRAGMENT_MAP, true);
mPagerAdapter.getItemForPosition(1).onRetailerClick(retailer);
}
/**
* Init the ViewPagerListeners, used to add an onPageChangeLister for the TabLayout
* also closes the keyboard when changing pages
*
* @param viewPager instance of the used viewpager
* @param tabLayout instance of the used TabLayout above
*/
private void initViewPagerListeners(final ViewPager viewPager, TabLayout tabLayout) {
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
DeviceUtils.hideKeyboard(MainActivity.this);
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
DeviceUtils.hideKeyboard(MainActivity.this);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
/**
* Builder method to build up a Geofencingrequest with the retrieved backend data
*
* @param geofences to provide the data, required for a geofence to be built. This can be:
* an Id, Latitude, Longitude, Radius, ExpirationDuration and TransitionTypes
* @return a new instance of a GeofencingRequest
*/
private GeofencingRequest buildGeofenceRequest(List<Geofence> geofences) {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(geofences);
return builder.build();
}
@Override
public void onConnectionSuspended(int i) {
Toast.makeText(this, "Could not connect with the Google API", Toast.LENGTH_LONG).show();
}
private void askBluetooth() {
new AlertDialog.Builder(this)
.setTitle("Enable bluetooth")
.setMessage("Bluetooth should be enabled, Turn bluetooth on?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
DeviceUtils.setBluetoothOn(true);
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
DeviceUtils.setBluetoothOn(false);
}
})
.setIcon(android.R.drawable.stat_sys_data_bluetooth)
.show();
}
/**
* When the GoogleApiClient is connected,
* the user is able to get all the geofences from the backend
*
* @param bundle null
*/
@Override
public void onConnected(@Nullable Bundle bundle) {
/* Trigger the network call to get all geofences.
The results can be shared with other classes that also listen to it */
AppClassWiring.geofenceDao().getAllGeofences();
}
/**
* Observable method that listens to the incoming results of the network call for geofences
*
* @param pointList recieved geofence/point objects from the API.
* Used to build up a GeofencingRequest. After building the GeofencingRequest,
* the data is provided to the GoogleApiClient to setup the geofences ready to trigger
*/
@Override
public void onResult(Object pointList) {
List<Point> points = (List<Point>) pointList;
geofenceList = new ArrayList<>();
for (int i = 0; i < points.size(); i++) {
geofenceList.add(new Geofence.Builder()
.setRequestId(points.get(i).getRetailer())
.setCircularRegion(
points.get(i).getValidLat(),
points.get(i).getValidLong(),
points.get(i).getValidRadius())
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER
| Geofence.GEOFENCE_TRANSITION_EXIT)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.build());
}
intent = new Intent(this, GeoFencingService.class);
// Permission check
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION);
} else {
LocationServices.GeofencingApi.addGeofences(
googleApiClient,
buildGeofenceRequest(geofenceList),
PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_LOCATION_PERMISSION: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationServices.GeofencingApi.addGeofences(
googleApiClient,
buildGeofenceRequest(geofenceList),
PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
}
}
}
}
}
/**
* @param error provides the error that was thrown by the retrofit call.
*/
@Override
public void onError(NetworkException error) {
Toast.makeText(this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
onBackPressedListener = null;
/* unregister from the geofence observer */
AppClassWiring.geofenceDao().unregisterObserver(this);
super.onDestroy();
}
@Override
public void onBackPressed() {
if (onBackPressedListener != null)
onBackPressedListener.doBack();
else
super.onBackPressed();
}
public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
this.onBackPressedListener = onBackPressedListener;
}
}
最佳答案
在 onCreate() 方法中使用此方法:
requestStoragePermission();
并在 onCreate() 方法之外定义此方法:
private void requestStoragePermission() {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
return;
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
return;
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)
return;
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED)
return;
ActivityCompat.requestPermissions(this, new String[]
{
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
android.Manifest.permission.CAMERA,
android.Manifest.permission.READ_PHONE_STATE,
}, STORAGE_PERMISSION_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
//Checking the request code of our request
if (requestCode == STORAGE_PERMISSION_CODE) {
//If permission is granted
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Displaying a toast
} else {
//Displaying another toast if permission is not granted
Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show();
}
}
}
关于首次启动时的 Android 运行时权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44592161/
SQLite、Content provider 和 Shared Preference 之间的所有已知区别。 但我想知道什么时候需要根据情况使用 SQLite 或 Content Provider 或
警告:我正在使用一个我无法完全控制的后端,所以我正在努力解决 Backbone 中的一些注意事项,这些注意事项可能在其他地方更好地解决......不幸的是,我别无选择,只能在这里处理它们! 所以,我的
我一整天都在挣扎。我的预输入搜索表达式与远程 json 数据完美配合。但是当我尝试使用相同的 json 数据作为预取数据时,建议为空。点击第一个标志后,我收到预定义消息“无法找到任何内容...”,结果
我正在制作一个模拟 NHL 选秀彩票的程序,其中屏幕右侧应该有一个 JTextField,并且在左侧绘制弹跳的选秀球。我创建了一个名为 Ball 的类,它实现了 Runnable,并在我的主 Draf
这个问题已经有答案了: How can I calculate a time span in Java and format the output? (18 个回答) 已关闭 9 年前。 这是我的代码
我有一个 ASP.NET Web API 应用程序在我的本地 IIS 实例上运行。 Web 应用程序配置有 CORS。我调用的 Web API 方法类似于: [POST("/API/{foo}/{ba
我将用户输入的时间和日期作为: DatePicker dp = (DatePicker) findViewById(R.id.datePicker); TimePicker tp = (TimePic
放宽“邻居”的标准是否足够,或者是否有其他标准行动可以采取? 最佳答案 如果所有相邻解决方案都是 Tabu,则听起来您的 Tabu 列表的大小太长或您的释放策略太严格。一个好的 Tabu 列表长度是
我正在阅读来自 cppreference 的代码示例: #include #include #include #include template void print_queue(T& q)
我快疯了,我试图理解工具提示的行为,但没有成功。 1. 第一个问题是当我尝试通过插件(按钮 1)在点击事件中使用它时 -> 如果您转到 Fiddle,您会在“内容”内看到该函数' 每次点击都会调用该属
我在功能组件中有以下代码: const [ folder, setFolder ] = useState([]); const folderData = useContext(FolderContex
我在使用预签名网址和 AFNetworking 3.0 从 S3 获取图像时遇到问题。我可以使用 NSMutableURLRequest 和 NSURLSession 获取图像,但是当我使用 AFHT
我正在使用 Oracle ojdbc 12 和 Java 8 处理 Oracle UCP 管理器的问题。当 UCP 池启动失败时,我希望关闭它创建的连接。 当池初始化期间遇到 ORA-02391:超过
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve
引用这个plunker: https://plnkr.co/edit/GWsbdDWVvBYNMqyxzlLY?p=preview 我在 styles.css 文件和 src/app.ts 文件中指定
为什么我的条形这么细?我尝试将宽度设置为 1,它们变得非常厚。我不知道还能尝试什么。默认厚度为 0.8,这是应该的样子吗? import matplotlib.pyplot as plt import
当我编写时,查询按预期执行: SELECT id, day2.count - day1.count AS diff FROM day1 NATURAL JOIN day2; 但我真正想要的是右连接。当
我有以下时间数据: 0 08/01/16 13:07:46,335437 1 18/02/16 08:40:40,565575 2 14/01/16 22:2
一些背景知识 -我的 NodeJS 服务器在端口 3001 上运行,我的 React 应用程序在端口 3000 上运行。我在 React 应用程序 package.json 中设置了一个代理来代理对端
我面临着一个愚蠢的问题。我试图在我的 Angular 应用程序中延迟加载我的图像,我已经尝试过这个2: 但是他们都设置了 src attr 而不是 data-src,我在这里遗漏了什么吗?保留 d
我是一名优秀的程序员,十分优秀!