小编Ema*_*lin的帖子

Android M - 检查运行时权限 - 如何确定用户是否选中"从不再问"?

根据这个:http://developer.android.com/preview/features/runtime-permissions.html#coding应用程序可以检查运行时权限和请求权限(如果尚未授予它).然后将显示以下对话框:

在此输入图像描述

如果用户拒绝重要权限,则应用程序应显示解释为何需要权限以及拒绝具有何种影响的解释.该对话框有两个选项:

  1. 再试一次(再次请求许可)
  2. 拒绝(app将在没有该权限的情况下工作).

Never ask again但是,如果用户检查,则不应显示带有解释的第二个对话框,尤其是如果用户之前已经拒绝过一次.现在的问题是:我的应用程序如何知道用户是否已检查过Never ask again?IMO onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)并没有给我这些信息.

第二个问题是:Google是否计划在权限对话框中添加自定义消息,以解释应用程序需要权限的原因?那样就永远不会有第二个对话框,肯定会有更好的ux.

android android-permissions android-6.0-marshmallow

288
推荐指数
10
解决办法
15万
查看次数

Android依赖项设置为compileOnly/provided,不支持

我使用com.android.tools.build:gradle:3.1.1了最新版本的摇篮(https://services.gradle.org/distributions-snapshots/gradle-4.8-20180417000132+0000-all.zip).

当我使用compileOnly依赖时,其中一些不会编译,有些会.例如

compileOnly "com.android.support:support-v4:27.1.1"
Run Code Online (Sandbox Code Playgroud)

完美的工作

compileOnly "com.facebook.stetho:stetho:1.5.0"
Run Code Online (Sandbox Code Playgroud)

给出编译错误:

Android dependency 'com.facebook.stetho:stetho:1.5.0' is set to compileOnly/provided which is not supported
Run Code Online (Sandbox Code Playgroud)

我的印象比任何依赖都可以编译.没有其他说明(https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#new_configurations).这两个库都具有传递依赖性.

任何帮助将不胜感激.

android gradle

10
推荐指数
1
解决办法
7850
查看次数

使用Intent.ACTION_CREATE_DOCUMENT(存储访问框架)选择目录/文件

如下所述:

http://www.doubleencore.com/2014/03/android-external-storage/

或者在这里:

http://www.androidpolice.com/2014/02/17/external-blues-google-has-brought-big-changes-to-sd-cards-in-kitkat-and-even-samsung-may-be-实施-他们/

KitKat将限制写入辅助外部存储到特定于程序包的目录(尽管一些开发人员已经找到了解决方法......).随着三星使用SD卡作为辅助外部存储并推出4.4.2更新,这已成为许多应用程序的主要问题.

我的应用程序有一个保存功能,允许用户选择一个任意目录来保存文件.我正在使用像org.openintents.action.PICK_DIRECTORY,com.estrongs.action.PICK_DIRECTORY或我的集成文件资源管理器这样的Intents来选择一个目录.用户当然可以自由选择SD卡上的任何路径,但由于KitKat的新限制,如果目录是我的应用程序没有写访问权限,实际的存储操作将失败.

我需要一种替代方法来选择KitKat上的目录,以便用户在尝试保存到SD卡时不会收到错误消息.这可以通过让他们只选择应用程序具有写访问权限的目录来实现.

我尝试使用Intent.ACTION_CREATE_DOCUMENT,如下所示:

Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT)
                    .addCategory(Intent.CATEGORY_OPENABLE)
                    .setType(attachment.getContentType())
                    .putExtra(Intent.EXTRA_TITLE, attachment.getName());

startActivityForResult(intent, RequestCodes.MSG_CHOOSE_DIRECTORY);
Run Code Online (Sandbox Code Playgroud)

这工作正常,我可以写入用户选择的文件但我只能选择某些目录.例如,对于pdf文件,它将返回下载目录(匹配Environment.DIRECTORY_DOWNLOADS),对于jpg,它将允许我选择下载目录和Google驱动器.但它确实没有让我选择在主外部存储器上选择其他文件夹,也不在sdcard上选择特定于包的目录(我尝试了不同的内容类型,如"*/*"或DocumentsContract.Document.MIME_TYPE_DIR,但无济于事).

所以我正在寻找的方法是让用户在主外部文件系统上选择一个目录(如Environment.getExternalStorageDirectory()实际上是内部存储器所返回的)以及框架可以访问的所有目录到辅助外部存储器中以便在该目录中保存文件.无论用户选择目录还是文件都无关紧要,应用程序将使用自己的文件名或用户选择的文件名.

或者知道某些应用程序如何找到解决新写入限制的方法当然也是一个可行的选择;-).ES文件资源管理器例如可以将任何文件写入SD卡上的任何目录,因为我可以通过我自己的测试在带有sdcard的无根S4上进行确认.

android android-intent

9
推荐指数
1
解决办法
1万
查看次数

Android应用程序包-> APK不包含必需的本机库

我正在使用新的应用程序捆绑包格式(aab)发布应用程序。该应用程序包括一些用于armeabi-v7a的本地库。当我在arm64-v8a架构上通过Google Play安装该应用程序时,它不包含没有arm64-v8a so本地文件的本机库。

根据此/sf/answers/2773574961/,armeabi-v7a库应在arm64-v8a设备上运行(并且通过adb安装时工作正常,因此确实可以工作)。

Google Play控制台会根据架构,屏幕密度等显示不同的apk。从apk大小中,我可以清楚地看出哪些不包含本机库。我还使用本机libs Monitor应用程序来分析已安装的apk,并且它显然不包括我需要的本机库(如果该应用程序具有arm64-v8a so文件,则它包括arm64-v8a本机库,但如果只有armeabi,则不包括-v7a版本)。

我的gradle构建文件包括以下用于捆绑包配置的小段代码:

    bundle {
        language {
            enableSplit = false
        }
        density {
            enableSplit = true
        }
        abi {
            enableSplit = true
//            include 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在这是我的问题:是否有办法告诉构建工具在每个apk中都包括“次优”本机库,其次是在特定体系结构上运行的最近版本?

PS:如果我为abi设置enableSplit = false,则它将包括本机库(如预期的那样),但不幸的是,对于包括x86在内的所有平台(仅20MB大)...

对于尚未看过Google Play如何将应用捆绑包拆分为APK的用户,以下是屏幕截图: 在此处输入图片说明

android google-play android-app-bundle

7
推荐指数
1
解决办法
2905
查看次数

Gradle maven-publish / Sonatype 创建多个无法关闭的存储库

我正在尝试将一个库部署到 Maven Central(我之前已经做过很多次),但在本例中它包含针对不同平台的许多不同出版物。通过插件上传maven-publish可以工作,但我最终在 Sonatype 中得到了多个存储库,每个存储库都包含文件的子集:

在此输入图像描述

因此,我无法关闭存储库,因为某些文件总是丢失(只有所有存储库一起包含通过 Sonatype 验证所需的所有文件)。

Sonatype 文档说:

为用户 ID、IP 地址和用户代理的每个组合创建一个单独的临时存储库。(https://help.sonatype.com/repomanager2/staging-releases/managing-staging-repositories

不过,对于创建的存储库来说,所有三个参数都是相同的,因此它应该创建一个。在本地发布以及从 Github 操作发布时都会发生这种情况。

回购协议在这里: https: //github.com/1gravity/Kotlin-Bloc

这是发布脚本:https://github.com/1gravity/Kotlin-Bloc/blob/master/buildSrc/src/main/kotlin/bloc-publish.gradle.kts

非常感谢任何帮助!

gradle maven kotlin kotlin-multiplatform

7
推荐指数
1
解决办法
557
查看次数

在LayoutInflater.inflate(resource,root,true)之后removeView无法正常工作

我动态地添加和删除视图到自定义视图(FrameLayout)执行此操作:

LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mMyView = inflater.inflate(resId, this, true);
Run Code Online (Sandbox Code Playgroud)

稍后我尝试删除视图,但视图不会删除:

removeView(mMyView);
Run Code Online (Sandbox Code Playgroud)

如果我这样做,一切都按预期工作:

mMyView = inflater.inflate(resId, this, **false**);
addView(mMyView);
Run Code Online (Sandbox Code Playgroud)

唯一的区别是我手动添加视图而不是让inflate调用.有谁知道为什么这会有所作为?

android view viewgroup

6
推荐指数
1
解决办法
6256
查看次数

Dashclock Widget扩展未更新

我有一个DashClockExtension有时不更新.

它使用LocalBroadcastReceiver更新类似于http://bit.ly/1e4uMl0的扩展名.接收方在onInitialize()方法中注册:

@Override
    protected void onInitialize(boolean isReconnect) {
        super.onInitialize(isReconnect);

        LocalBroadcastManager broadcastMgr = LocalBroadcastManager.getInstance(this);
        if (mDashClockReceiver != null) {
            try {
                broadcastMgr.unregisterReceiver(mDashClockReceiver);
            } catch (Exception ignore) {}
        }
        mDashClockReceiver = new DashClockUpdateReceiver();
        broadcastMgr.registerReceiver(mDashClockReceiver, new IntentFilter(UPDATE_DASHCLOCK));
    }
Run Code Online (Sandbox Code Playgroud)

这就是我发送广播的方式:

public static void updateDashClock() {
    LocalBroadcastManager.getInstance(Application.getContext()).sendBroadcast(new Intent(UPDATE_DASHCLOCK));
}        
Run Code Online (Sandbox Code Playgroud)

这是我的BroadcastReceiver:

private class DashClockUpdateReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        retrieveDataAndUpdateWidget();
    }
}
Run Code Online (Sandbox Code Playgroud)

我注意到,当广播被触发时,接收器有时不会收到该事件.
我通过杀死我的应用程序来测试它,但这不会重现问题,所以我不知道为什么会发生这种情况.

任何人?

android broadcastreceiver dashclock

6
推荐指数
1
解决办法
1142
查看次数

检索自定义视图时出现ClassCastException

我有这样的布局:

<com.mypackage.QuadPaneHorizontalSplit
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

<!-- more views here -->

</com.mypackage.QuadPaneHorizontalSplit>
Run Code Online (Sandbox Code Playgroud)

QuadPaneHorizo​​ntalSplit类扩展了QuadPaneLayout(扩展了LineraLayout):

public class QuadPaneHorizontalSplit extends QuadPaneLayout {

    public QuadPaneHorizontalSplit(Context context) {
        super(context);
    }

    public QuadPaneHorizontalSplit(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public QuadPaneHorizontalSplit(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected boolean isVerticalSplit() {
        return false;
    }

}
Run Code Online (Sandbox Code Playgroud)

使用setContentView设置布局后,我尝试检索自定义视图:

QuadPaneLayout quadPaneLayout = (QuadPaneLayout) findViewById(R.id.root_layout);
Run Code Online (Sandbox Code Playgroud)

一般来说效果很好,但我得到了一些崩溃报告,但有以下例外情况:

java.lang.ClassCastException:com.mypackage.QuadPaneHorizo​​ntalSplit无法强制转换为com.mypackage.QuadPaneLayout

QuadPaneHorizo​​ntalSplit显然扩展了QuadPaneLayout,因此不应该有例外.我收到Android 4.x设备和不同制造商的崩溃报告.有趣的是,所有的设备都扎根,所以也许这是一个自定义rom的问题?请注意,这行代码每天执行数千次没有问题,到目前为止我只有13次崩溃(BugSense),但我仍然想深究这一点.

我知道这个:https://stackoverflow.com/a/7823787/534471但我没有使用include这个布局,我不想添加合并标签,因为这可能会产生不良影响.

任何人都知道这里发生了什么?

android android-layout

6
推荐指数
1
解决办法
290
查看次数

使用粘性沉浸模式检测系统 ui 何时可见

当使用粘性沉浸模式(https://developer.android.com/training/system-ui/immersive.html)时,既不会调用 View.OnSystemUiVisibilityChangeListener 也不会清除任何可见性标志(如 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION):

粘滞标志——这是您在使用 IMMERSIVE_STICKY 标志时看到的 UI,并且用户滑动以显示系统栏。半透明条暂时出现,然后再次隐藏。滑动操作不会清除任何标志,也不会触发您的系统 UI 可见性更改侦听器,因为系统栏的瞬时外观不被视为 UI 可见性更改。

我有一个带有复杂手势检测代码的视图。向下滑动以显示系统导航 ui 确实会干扰这些手势。如果我使用常规沉浸模式,我可以检查系统导航 ui 是否可见,在这种情况下,我会忽略手势,但使用粘性模式则无法进行检查(如上所述)。

有谁知道如何确定系统导航 ui 在粘性沉浸模式下是否可见,或者有没有人知道如何处理干扰我自己的手势检测代码的向下滑动?

我知道这个问题Detecting when system buttons are visible while using 'immersive mode'但我见过使用粘性沉浸模式和手势检测的应用程序,不会被向下滑动搞砸。

android

6
推荐指数
0
解决办法
2582
查看次数

GoogleAccountCredential.setSelectedAccountName(String)在没有"联系人"权限的Android 6.0上无效

我正在使用以下方法检索GoogleAccountCredential对象:

GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(
                context, Arrays.asList({ GmailScopes.MAIL_GOOGLE_COM }))
                .setBackOff(new ExponentialBackOff())
                .setSelectedAccountName(email)
Run Code Online (Sandbox Code Playgroud)

电子邮件是我在设备上使用的Gmail帐户.

如果我使用credential.getSelectedAccountName检索帐户名,则结果为null.

这仅在运行Android Marshmallow的设备上发生,并且仅在应用程序没有"联系人"权限时才会发生.只要我授予"联系人"权限,一切正常.

为什么GoogleAccountCredential.setSelectedAccountName(String)需要"联系"权限?这是一个错误还是一个功能?

android oauth-2.0 android-permissions google-oauth android-6.0-marshmallow

4
推荐指数
1
解决办法
1320
查看次数

如何确定应用程序是否在Android M上运行(开发者预览版)

注意:这个问题是针对Android M开发者预览而不是官方Android 6.0.

android.os.Build.VERSION.SDK_INT在Android M上返回22(22是LOLLIPOP_MR1的api级别).我们如何检查应用程序是否在Android M上运行?我有这样的想法,但显然不起作用:

public boolean isAndroidMOrHigher() {
    return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.MNC;
}
Run Code Online (Sandbox Code Playgroud)

我为什么需要这个?例如,检查我是否需要请求权限,因为Android M有一个新的权限模型.

我能做到这一点:

public boolean isAndroidMOrHigher() {
    return "M".equalsIgnoreCase(Build.VERSION.RELEASE);
}
Run Code Online (Sandbox Code Playgroud)

但这似乎是一个黑客IMO.

真的有两个问题:

  • 最干净的方法是什么?
  • 这是一个错误还是应该是这样的?

android android-6.0-marshmallow

2
推荐指数
1
解决办法
3025
查看次数