Skip to content

Commit

Permalink
新增 Android 8.0 通知渠道开关适配
Browse files Browse the repository at this point in the history
优化 Android 14 前台 Service 类型适配
优化 Logcat 在有悬浮窗权限的情况下的显示逻辑
  • Loading branch information
getActivity committed Jan 27, 2024
1 parent dd34a59 commit ffbbbf8
Show file tree
Hide file tree
Showing 14 changed files with 177 additions and 48 deletions.
49 changes: 49 additions & 0 deletions HelpDoc.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

* [我如果要在线上使用这个库该怎么办](#我如果要在线上使用这个库该怎么办)

* [在多进程情况下无法展示入口怎么办](#在多进程情况下无法展示入口怎么办)

#### Logcat 入口配置

* 框架默认提供了两种入口
Expand Down Expand Up @@ -276,4 +278,51 @@ try {
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
```

#### 在多进程情况下无法展示入口怎么办

* 这个问题其实之前就有人提出过 [Logcat/issues/35](https://github.com/getActivity/Logcat/issues/35),但是经过核实是无法修复的,这是因为在开启子进程的情况下,会二次创建 Application 对象,然后重新走一遍 onCreate 方法,但是 ContentProvider 组件就不一样了,并不会重复创建,这就导致一个问题,Logcat 这个框架本身就依赖 ContentProvider 作为框架的初始化入口,但是它在子进程并不会被系统二次创建,更别说调用了,这个属于硬伤。

* 当然不代表这就没有解决手段,你可以手动初始化 Logcat 框架来解决这一问题,具体方式如下:

* 第一步:先在清单文件中去除 Logcat 框架初始化入口

```xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.xxx.xxx">

<application>

<provider
android:name="com.hjq.logcat.LogcatProvider"
tools:node="remove" />

</application>

</manifest>
```

* 第二步:在 Application.onCreate 方法中手动初始化 Logcat 框架

```java
public final class XxxApplication extends Application {

@Override
public void onCreate() {
super.onCreate();

try {
Class<?> logcatProviderClass = Class.forName("com.hjq.logcat.LogcatProvider");
Object logcatProvider = logcatProviderClass.newInstance();
Method attachInfoMethod = logcatProviderClass.getMethod("attachInfo", Context.class, ProviderInfo.class);
attachInfoMethod.setAccessible(true);
attachInfoMethod.invoke(logcatProvider, this, null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
28 changes: 2 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

* 项目地址:[Github](https://github.com/getActivity/Logcat)

* 可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,[点击此处可直接下载](https://github.com/getActivity/Logcat/releases/download/11.82/Logcat.apk)
* 可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,[点击此处可直接下载](https://github.com/getActivity/Logcat/releases/download/11.85/Logcat.apk)

![](picture/demo_code.png)

Expand Down Expand Up @@ -51,7 +51,7 @@ dependencyResolutionManagement {
```groovy
dependencies {
// 日志调试框架:https://github.com/getActivity/Logcat
debugImplementation 'com.github.getActivity:Logcat:11.82'
debugImplementation 'com.github.getActivity:Logcat:11.85'
}
```

Expand All @@ -66,18 +66,6 @@ android.enableJetifier = true

* 如果项目是基于 **Support** 包则不需要加入此配置

#### compileSdk 版本要求

* 如果项目的 `compileSdkVersion` 小于 29,则需要先升级成 29

```groovy
android {
compileSdkVersion 29
}
```

* 如果项目的 `compileSdkVersion` 大于等于 29,则不需要修改此配置

#### 使用方式

* 无需调用,直接运行,然后授予悬浮窗权限即可
Expand Down Expand Up @@ -158,18 +146,6 @@ android {

![](https://raw.githubusercontent.com/getActivity/Donate/master/picture/pay_ali.png) ![](https://raw.githubusercontent.com/getActivity/Donate/master/picture/pay_wechat.png)

#### 广告区

* 我现在任腾讯云服务器推广大使,大家如果有购买服务器的需求,可以通过下面的链接购买

[![](https://upload-dianshi-1255598498.file.myqcloud.com/upload/nodir/345X200-9ae456f58874df499adf7c331c02cb0fed12b81d.jpg)](https://curl.qcloud.com/A6cYskvv)

[【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中](https://curl.qcloud.com/A6cYskvv)

[![](https://upload-dianshi-1255598498.file.myqcloud.com/345-200-b28f7dee9552f4241ea6a543f15a9798049701d4.jpg)](https://curl.qcloud.com/up4fQsdn)

[【腾讯云】中小企业福利专场,多款刚需产品,满足企业通用场景需求](https://curl.qcloud.com/up4fQsdn)

## License

```text
Expand Down
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.hjq.logcat.demo">

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

Expand Down
4 changes: 2 additions & 2 deletions common.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ android {
minSdk 16
// Android 版本适配指南:https://github.com/getActivity/AndroidVersionAdapter
targetSdk 34
versionCode 1182
versionName "11.82"
versionCode 1185
versionName "11.85"
}

// 支持 Java JDK 8
Expand Down
8 changes: 1 addition & 7 deletions library/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,7 @@
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
android:windowSoftInputMode="stateHidden" />

<!-- 适配 targetSdk 34:https://developer.android.google.cn/about/versions/14/changes/fgs-types-required?hl=zh-cn -->
<!-- java.lang.RuntimeException:
Unable to start service com.hjq.logcat.LogcatService with Intent:
android.app.MissingForegroundServiceTypeException:
Starting FGS without a type callerApp=ProcessRecord targetSDK=34 -->
<!-- 加上 foregroundServiceType 属性后,compileSdkVersion 需要 29 及以上的版本才能编译通过 -->
<service android:name=".LogcatService" android:foregroundServiceType="dataSync" />
<service android:name=".LogcatService" />

</application>

Expand Down
4 changes: 2 additions & 2 deletions library/src/main/java/com/hjq/logcat/LogcatActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ public final class LogcatActivity extends AppCompatActivity
CompoundButton.OnCheckedChangeListener, LogcatManager.Callback,
LogcatAdapter.OnItemLongClickListener, LogcatAdapter.OnItemClickListener {

private final static String[] ARRAY_LOG_LEVEL = {"Verbose", "Debug", "Info", "Warn", "Error"};
private final static String[] ARRAY_LOG_LEVEL_PORTRAIT = {"V", "D", "I", "W", "E"};
private static final String[] ARRAY_LOG_LEVEL = {"Verbose", "Debug", "Info", "Warn", "Error"};
private static final String[] ARRAY_LOG_LEVEL_PORTRAIT = {"V", "D", "I", "W", "E"};

private View mRootView;
private View mBarView;
Expand Down
59 changes: 59 additions & 0 deletions library/src/main/java/com/hjq/logcat/LogcatGlobalDispatcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.hjq.logcat;

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.view.View;

/**
* author : Android 轮子哥
* github : https://github.com/getActivity/Logcat
* time : 2020/01/24
* desc : Logcat 悬浮窗全局显示派发
*/
final class LogcatGlobalDispatcher implements Application.ActivityLifecycleCallbacks {

static void launch(Application application) {
LogcatWindow logcatWindow = new LogcatWindow(application);
logcatWindow.show();

application.registerActivityLifecycleCallbacks(new LogcatGlobalDispatcher(logcatWindow));
}

private final LogcatWindow mLogcatWindow;

private LogcatGlobalDispatcher(LogcatWindow logcatWindow) {
mLogcatWindow = logcatWindow;
}

@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}

@Override
public void onActivityStarted(Activity activity) {}

@Override
public void onActivityResumed(Activity activity) {
if (!(activity instanceof LogcatActivity)) {
return;
}
mLogcatWindow.setWindowVisibility(View.GONE);
}

@Override
public void onActivityPaused(Activity activity) {}

@Override
public void onActivityStopped(Activity activity) {
if (!(activity instanceof LogcatActivity)) {
return;
}
mLogcatWindow.setWindowVisibility(View.VISIBLE);
}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}

@Override
public void onActivityDestroyed(Activity activity) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
* author : Android 轮子哥
* github : https://github.com/getActivity/Logcat
* time : 2020/01/24
* desc : Logcat 悬浮窗显示派发
* desc : Logcat 悬浮窗局部显示派发
*/
final class LogcatDispatcher implements Application.ActivityLifecycleCallbacks {
final class LogcatLocalDispatcher implements Application.ActivityLifecycleCallbacks {

static void with(Application application) {
application.registerActivityLifecycleCallbacks(new LogcatDispatcher());
static void launch(Application application) {
application.registerActivityLifecycleCallbacks(new LogcatLocalDispatcher());
}

@Override
Expand Down
32 changes: 30 additions & 2 deletions library/src/main/java/com/hjq/logcat/LogcatProvider.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package com.hjq.logcat;

import android.app.Application;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.provider.Settings;
import android.support.v4.app.NotificationManagerCompat;
import android.widget.Toast;

Expand All @@ -29,7 +35,7 @@ public boolean onCreate() {
Boolean windowEntrance = LogcatUtils.getMetaBooleanData(
context, LogcatContract.META_DATA_LOGCAT_WINDOW_ENTRANCE);
if (notifyEntrance == null && windowEntrance == null) {
if (NotificationManagerCompat.from(context).areNotificationsEnabled()) {
if (isNotificationChannelEnabled(context)) {
notifyEntrance = true;
} else {
windowEntrance = true;
Expand All @@ -44,7 +50,11 @@ public boolean onCreate() {

if (windowEntrance != null && windowEntrance) {
if (context instanceof Application) {
LogcatDispatcher.with((Application) context);
if (VERSION.SDK_INT >= VERSION_CODES.M && Settings.canDrawOverlays(context)) {
LogcatGlobalDispatcher.launch((Application) context);
} else {
LogcatLocalDispatcher.launch((Application) context);
}
} else {
Toast.makeText(context, R.string.logcat_launch_error, Toast.LENGTH_LONG).show();
}
Expand Down Expand Up @@ -77,4 +87,22 @@ public int delete(Uri uri, String selection, String[] selectionArgs) {
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return 0;
}

private boolean isNotificationChannelEnabled(Context context) {
if (!NotificationManagerCompat.from(context).areNotificationsEnabled()) {
return false;
}

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
return true;
}

NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = manager.getNotificationChannel(LogcatService.NOTIFICATION_CHANNEL_ID);
if (channel == null) {
return true;
}

return channel.getImportance() != NotificationManager.IMPORTANCE_NONE;
}
}
4 changes: 3 additions & 1 deletion library/src/main/java/com/hjq/logcat/LogcatService.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
*/
public final class LogcatService extends Service {

public static final String NOTIFICATION_CHANNEL_ID = "logcat";

private static final int BACKUP_SERVICE_NOTIFICATION_ID = Integer.MAX_VALUE >> 2;

@Override
Expand Down Expand Up @@ -65,7 +67,7 @@ public int onStartCommand(Intent intent, int flags, int startId) {
// 设置通知渠道
if (VERSION.SDK_INT >= VERSION_CODES.O) {
// 通知渠道的id
String notificationChannelId = "logcat";
String notificationChannelId = NOTIFICATION_CHANNEL_ID;
NotificationChannel channel = new NotificationChannel(notificationChannelId,
getString(R.string.logcat_notify_channel_name), NotificationManager.IMPORTANCE_MIN);
// 配置通知渠道的属性
Expand Down
25 changes: 21 additions & 4 deletions library/src/main/java/com/hjq/logcat/LogcatWindow.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.hjq.logcat;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.util.TypedValue;
import android.view.Gravity;
Expand All @@ -17,15 +19,23 @@
*/
final class LogcatWindow extends EasyWindow<LogcatWindow> implements EasyWindow.OnClickListener<View> {

LogcatWindow(Activity activity) {
public LogcatWindow(Application application) {
super(application);
init(application);
}

public LogcatWindow(Activity activity) {
super(activity);
init(activity);
}

ImageView imageView = new ImageView(activity.getApplicationContext());
private void init(Context context) {
ImageView imageView = new ImageView(context.getApplicationContext());
imageView.setId(android.R.id.icon);
imageView.setImageResource(R.drawable.logcat_selector_floating);
setContentView(imageView);

int size = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 45, activity.getResources().getDisplayMetrics());
int size = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 45, context.getResources().getDisplayMetrics());
setWidth(size);
setHeight(size);

Expand All @@ -37,6 +47,13 @@ final class LogcatWindow extends EasyWindow<LogcatWindow> implements EasyWindow.

@Override
public void onClick(EasyWindow window, View view) {
startActivity(new Intent(getContext(), LogcatActivity.class));
Context context = getContext();
Intent intent = new Intent(context, LogcatActivity.class);
if (!(context instanceof Activity)) {
// 如果当前的上下文不是 Activity,调用 startActivity 必须加入新任务栈的标记,否则会报错:android.util.AndroidRuntimeException
// Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
startActivity(intent);
}
}
1 change: 1 addition & 0 deletions library/src/main/res/values-en/strings.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>

<string name="logcat_launch_error">Error parameter. Unable to start Logcat</string>
Expand Down
1 change: 1 addition & 0 deletions library/src/main/res/values-zh-rTW/strings.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>

<string name="logcat_launch_error">參數錯誤,無法啓動 Logcat</string>
Expand Down
1 change: 1 addition & 0 deletions library/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>

<string name="logcat_launch_error">参数错误,无法启动 Logcat</string>
Expand Down

0 comments on commit ffbbbf8

Please sign in to comment.