小编and*_*per的帖子

是否可以在安装时添加gradle任务以授予所有需要的权限?

背景

从Android 6开始,每次安装应用程序时,都需要在运行时授予其权限。

问题

从IDE运行应用程序时,这可能会变得非常烦人,因为每次尝试试用应用程序(如果未安装)时都需要重新授予权限,这是繁琐的操作,尤其是当您具有多个权限时。

当然,以这种方式测试应用程序也很重要,因为这是用户使用应用程序的方式,但是从某个时候开始就不需要了,因为您已经很好地处理了它

我尝试过的

我唯一发现的是如何为此(此处)创建新的gradle任务,但这与安装不兼容。相反,我需要单独运行它,但是为此,无论如何,我只能使用adb命令使用批处理文件。

我发现(这里)的另一件事是做到这一点,但又由于某种原因在启动之前重新安装(这意味着您要两次安装该应用程序,而不是每次安装一次)。这不是一个好的解决方案。

问题

有没有一种方法可以在通过IDE安装应用程序后自动授予所有权限?

permissions android adb gradle android-studio

5
推荐指数
0
解决办法
192
查看次数

是否可以颠倒在垂直 LinearLayout 中布局的视图顺序?

默认情况下,垂直 LinearLayout 中的视图是从上到下测量和布局的,就像水平视图从左到右一样。

通常,如果我想要一个布局从下到上测量它的孩子,我通常使用RelativeLayout,每个孩子都有一个id,而底部视图的layout_alignParentBottom设置为true,其余的有“layout_above”设置为它们下面的视图:

<RelativeLayout>
 <View android:id="@+id/bottomView android:layout_alignParentBottom="true" />

 <View android:id="@+id/secondView android:layout_above="@+id/bottomView " />

 <View android:id="@+id/thirdView android:layout_above="@+id/secondView " />

 ...
</RelativeLayout
Run Code Online (Sandbox Code Playgroud)

但这设置起来很烦人,如果添加到另一个布局中可能会出现问题。

是否有可能在 LinearLayout 上有这种行为?我唯一发现的是LayoutDirection,但这似乎属于RTL方向(水平),所以它不起作用。

android android-layout android-linearlayout

5
推荐指数
1
解决办法
2566
查看次数

如何在目标不足的情况下在Android O上创建快捷方式?

背景

Android O对快捷方式的工作方式进行了各种更改:

https://developer.android.com/preview/behavior-changes.html#as

问题

根据Android O的最新变化,完全忽略了创建快捷方式的广播意图:

https://developer.android.com/reference/android/content/Intent.html#ACTION_CREATE_SHORTCUT https://developer.android.com/preview/behavior-changes.html#as

com.android.launcher.action.INSTALL_SHORTCUT广播对您的应用不再有任何影响,因为它现在是一个私有的隐式广播.相反,您应该使用ShortcutManager类中的requestPinShortcut()方法创建应用程序快捷方式.

这意味着,例如,无论您使用哪个应用或用户具有哪个启动器,此代码都将无法使用:

private void addShortcut(@NonNull final Context context) {
    Intent intent = new Intent().putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(context, MainActivity.class).setAction(Intent.ACTION_MAIN))
            .putExtra(Intent.EXTRA_SHORTCUT_NAME, "HelloWorldShortcut")
            .putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, ShortcutIconResource.fromContext(context, R.mipmap.ic_launcher))
            .setAction("com.android.launcher.action.INSTALL_SHORTCUT");
    context.sendBroadcast(intent);
}
Run Code Online (Sandbox Code Playgroud)

目前,即使Play商店本身也无法创建应用程序的快捷方式(至少在当前版本中:80795200).即使对谷歌的发射器,它也没有做任何事情.

这个问题

虽然我很反对API的这种变化(并且写了关于它在这里,在这里),并在这里,我想知道那会是什么采取仍然使它工作.

我知道有一个API,使用requestPinShortcut,但这需要应用程序以Android O为目标,这意味着必须进行更多更改以确保应用程序在那里工作.

我的问题是:假设您的应用针对Android API 25,如何在Android O上创建快捷方式?是否可以通过使用较新API的反映?如果是这样,怎么样?

android shortcut android-intent android-8.0-oreo

5
推荐指数
2
解决办法
3702
查看次数

如何查询属于某个帐户的所有联系人?

背景

地址簿上的联系人可以拥有附加到他们的帐户数据.每个应用都可以拥有一个帐户,然后为该联系人添加自己的信息.

诸如Telegram,WhatsApp,Viber等应用程序 - 都创建了一个向联系人添加信息和/或操作的帐户.

以下是一个包​​含WhatsApp和Viber帐号的联系人示例:

在此输入图像描述

问题

我正在试图弄清楚如何获取具有指定帐户的所有联系人.

由于WhatsApp是我所知道的最受欢迎的,我的测试专注于它.

我的问题是,有些用户声称我几乎没有回复联系人,有些人声称它甚至没有显示任何一个.它似乎通常工作,在我的情况下,它总是有效,但在代码上可能不是很好.

我试过的

我必须制作下一个代码,这对我来说似乎有用,可以获得所有WhatsApp联系人的电话到联系信息的地图.

我们的想法是获取WhatsApp联系人与所有基本联系人数据的所有可能信息,并合并那些匹配相同查找密钥的信息.

我试图使用更好的加入查询,但我失败了.也许它也有可能,并且可能更有效率.

这是代码:

/**
 * returns a map of lookup-key to contact-info, of all WhatsApp contacts
 */
@NonNull
public HashMap<String, ContactInfo> getAllWhatsAppPhones(Context context) {
    ContentResolver cr = context.getContentResolver();
    final HashMap<String, ContactInfo> phoneToContactInfoMap = new HashMap<>();
    final HashMap<String, String> whatsAppLookupKeyToPhoneMap = new HashMap<>();
    final String phoneMimeType = Phone.CONTENT_ITEM_TYPE;
    final Cursor whatsAppCursor;
    whatsAppCursor = cr.query(Data.CONTENT_URI,
            new String[]{Phone.NUMBER, Phone.LOOKUP_KEY},
            Phone.MIMETYPE + " = ?", new String[]{WhatsAppStuff.WHATS_APP_MIME_TYPE}, null);
    if (whatsAppCursor == null) …
Run Code Online (Sandbox Code Playgroud)

android android-contacts

5
推荐指数
1
解决办法
529
查看次数

如何将DiffUtil.Callback与具有页眉和页脚的RecyclerView一起使用?

背景

我正在开发一个带有RecyclerView的应用程序,您可以根据需要上下滚动。

数据项是从服务器加载的,因此,如果您要到达底部或顶部,则应用程序将获取新数据以显示在那里。

为了避免奇怪的滚动行为并停留在当前项目上,我使用了' DiffUtil.Callback ',覆盖了'getOldListSize','getNewListSize','areItemsTheSame','areContentsTheSame'。

我在这里问过这个问题,因为我从服务器获得的只是一个全新的项目列表,而不是与上一个列表的区别。

问题

RecyclerView没有仅要显示的数据。也有一些特殊的项目:

由于Internet连接速度可能很慢,因此RecyclerView中有一个标题项和一个脚注项,它们只有一个特殊的“进度”视图,以表明您已经到达边缘并且将很快加载。

页眉和页脚始终存在于列表中,并且不会从服务器收到它们。它纯粹是UI的一部分,只是为了显示即将加载的内容。

就像其他项一样,它需要由DiffUtil.Callback处理,因此对于areItemsTheSameareContentsTheSame,如果旧页眉是新页眉,而旧页脚是新页脚,则只返回true:

    override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        val oldItem = oldItems[oldItemPosition]
        val newItem = newItems[newItemPosition]
        when {
            oldItem.itemType != newItem.itemType -> return false
            oldItem.itemType == ItemType.TYPE_FOOTER || oldItem.itemType == AgendaItem.TYPE_HEADER -> return true
            ...
        }
    }

    override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        val oldItem = oldItems[oldItemPosition]
        val newItem = newItems[newItemPosition]
        return when {
            oldItem.itemType == ItemType.TYPE_FOOTER || …
Run Code Online (Sandbox Code Playgroud)

android android-recyclerview

5
推荐指数
1
解决办法
1118
查看次数

"SecurityException: Permission Denial" when opening a calendar Intent

Background

In order to go to the calendar at a specific time, we use this (based on this link) :

@Nullable
public static Intent prepareIntentForCalendar(final Context context, final Date date) {
    Intent intent = null;
    final Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon();
    builder.appendPath("time");
    ContentUris.appendId(builder, date.getTime());
    intent = new Intent(Intent.ACTION_VIEW).setData(builder.build());
    final PackageManager pm = context.getPackageManager();
    final ResolveInfo resolveActivity = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY
            | PackageManager.GET_RESOLVED_FILTER);
    if (resolveActivity == null)
        return null;
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY
            | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
    return intent;
}
Run Code Online (Sandbox Code Playgroud)

Only if it's …

android android-intent android-calendar android-securityexception

5
推荐指数
0
解决办法
389
查看次数

是否可以单独使用电子邮件获取个人公开个人资料照片,就像使用旧的G +/Picasa API一样?

背景

在过去和不久的将来,如果有人的电子邮件,可以获取个人资料照片,如下所示:

检索用户的公共google/gmail图片

它甚至可以没有任何登录到G +的网络,如图所示在这里.

问题

正如文档所说(这里),这个API将很快被弃用,因此不再可以使用它:

Picasa网络相册数据API将关闭,所有关联的OAuth范围都将被停用.阅读弃用通知.

关键日期:

  • 2019年1月除非您申请了分机,否则从此日期开始,所有对Picasa网络相册数据API的调用都将失败.
  • 2019年3月 Picasa网络相册API将被关闭.从此日期开始,对此API的所有调用都将失败,您无法请求任何进一步的扩展.

我发现了什么

查看新的API(迁移指南普通文档),我没有看到任何类似的方法来访问网站URL并获取配置文件的图像.他们所谈论的只是Google相册应用的照片API.

我所知道的是,有一个类似的东西的"人"API,但我记得它需要先登录.

这个问题

目前有哪些替代API?

有没有办法使用谷歌的API获取一个人的电子邮件地址的公开个人资料照片,即使没有登录?或者也许现在需要登录,无论如何?

android picasa google-plus

5
推荐指数
1
解决办法
297
查看次数

当我只能处理文件或文件路径时如何处理 SAF?

背景

在 Android Q 之前,如果我们想要获取有关 APK 文件的信息,我们可以使用WRITE_EXTERNAL_STORAGEREAD_EXTERNAL_STORAGE来访问存储,然后在文件路径上使用PackageManager.getPackageArchiveInfo函数。

类似的情况也存在,例如在压缩文件上使用ZipFile 类,可能还有无数的框架 API 和第三方库。

问题

谷歌最近宣布了对 Android Q 的大量限制。

其中之一称为“范围存储”,当访问设备拥有的所有文件时,它会破坏存储权限。它可以让您处理媒体文件,或者使用非常受限的存储访问框架 ( SAF ),该框架不允许应用程序使用文件 API 和文件路径访问和使用文件。

当Android Q Beta 2发布时,它破坏了很多应用程序,包括谷歌的应用程序。原因是它默认打开,影响所有应用程序,无论它们是否针对 Android Q。

原因是许多应用程序、SDK 和 Android 框架本身 - 都经常使用文件 API。在许多情况下,它们也不支持 InputStream 或 SAF 相关的解决方案。一个例子就是我写的 APK 解析示例 (PackageManager.getPackageArchiveInfo)。

然而,在 Q beta 3 上,情况发生了一些变化,因此目标 Q 的应用程序将具有范围存储,并且有一个标志可以禁用它,但仍然像往常一样使用正常的存储权限和文件 API。遗憾的是,该标志只是暂时的(请阅读此处),因此它推迟了不可避免的事情。

我尝试过的

我已经尝试并发现了接下来的事情:

  1. 使用存储权限确实不允许我读取任何非媒体文件的文件(我想找到 APK 文件)。就好像这些文件不存在一样。

  2. 使用 SAF,我可以找到 APK 文件,并通过一些解决方法来找到其真实路径(链接此处),我注意到文件 API 可以告诉我该文件确实存在,但无法获取其大小,并且框架无法使用其路径getPackageArchiveInfo在这里写过这个

  3. 我尝试创建到该文件的符号链接(链接此处 …

android file storage-access-framework android-10.0 scoped-storage

5
推荐指数
1
解决办法
1705
查看次数

如何获得Android Q上的应用程序的网络使用率?

背景

我知道我们可以通过使用类似的东西(在过去,在这里询问)来获取指定应用程序的网络使用情况(到目前为止,从某个特定时间到目前为止移动和Wifi的总带宽使用量):

    private final static int[] NETWORKS_TYPES = new int[]{ConnectivityManager.TYPE_WIFI, ConnectivityManager.TYPE_MOBILE};

    long rxBytes=0L, txBytes=0L;
    final TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    final String subscriberId = telephonyManager.getSubscriberId();
    final ApplicationInfo applicationInfo = context.getPackageManager().getApplicationInfo(packageName, 0);
    final int uid = applicationInfo.uid;
    for (int networkType : NETWORKS_TYPES) {
        final NetworkStats networkStats = networkStatsManager.queryDetailsForUid(networkType, subscriberId, 0, System.currentTimeMillis(), uid); 
        final Bucket bucketOut = new Bucket();
        while (true) {
                networkStats.getNextBucket(bucketOut);
                final long rxBytes = bucketOut.getRxBytes();
                if (rxBytes >= 0)
                    totalRx += rxBytes;
                final long txBytes = bucketOut.getTxBytes(); …
Run Code Online (Sandbox Code Playgroud)

networking android android-10.0

5
推荐指数
1
解决办法
461
查看次数

如何将 FAB 塑造为圆角按钮(药丸形状),类似于联系人应用程序的联系人详细信息屏幕?

背景

最初,FAB(浮动操作按钮)只有一个形状:圆形,并且它只能选择在其中包含一个图标。

问题

在过去一年左右的时间里,谷歌在其应用程序中添加了各种屏幕,显示改变其大小的 FAB。例如,如果你打开它的通讯录应用程序并选择一个联系人,那么你就是一个 FAB:

在此处输入图片说明

如果你滚动一点,它就会变成一个圆圈,里面只有一个图标:

在此处输入图片说明

我想知道如何制作这样的 FAB,并使用类似的,中间只有一个图标(没有文字),意思是圆角。

类似的东西:

在此处输入图片说明

我的尝试和发现

起初,我试图只是将 FAB 的宽度设置得更大,但这并没有帮助,因为它坚持是一个完美的圆形(适合正方形,并且没有边缘)。

看到可能 FAB 目前无法处理这个,我改用 MaterialCardView:

                <com.google.android.material.card.MaterialCardView
Run Code Online (Sandbox Code Playgroud)

android:layout_width="60dp" android:layout_height="32dp" android:clickable="true" android:focusable="true" app:cardBackgroundColor="..." app:cardCornerRadius="16dp">

                    <androidx.appcompat.widget.AppCompatImageView
                        android:layout_width="wrap_content" android:layout_height="wrap_content"
                        android:layout_gravity="center" app:srcCompat="..."/>
                </com.google.android.material.card.MaterialCardView>
Run Code Online (Sandbox Code Playgroud)

这有效,但点击效果消失了。

我也试过 MaterialButton,但这不支持中间的图标,只支持里面的各种文字。

后来,我注意到 FAB 实际上确实有一种方法可以自定义自身的形状:

https://developer.android.com/reference/com/google/android/material/floatingactionbutton/FloatingActionButton#setshapeappearance

https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android/material/floatingactionbutton/FloatingActionButton.java

另外,对于不断扩大的 FAB,我发现了这一点:

https://developer.android.com/reference/com/google/android/material/floatingactionbutton/ExtendedFloatingActionButton

https://material.io/develop/android/components/extended-floating-action-button/

所以查看它的代码,我发现它使用了一个药丸的形状,我试图做一个与普通 FAB 类似的事情:

class PillFab @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
    FloatingActionButton(context, attrs, defStyleAttr) {
    init {
        val shapeAppearanceModel =
            ShapeAppearanceModel(context, attrs, defStyleAttr, DEF_STYLE_RES, ShapeAppearanceModel.PILL)
        shapeAppearance = shapeAppearanceModel
    }

    companion object …
Run Code Online (Sandbox Code Playgroud)

android material-design floating-action-button material-components material-components-android

5
推荐指数
1
解决办法
1782
查看次数