android

适配Android 12的行为变更—–精确的闹钟权限

为了鼓励应用节省系统资源,以 Android 12 及更高版本为目标平台且设置了精确的闹钟的应用必须能够访问“闹钟和提醒”功能,该功能显示在系统设置的特殊应用访问权限屏幕中。如需获取这种特殊应用访问权限,需在清单中请求 SCHEDULE_EXACT_ALARM 权限。

开发者网站请参考:

行为变更:以 Android 12 为目标平台的应用 | Android Developers

   简单来说就是代码中如果使用了setAlarmClock()、setExact()、setExactAndAllowWhileIdle()这几种方法,则设置的是精准的闹钟。在Android12环境下,调用这些方法时,如果SCHEDULE_EXACT_ALARM权限未打开,应用就会crash(做之前先测试一下,要是权限关闭以后,调用这些方法,要是应用不会crash,应该不需要对应)。所以,在调用这些方法时,要增加权限检查。

应对方法:

(1).申请权限

(2).跳转到授权画面

Google Pixel的处理流程:在一打开应用的时候就进行权限检查,如果check到SCHEDULE_EXACT_ALARM权限没打开,就使用toast提示用户打开授权界面,若用户不打开设置的闹钟都不好用(我的建议是弹dialog,要是用户拒绝就直接退出应用,省得后面麻烦)

Uri uri = Uri.parse("package:"+this.getPackageName());
Intent i = new Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM,uri);
startActivity(i,200);

SCHEDULE_EXACT_ALARM权限 授权画面

(3).判断是否具有权限

alarmManager=(AlarmManager)getSystemService(Context.ALARM_SERVICE);
boolean  hasPermission = alarmManager.canScheduleExactAlarms();//true:有权限,false:没有权限
if(hasPermission){
    setAlarmClock();//设置精准闹钟的方法
    setExact();
    setExactAndAllowWhileIdle();
}else{
    //如果没检查到权限,应该做出相应的处理
    //(1).什么都不做,写一条log。如果权限关闭闹钟将无法使用
    //(2).设置不精准的闹钟
    //(3).使用dialog、toast等提示用户打开权限(具体项目,具体设计,不建议在每次设置精准闹钟时候都对用户进行提示,这样的用户体验感不好)
}

注意点:

1.如果用户在SCHEDULE_EXACT_ALARM权限打开的时候设置闹钟,在闹钟到点前将闹钟关闭,到时间闹钟是不会响的,如果用户发现闹钟到点没响,就将SCHEDULE_EXACT_ALARM权限打开,闹钟可以响(闹钟过时,闹钟会被miss掉)

对应方法:设定一个广播接收器(静态,动态都可以),接收”AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED”
这里要注意:只有在打开精准闹钟权限的时候才能收到广播;关闭时是收不到的,只能每次使用方法的时候checkPermission。
如果收不到广播的话,在终端运行以下命令,启用行为更:(模拟器也要运行)
adb shell am compat enable REQUIRE_EXACT_ALARM_PERMISSION [packageName]

正常来说,SCHEDULE_EXACT_ALARM权限是默认打开的,用户应该也不会找到这个将它关闭,更不太可能进行这么非人类的操作,但是我们作为开发者应该考虑滴全面些。我就打算等Android 12适配了,我就给各个手机厂商找茬去。Google Pixel已经被我找过一次茬了,我这里面说的情况,Google就还没做出处理(11月为止)。

2.App info和System Setting都有SCHEDULE_EXACT_ALARM 权限,它们俩的授权界面虽然长得一样,但是是不一样的界面。这将会导致一个问题,要是在App info中将权限关闭,在跳转授权界面的时候可能会跳转两个授权界面。
对应方法:在点击跳转按钮的时候再startActivity,这样就能把App info的授权界面(AlarmsAndRemindersAppActivity)给覆盖掉

public void createAlertDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(R.string.extra_alarm_permission_descript_title);
        builder.setPositiveButton(R.string.extra_alarm_permission_turn_on, new DialogInterface.OnClickListener() {
            Uri uri = Uri.parse("package:" + "com.android.deskclock");
            Intent intent = new Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM, uri);
            public void onClick(DialogInterface dialog, int which) {
                startActivity(intent);
            }
        });
        builder.setNegativeButton(R.string.extra_alarm_permission_ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });
        mExtraAlarmDialog = builder.create();
        mExtraAlarmDialog.setCancelable(false);
        mExtraAlarmDialog.show();
    }

Android Studio编译报错:“ java.lang.OutOfMemoryError: Java heap space”

前言:

最近换了工作,到了新东家,厂子大了,人也多了,希望在新的环境中不断成长。在上家公司电脑是最好的,新的公司就是一般配置,内存只有8G,因此Android Studio3.5编译报错:java.lang.OutOfMemoryError。

原因:

java.lang.OutOfMemoryError: GC overhead limit exceeded 则表示程序消耗了太多的可用内存,并且GC屡屡没能有效回收清理。一次GC后大部分的堆空间任然被占用,GC的频繁调用将使CPU的一直处于高负荷状态,由于GC过度频繁运行,客户程序也将无法正常往下运行导致程序崩溃。

解决方法:
1.在build.gradle中的android{}添加如下脚本:

defaultConfig {

    ...

    dexOptions { 
        javaMaxHeapSize “4g” 
    }

}

2.在gradle.properites文件中添加如下配置:

# 解决OutOfMemoryError
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.jvmargs=-Xmx5120m

Android Studio -Xlint:deprecation 乱码

总结:Android Studio 安装目录下bin文件夹下 studio64.exe.vmoptions文件末尾追加

 -Dfile.encoding=UTF-8

 然后重启即可,不放心的话可以在studio.exe.vmoptions也加上

后面不用看了参考:

QUERY_ALL_PACKAGES 权限的合规思考

App接入广告SDK播放视频广告,这类型广告一般会在视频中设置第三方引流App入口,通常会配置applist权限,对设备上所安装的软件包请求广泛的可见性权限,进而实现精准向用户引流未下载的软件包,或是用于数据统计、广告分析的目的。

应用通过从终端上全局查询的 已安装应用程序列表 ,如每款应用软件的名称、版本等, 为个人设备信息类别 属于用户的敏感个人信息

Android 11及更高版本(AndroidAPI 级别30及以上)的应用,引入了QUERY_ALL_PACKAGES 权限, 更改了应用查询用户已在设备上安装的其他应用以及与之交互的方式,不同于前述11版本以下的获取applist权限的方式,无法直接获取其他已安装应用程序列表,只能查询自己应用和系统应用的信息, 而非前述请求查看的 广 泛的 应用可见 性权限。

应用 使用QUERY_ALL_PACKAGES 权限时, 如果需要查询或与之交互的其他特定应用时,需要已集成该特定应用,或是使用某服务功能需与之特定应用交互的,才可以通过添加特定应用的软件包名至

<queries>元素内声明应用需提高软件包的可见性, 从而实现请求所必需的最小软件包的可见性权限,确保应用能够在最小权限范围内收集使用用户已安装应用程序列表的敏感信息,获取适当范围内的可见性权限(有限的可见性权限)。

但是,应用通过QUERY_ALL_PACKAGES 权限获取有限的可见性权限,仍然是有门槛的,且需进行隐私权限的合规审查。

Google Play 对于目标运行环境为 Android 11(API 级别 30)且请求获取 QUERY_ALL_PACKAGES 权限 的应用 ,新政策于 2022 年 7 月 1 日开始执行

如果Play 内的应用对QUERY_ALL_PACKAGES 权限的使用,在Google Play 政策允许范畴内, 应用需在清单中明确声明此权限且声明使用范围更具体的软件包可见性权限。 否则,应用通过QUERY_ALL_PACKAGES 权限收集已安装应用程序列表,并非是应用所涉的核心功能的以及与该权限启用发现的特定应用进行的互操作,即使应用进行了权限声明,也不符合Google Play 政策要求,应用将面临被Google Play下架。

Google Play 允许QUERY_ALL_PACKAGES 权限的使用情形涉及满足以下条件的应用:为了解相关情况或进行互操作(可能符合该权限的使用条件),必须发现设备上任何及所有已安装的应用。允许的使用情形包括:设备搜索、杀毒应用、文件管理器和浏览器。

如果 应用的某个可验证的核心用途涉及金融交易功能 (例如专用银行服务、专用数字钱包), Google Play 会允许该应用仅出于安全方面的目的而广泛地查询已安装的应用。

但是,在下述场景中 不允许使用 QUERY_ALL_PACKAGES  权限

  • 对该权限的使用与实现应用的核心用途并没有直接关系。
    • 此类使用情形包括点对点 (P2P) 分享。点对点分享只有在作为应用的核心用途的情况下,才属于允许的使用情形。
  • 获取数据是为了将其出售。
  • 无需非常广泛地查询应用安装情况就能完成目标任务。

此外,Google Play特别强调通过 Play分发的应用所查询的已安装应用程序列表数据不得出售,也不得分享给其他方来用于分析或广告获利目的。

Google Play限制应用的QUERY_ALL_PACKAGES 权限,尽可能地让应用遵循最小必要原则调用权限,获取用户个人信息,同时还可以帮助Play评估应用的隐私性和安全性,应用仅能在其显著声明的目的和范围内,以及征得用户同意的目的和范围内使用QUERY_ALL_PACKAGES 权限,对于没有核心功能或用途而查询其他应用安装情况的应用, Google Play 予以清退下架。

同理,依据《个人信息保护法》,除法定无需同意的情形除外,收集使用用户个人信息,应征得个人信息主体的同意,敏感信息应取得单独同意。

对于 Android 11(API 级别 30)运行环境,App或SDK配置了QUERY_ALL_PACKAGES 权限,查询已安装应用程序列表的敏感信息时,首先需考虑其配置此权限的正当、合理与必要性。

此权限是否涉及核心功能或者应用必须与之特定应用进行的互操作的合理必要场景,采取对个人权益影响最小权限的查看应用列表方式。其次,App或SDK在隐私政策中应明确告知QUERY_ALL_PACKAGES权限的方式、目的和范围,声明获取的特定已安装应用程序列表清单,且在特定场景时触发权限(如与特定应用进行互操作时),以弹窗或其他显著方式告知并征得用户的同意。

当然,配置了QUERY_ALL_PACKAGES 权限的应用,目前不参考上述声明与同意方式,也不太会导致App在应用市场上被下架或被通报整改。 对于 Android 11以下环境的App或SDK收集使用已安装应用程序列表的信息,目前主要通过隐私政策告知用户收集使用的目的、方式、范围和场景。但将来可能会渐趋于上述11以上的合规标准。

running gradle task assembledebug stuck

Here is solution in my case.

  1. Open your flutter Project directory.
  2. Change directory to android directory in your flutter project directory cd android
  3. clean gradle ./gradlew clean
  4. Build gradle ./gradlew build or you can combine both commands with just ./gradlew clean build (Thanks @daniel for the tip)
  5. Now run your flutter project. If you use vscode, press F5. First time gradle running assembleDebug will take time.

PS: Delete gradle in case of all that steps don’t work

PANIC: Missing emulator engine program for ‘x86’ CPU.

emulator -avd xx

一直报错:

PANIC: Missing emulator engine program for ‘x86’ CPU.

最终找到原因:

在创建虚拟机的时候,AS会默认推荐下载带Google APIs的x86 Images,由于大陆对google的限制,所以会导致报错。

解决办法,下载不带Google APIs的x86 Images, 然后再重启终端,重新输入命令,成功启动安卓虚拟机。

 

远程连接centos打开Androidstudio空白

For me, this issue was an XRDP issue, fixed in CentOS 7.6 by editing /etc/xrdp/xrdp.ini and changing to max_bpp=24.

 

参考连接:

https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000675024-Blank-configuration-window-