在 Android M 中,如果用户手动更改我的应用程序设置中的权限,它总是会重新启动我的应用程序和 Activity。这会导致大多数屏幕出现异常行为。
是否有广播接收器知道用户已从设置中撤销/授予权限?或者还有其他方法来处理这种重启行为吗?
当第一个活动暂停时,我开始第二个活动。
FirstActivity.java
@Override
public void onPause(){
super.onPause();
startActivity(new Intent(this, SecondActivity.class));
}
Run Code Online (Sandbox Code Playgroud)
当我按下主屏幕按钮时,SecondActivity 将启动,但会有延迟。在这段延迟中,有足够的时间打开新应用程序(例如Messenger)。但是,当我打开一个新应用程序时,SecondActivity 将不再启动(它甚至不会调用 SecondActivity 的 onCreate 方法)。
即使我打开一个新应用程序,如何仍然启动 SecondActivity?
在 Marshmallow 的运行时权限的 Android 文档中,以下代码注释指的是取消权限请求:
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Run Code Online (Sandbox Code Playgroud)
我无法确定如何实际取消权限请求,以便 grantResults 数组返回长度 == 0。请求权限的对话框仅允许用户允许或拒绝该请求,因此可以通过以下方式取消请求用户操作不明显。
然而,我运行了 Monkey,它至少成功完成了一次。
onRequestPermissionResult 的文档表明可以取消。
如何重现 grantResults 长度为 0 的情况(这表明这是一个已取消的请求)?(String[] grantResults 不为 null,但长度为 0)
我有一个应用程序提供使用指纹进行身份验证。
在询问用户是否想要启用它之前,我会验证它是否可用,并且是通过以下方式完成的:
FingerprintManager fingerprintManager = context.getSystemService(FingerprintManager.class);
return fingerprintManager.isHardwareDetected() && fingerprintManager.hasEnrolledFingerprints();
Run Code Online (Sandbox Code Playgroud)
FingerprintManager的两个方法都注释有:
@RequiresPermission(USE_FINGERPRINT)
Run Code Online (Sandbox Code Playgroud)
但是,USE_FINGERPRINT 权限是普通权限,如http://developer.android.com/guide/topics/security/normal-permissions.html中所指定。这意味着,一旦您在AndroidManifest.xml文件中声明该权限(我们这样做,该功能已经过测试并在测试设备上运行),您就不必在运行时检查它。
根据 Fabric 崩溃报告的报告,现在发生的情况是,一些用户在调用FingerprintManager.isHardwareDetected()时崩溃:
java.lang.SecurityException: Must have android.permission.USE_FINGERPRINT permission.: Neither user 10150 nor current process has android.permission.USE_FINGERPRINT.
Run Code Online (Sandbox Code Playgroud)
到目前为止,已经有 2 位用户出现这种情况,他们都使用 Marshmallow(Android 6.0),但他们都没有 root(据 Fabric 报道),设备是 LG G4 Stylus(LG H635)和 Sony Xperia Z5 Premium(Sony E6853)。
关于这如何可能以及可能的解决方案有什么解释吗?
如果这些用户不是使用普通 Android,我想说他们能够通过自定义 ROM 功能(例如 CyanogenMod 的隐私保护)来操纵应用程序权限。但事实似乎并非如此。
堆栈跟踪是:
Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{MY.PACKAGE/MY.PACKAGE.MYACTIVITY}: java.lang.SecurityException: Must have android.permission.USE_FINGERPRINT permission.: Neither user 10150 nor …Run Code Online (Sandbox Code Playgroud) android android-permissions android-6.0-marshmallow android-fingerprint-api
我正在触发一个 DatePickerDialog,它工作并显示良好,直到 api 22 (Android 5.1),我在其上设置混合和最大日期(最小 = 当前日期,最大 = 从当前日期开始的 1 个月),但它只是显示当前日期在 Api 23 中,我附上了代码和图像。
///////////////////////////////datepickerdialog///////////////////////////////
public static class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener{
@Override
public Dialog onCreateDialog(Bundle savedInstanceState){
final Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
/*
Create a DatePickerDialog using Theme.
DatePickerDialog(Context context, int theme, DatePickerDialog.OnDateSetListener listener,
int year, int monthOfYear, int dayOfMonth)
*/
// DatePickerDialog THEME_DEVICE_DEFAULT_LIGHT
DatePickerDialog dpd = new DatePickerDialog(getActivity(),this,year,month,day);
if (Build.VERSION.SDK_INT < 22){
dpd.getDatePicker().setCalendarViewShown(true);
dpd.getDatePicker().setSpinnersShown(false);
dpd.getDatePicker().getCalendarView().setShowWeekNumber(false); …Run Code Online (Sandbox Code Playgroud) 在我们的应用程序分析中,我们注意到getIntent().getExtras()呼叫崩溃的数量有所增加。它是间歇性的,我们无法复制它。
崩溃有两种情况:
12 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.os.Parcel.dataSize()' on a null object reference
13 at android.os.BaseBundle.<init>(BaseBundle.java:126)
14 at android.os.Bundle.<init>(Bundle.java:102)
15 at android.content.Intent.getExtras(Intent.java:5685)
Run Code Online (Sandbox Code Playgroud)
和
12 Caused by: java.lang.IllegalArgumentException
13 at android.os.Parcel.nativeAppendFrom(Native Method)
14 at android.os.Parcel.appendFrom(Parcel.java:458)
15 at android.os.BaseBundle.<init>(BaseBundle.java:126)
16 at android.os.Bundle.<init>(Bundle.java:102)
17 at android.content.Intent.getExtras(Intent.java:5685)
Run Code Online (Sandbox Code Playgroud)
检索代码基本上如下onResume() {... getIntent().getExtras() ...}。我们检查包是否不为空,但它在此之前崩溃了。
我们确实通过了自定义的可打包,但正在通过对其进行编组和解组的广泛单元测试。
这些崩溃的有趣统计数据是,它主要发生在 Android 6+ 上(记录的 72% 的会话中,95% 的崩溃发生在 Android 6+ 上)。此外,三星设备上很少发生意外崩溃(该制造商记录的 73% 的会话中只有 10% 发生崩溃)。
此崩溃对应用程序崩溃率造成约 0.15% 的影响,并且呈上升趋势(可能是因为 API23+ 上的数量或用户不断增加)。
有人遇到过类似的事情或者已经有解决方案了吗?
crash android parcelable android-intent android-6.0-marshmallow
Firebase 崩溃报告捕获的异常:
异常 java.lang.RuntimeException:无法启动活动 ComponentInfo{com.talmir.mickinet/com.talmir.mickinet.activities.HomeActivity}:android.content.res.Resources$NotFoundException:资源 ID 0x7f080058 android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2249) android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2299) android.app.ActivityThread.access$700 (ActivityThread.java:154) android.app.ActivityThread$H.handleMessage ...
由 android.content.res.Resources$NotFoundException 引起:资源 ID 0x7f080058 android.content.res.Resources.getValue (Resources.java:1883) android.support.v7.widget.AppCompatDrawableManager.c (SourceFile:332) android.support .v7.widget.AppCompatDrawableManager.a (SourceFile:197) android.support.v7.widget.AppCompatDrawableManager.getDrawable ...
HomeActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home); // line 238
FirebaseCrash.log("HomeActivity");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
if (!canAccessCamera() || !canAccessExternalStorage() || !canAccessContacts())
requestPermissions(INITIAL_PERMISSIONS, INITIAL_REQUEST);
copyRawFile(R.raw.file_receive);
// other codes...
Run Code Online (Sandbox Code Playgroud)
活动主页.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_home"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.talmir.mickinet.activities.HomeActivity"
android:background="@color/snow">
<fragment
android:id="@+id/frag_list"
class="com.talmir.mickinet.fragments.DeviceListFragment"
android:layout_width="match_parent"
android:layout_height="@dimen/phone_list_height">
</fragment>
<fragment
android:id="@+id/frag_detail" …Run Code Online (Sandbox Code Playgroud) java android android-lifecycle android-4.2-jelly-bean android-6.0-marshmallow
我有一个定期运行以保持网络连接活动的方法。在打瞌睡模式期间,我想禁止它定期运行,并在维护窗口期间只运行一次。当设备退出打瞌睡状态时,我希望再次定期调用该方法。我怎样才能做到这一点?
我已经注册了一个接收器,用于监听PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED广播然后调用PowerManager.isDeviceIdleMode()。但是,这两种情况都会返回 false - 在维护时段期间和设备退出 Doze 模式时。我如何区分它们?
我有一个 FileObserver 观察外部存储中文件夹上的 ALL_EVENTS (用于测试目的)。
FileObserver 将触发源自平板电脑的任何事件。例如,如果我的应用程序或平板电脑上的另一个应用程序在此文件夹中创建了一个文件,则它可以正常工作。
但是,在较新的 Marshmallow 系统上,使用 MTP 复制文件时不会触发任何内容。如果我用 shell 复制文件也是如此。一切都可以在我们之前的 Lollipop 系统上运行。
知道为什么会发生这种情况吗?
我正在尝试使用 WorkManager 运行后台服务。当应用程序进入后台时,我启动了 WorkManager。每当 WorkManger 运行时,我也会启动后台服务。应用程序进入后台后,我可以看到我的应用程序服务。我还可以看到,它是在我通过在应用程序列表中滑动关闭应用程序后大约 15 分钟后启动的。所以我确信 Workmanager 在开始时正在工作。但我认为它不适用于打瞌睡模式。将手机从打瞌睡模式唤醒后,我也看不到我的服务。
我的代码:
public class MyWorker extends Worker {
public MyWorker() {
super();
}
@NonNull
@Override
public WorkerResult doWork() {
Intent intent = new Intent(getApplicationContext(), MyService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
MyJobIntentService.enqueueWork(getApplicationContext(), new Intent());
} else {
Intent intent = new Intent(getApplicationContext(), MyService.class);
getApplicationContext().startService(intent);
}
return WorkerResult.SUCCESS;
}
}
public void startWorkManger() {
PeriodicWorkRequest request = new PeriodicWorkRequest
.Builder(MyWorker.class, MIN_PERIODIC_INTERVAL_MILLIS, TimeUnit.MILLISECONDS).addTag(TAG).build();
mWorkManager.enqueue(request);
}
Run Code Online (Sandbox Code Playgroud)
有什么不对?
android android-6.0-marshmallow android-7.0-nougat android-8.0-oreo android-workmanager