Android 开发中遇到的 bug(5)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/willway_wang/article/details/88674375

前言

记录开发中遇到的 bug,不再让自己重复地被同样的 bug 折磨。

正文

1. Android 8.0后notification通知声音无法关闭或开启的问题

时间:2019年3月19日11:38:39
解决办法:参考了 https://blog.csdn.net/fzkf9225/article/details/81119780。需要特别注意的是,要记得更新 channelId,新的设置才会生效。

2. Android 8.0获取wifi ssid 为 unknow ssid 的问题

时间:2019年3月19日14:40:10
解决办法:

// 在 8.0 以上使用,避免获取到的名字为 <unknown ssid>
ConnectivityManager cm = (ConnectivityManager) Utils.getApp().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
String ssid= networkInfo.getExtraInfo();

还有一种办法,增加定位权限:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

这个还需要动态申请,还需要在 app 里特别说明,有点麻烦。

3. fatal: Not a valid object name: ‘master’.

时间:2019年3月21日10:53:14
问题描述:在一个名字为 gitskill 的目录,使用 git init 初始化这个目录;然后使用 git branch dev 创建 dev 分支,出现这个错误。命令使用如下:

wangzhichao@wangzhichao-PC MINGW64 ~/Desktop/gitskill
$ git init
Initialized empty Git repository in C:/Users/wangzhichao/Desktop/gitskill/.git/
wangzhichao@wangzhichao-PC MINGW64 ~/Desktop/gitskill (master)
$ git branch dev
fatal: Not a valid object name: 'master'.

问题分析:使用 git branch 命令查看一下分支状况,如下:

wangzhichao@wangzhichao-PC MINGW64 ~/Desktop/gitskill (master)
$ git branch

wangzhichao@wangzhichao-PC MINGW64 ~/Desktop/gitskill (master)
$

是的,没有看错,没有分支存在。连 master 分支都不存在。实际上,git init 并不会创建 master 分支,直到完成了第一次 commit。查看下面的命令:

wangzhichao@wangzhichao-PC MINGW64 ~/Desktop/gitskill (master)
$ git st
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        HelloWorld.java

nothing added to commit but untracked files present (use "git add" to track)

wangzhichao@wangzhichao-PC MINGW64 ~/Desktop/gitskill (master)
$ git add .

wangzhichao@wangzhichao-PC MINGW64 ~/Desktop/gitskill (master)
$ git branch

wangzhichao@wangzhichao-PC MINGW64 ~/Desktop/gitskill (master)
$ git commit -m "commit HelloWorld.java"
[master (root-commit) 7fcf75a] commit HelloWorld.java
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 HelloWorld.java

wangzhichao@wangzhichao-PC MINGW64 ~/Desktop/gitskill (master)
$ git branch
* master

wangzhichao@wangzhichao-PC MINGW64 ~/Desktop/gitskill (master)
$

解释一下,在 add 了 HelloWorld.java 后,依然没有 master 分支;只有在 commit 了 HelloWorld.java 后,才有了 master 分支。

4. /system/bin/sh: grep: can’t execute: Permission denied

时间:2019年3月21日13:06:59
问题描述:

C:\Users\wangzhichao>adb shell "top|grep com.bat.clean"
/system/bin/sh: grep: can't execute: Permission denied

解决办法:
换取一个 root 的手机测试,没有问题了。所以,现在认为是因为手机没有 root。

5. java.lang.IllegalArgumentException: Failed to find configured root that contains xxx

时间:2019年3月22日22:11:46
错误日志:

java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/9016-4EF8/Videos/20160129_200650.mp4
    at android.support.v4.content.FileProvider$SimplePathStrategy.null a(null)(FileProvider.java:183)
    at android.support.v4.content.FileProvider.null a(null)(FileProvider.java:4)
    at com.sdk.clean.video.VideoUtils.null a(null)(VideoUtils.java:53)
    at com.bat.clean.adapter.VideoResultAdapter$MediaViewHolder.null a(null)(VideoResultAdapter.java:10)
    at com.bat.clean.adapter.VideoResultAdapter$MediaViewHolder.null lambda$W8mSMnpQe-6pAYCNycyrYkg_zAw(null)(VideoResultAdapter.java:0)
    at com.bat.clean.a.-$$Lambda$k$b$W8mSMnpQe-6pAYCNycyrYkg_zAw.null onClick(null)(-.java:4)
    at android.view.View.null performClick(null)(View.java:6993)
    at android.view.View$PerformClick.null run(null)(View.java:26512)
    at android.os.Handler.null handleCallback(null)(Handler.java:790)
    at android.os.Handler.null dispatchMessage(null)(Handler.java:99)
    at android.os.Looper.null loop(null)(Looper.java:164)
    at android.app.ActivityThread.null main(null)(ActivityThread.java:7000)
    at java.lang.reflect.Method.null invoke(null)(Method.java)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.null run(null)(RuntimeInit.java:441)
    at com.android.internal.os.ZygoteInit.null main(null)(ZygoteInit.java:1408)

机型是8.1.0
问题分析:是在将外置 sd 卡上的视频资源,发送给视频播放器打开时,或则是图片资源,发送给图片打开器(图库)时出现的错误。其实内置 sd 卡上,是没有问题的。代码中已经通过 FileProvider 的形式来处理了,并且在 xml 文件夹下增加了 file_path.xml,如下:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path path="Android/data/com.bat.clean/" name="files_root" />
    <external-path path="." name="external_storage_root" />
</paths>

解决办法:查询 https://blog.csdn.net/fengyuzhengfan/article/details/52876586#commentsedit--,在 file_path.xml 中增加一个节点:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path path="Android/data/com.bat.clean/" name="files_root" />
    <external-path path="." name="external_storage_root" />
    <!--https://blog.csdn.net/fengyuzhengfan/article/details/52876586#commentsedit-->
    <root-path path="" name="video_photo_root" />
</paths>

文章作者能深入源码找出解决办法,很赞。

6. Java error: Comparison method violates its general contract

时间:2019年3月23日10:59:11
问题描述:

    private List<AppBean> mAppInfoList = new ArrayList<>();

    public void setPosition(int position, List<AppBean> appInfoList) {
        mPosition = position;
        mAppInfoList.clear();
        mAppInfoList.addAll(appInfoList);
        sortList(mAppInfoList, mPosition);
    }
    
    private void sortList(List<AppBean> appInfoList, final int position) {
        Collections.sort(appInfoList, (p1, p2) -> {
            if (position == POSITION_DATE) { // 按日期排序
                if (p1.getLastUpdateTime() > p2.getLastUpdateTime()) {
                    return 1;
                }
                if (p1.getLastUpdateTime() == p2.getLastUpdateTime()) {
                    return 0;
                }
                return -1;
            } else if (position == POSITION_SIZE) { // 按大小排序
                if (p1.getPkgSize() > p2.getPkgSize()) {
                    return 1;
                }
                if (p1.getPkgSize() == p2.getPkgSize()) {
                    return 0;
                }
                return -1;
            } else if (position == POSITION_NAME) { // 按名字首字母排序
                final String lhs = StringUtils.getFirstCharacter(p1.getAppName());
                final String rhs = StringUtils.getFirstCharacter(p2.getAppName());
                return lhs.compareTo(rhs);
            }
            return 0;
        });
    }

使用场景是在一个 Activity 里,获取到应用列表,在 Fragment 里按照日期、大小、名字首字母进行排序。
在排序集合时出现的问题,暂时没有解决办法,也没有复现。查询了 https://stackoverflow.com/questions/19325256/java-lang-illegalargumentexception-comparison-method-violates-its-general-contr,也没有复现问题。

7. Duplicate class found in the file ‘E:\AndroidWorkspaces\BatCleaner\app\src\main\res\layout\main_activity.xml’

时间:2019年3月25日10:31:40
问题描述:
使用 Room 数据库时出现的错误,在 Dao 接口中添加一条删除语句,如下所示:

@Dao
public interface NotificationItemDao {
    @Delete
    Long delete(NotificationItem item);

}

重新运行就出现了上面的错误。实际上,Databinding 编译的类都出错了,Glide 也出错了。

错误: 找不到符号
符号:   类 GlideApp
位置: 程序包 com.bat.clean
错误: 找不到符号
符号:   类 DataBindingComponent
位置: 程序包 android.databinding

所以,问题定位在添加的删除语句上。不使用这条删除语句,编译正常。添加这条删除语句,编译出错。问题就是出在这条删除语句上。对比之前自己的代码,把语句改成如下:

@Delete
int delete(NotificationItem item);

即把返回值由 Long 改为 int
重新编译,解决了这个问题。

8. 继承 NotificationListenerService,监听无效

时间:2019年3月26日09:37:16
问题描述:
继承 NotificationListenerService 的类如下:

public class NotificationObserverService extends NotificationListenerService {
    private static final String TAG = NotificationObserverService.class.getSimpleName();
    private static List<NotificationItem> sNotificationItemList = new ArrayList<>();

    @Override
    public void onCreate() {
        super.onCreate();
        LogUtils.dTag(TAG, "onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        LogUtils.dTag(TAG, "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        super.onNotificationPosted(sbn);
        LogUtils.dTag(TAG, "onNotificationPosted: currThread=" + Thread.currentThread().getName());
    }

    // API 18
    @Override
    public void onNotificationRemoved(StatusBarNotification sbn) {
        super.onNotificationRemoved(sbn);
        LogUtils.dTag(TAG, "18 onNotificationRemoved: currThread=" + Thread.currentThread().getName());
    }

    // API 21
    @Override
    public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
        super.onNotificationRemoved(sbn, rankingMap);
        LogUtils.dTag(TAG, "21 onNotificationRemoved: currThread=" + Thread.currentThread().getName());
    }

    // API 26
    @Override
    public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap, int reason) {
        super.onNotificationRemoved(sbn, rankingMap, reason);
        LogUtils.dTag(TAG, "26 onNotificationRemoved: currThread=" + Thread.currentThread().getName());
    }

    @Override
    public void onListenerConnected() {
        super.onListenerConnected();
        LogUtils.dTag(TAG, "onListenerConnected");
        sListenerConnected = true;
    }

    private static boolean sListenerConnected = false;

    @Override
    public void onListenerDisconnected() {
        super.onListenerDisconnected();
        LogUtils.dTag(TAG, "onListenerDisconnected");
        sListenerConnected = false;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
     
    }

    /**
     * 监听服务被杀掉后重启的方法
     */
    public static void start(Context context) {
        if (sListenerConnected) {
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            requestRebind(new ComponentName(context, NotificationObserverService.class));
        } else {
            PackageManager pm = context.getPackageManager();
            pm.setComponentEnabledSetting(new ComponentName(context, NotificationObserverService.class),
                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
            pm.setComponentEnabledSetting(new ComponentName(context, NotificationObserverService.class),
                    PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
        }
    }

}

在清单中注册:


 		<service
            android:name=".service.NotificationObserverService"
            android:label="@string/app_notification_name"
            android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
            <intent-filter>
                <action android:name="android.service.notification.NotificationListenerService" />
            </intent-filter>
        </service>

在荣耀6(6.0)手机上却不能监听到回调,但是在荣耀Play(9.0)以及一个4.4.4 的小手机上都是正常的。
解决办法:尝试修改了 NotificationObserverService 的名字。改为 NotificationCleanerObserverService 或者 NotificationObserverService11,总之不要是 NotificationObserverService。再次运行在荣耀6上,可以正常监听了。现在自己推测是 NotificationObserverService 这个名字和荣耀6系统里的冲突了。只是推测,但也没必要去验证了。

9. Could not download fastutil.jar (it.unimi.dsi:fastutil:7.2.0)

时间:2019年4月2日22:09:40
问题描述:下载如上的 jar 一直下载不下来。
解决方法:
这种一般是网速的问题,可以用下面的方法解决。

buildscript {
    repositories {
        maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}
        google()
        jcenter()

    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.2'
        
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

 maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'} 

这句添加进去。需要特别注意的是,要在 google() 之前。不然,不会生效的。其实,可以把

google()
jcenter()

替换为

maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }

10. error: ‘home_content_action_view_accelerate’ is incompatible with attribute layout_constraintEnd_toEndOf (attr) reference|enum [parent=0].error: failed linking file resources.

时间:2019年4月5日14:37:10
问题描述:在使用 ConstraintLayout 的属性时报错,代码如下:

		<com.iekie.free.clean.ui.view.HomeContentActionView
           android:id="@+id/home_content_action_view_power"
           android:layout_width="0dp"
           android:layout_marginTop="8dp"
           android:layout_marginBottom="16dp"
           android:layout_height="wrap_content"
           android:src="@drawable/home_content_power"
           android:text="@string/battery_title"
           app:layout_constraintBottom_toBottomOf="parent"
           app:layout_constraintEnd_toEndOf="home_content_action_view_accelerate"
           app:layout_constraintStart_toStartOf="@id/home_content_action_view_accelerate"
           app:layout_constraintTop_toBottomOf="@id/home_content_action_view_accelerate"/>

上面就是错误指向的地方。错误日志说:home_content_action_view_accelerate 和 layout_constraintEnd_toEndOf 这个属性不兼容,或者说存在矛盾。那么去看一下这一行:

app:layout_constraintEnd_toEndOf="home_content_action_view_accelerate"

原来是少了 @id/,正确的应该是:

app:layout_constraintEnd_toEndOf="@id/home_content_action_view_accelerate"

最后

代码出错了,关键是要仔细查看日志。能够仔细地查看日志,就离解决问题很近了。

猜你喜欢

转载自blog.csdn.net/willway_wang/article/details/88674375