Compare commits
5 Commits
powerbell-
...
powerbell-
| Author | SHA1 | Date | |
|---|---|---|---|
| e51d46186a | |||
| 8fc6855066 | |||
| 4ceaf1e46a | |||
| e669bbb04b | |||
| 6bf3ebe2fd |
@@ -29,11 +29,11 @@ android {
|
||||
applicationId "cc.winboll.studio.powerbell"
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 30
|
||||
versionCode 6
|
||||
versionCode 7
|
||||
// versionName 更新后需要手动设置
|
||||
// .winboll/winbollBuildProps.properties 文件的 stageCount=0
|
||||
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
|
||||
versionName "15.12"
|
||||
versionName "15.14"
|
||||
if(true) {
|
||||
versionName = genVersionName("${versionName}")
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#Created by .winboll/winboll_app_build.gradle
|
||||
#Thu Dec 11 20:54:28 HKT 2025
|
||||
stageCount=16
|
||||
#Sat Dec 13 13:05:44 GMT 2025
|
||||
stageCount=0
|
||||
libraryProject=
|
||||
baseVersion=15.12
|
||||
publishVersion=15.12.15
|
||||
buildCount=0
|
||||
baseBetaVersion=15.12.16
|
||||
baseVersion=15.14
|
||||
publishVersion=15.14.0
|
||||
buildCount=1
|
||||
baseBetaVersion=15.14.1
|
||||
|
||||
@@ -4,12 +4,6 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="cc.winboll.studio.powerbell">
|
||||
|
||||
<!-- 只能在前台获取精确的位置信息 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
|
||||
<!-- 只有在前台运行时才能获取大致位置信息 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
|
||||
<!-- 拍摄照片和视频 -->
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
|
||||
@@ -143,14 +137,14 @@
|
||||
</activity-alias>
|
||||
|
||||
<activity
|
||||
android:name="cc.winboll.studio.powerbell.activities.ClearRecordActivity"
|
||||
android:name=".activities.ClearRecordActivity"
|
||||
android:parentActivityName="cc.winboll.studio.powerbell.MainActivity"
|
||||
android:launchMode="singleTask">
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="cc.winboll.studio.powerbell.activities.BackgroundSettingsActivity"
|
||||
android:name=".activities.BackgroundSettingsActivity"
|
||||
android:parentActivityName="cc.winboll.studio.powerbell.MainActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask">
|
||||
@@ -190,14 +184,14 @@
|
||||
</receiver>
|
||||
|
||||
<service
|
||||
android:name="cc.winboll.studio.powerbell.services.ControlCenterService"
|
||||
android:name=".services.ControlCenterService"
|
||||
android:priority="1000"
|
||||
android:enabled="true"
|
||||
android:exported="false"
|
||||
android:process=".controlcenterservice"/>
|
||||
|
||||
<service
|
||||
android:name="cc.winboll.studio.powerbell.services.AssistantService"
|
||||
android:name=".services.AssistantService"
|
||||
android:enabled="true"
|
||||
android:exported="false"
|
||||
android:process=".assistantservice"/>
|
||||
@@ -206,13 +200,13 @@
|
||||
android:name="android.max_aspect"
|
||||
android:value="4.0"/>
|
||||
|
||||
<activity android:name="cc.winboll.studio.powerbell.activities.BatteryReporterActivity"/>
|
||||
<activity android:name=".activities.BatteryReporterActivity"/>
|
||||
|
||||
<activity android:name="cc.winboll.studio.powerbell.activities.PixelPickerActivity"/>
|
||||
<activity android:name=".activities.PixelPickerActivity"/>
|
||||
|
||||
<activity android:name="cc.winboll.studio.powerbell.activities.BatteryReportActivity"/>
|
||||
<activity android:name=".activities.BatteryReportActivity"/>
|
||||
|
||||
<activity android:name="cc.winboll.studio.powerbell.unittest.MainUnitTestActivity"/>
|
||||
<activity android:name=".unittest.MainUnitTestActivity"/>
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
@@ -226,16 +220,16 @@
|
||||
|
||||
</provider>
|
||||
|
||||
<activity android:name="cc.winboll.studio.powerbell.activities.ShortcutActionActivity"/>
|
||||
<activity android:name=".activities.ShortcutActionActivity"/>
|
||||
|
||||
<activity android:name="cc.winboll.studio.powerbell.activities.SettingsActivity"/>
|
||||
<activity android:name=".activities.SettingsActivity"/>
|
||||
|
||||
<!-- 1. 注册 UCropActivity(关键:解决崩溃) -->
|
||||
<activity
|
||||
android:name="com.yalantis.ucrop.UCropActivity"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
|
||||
android:exported="true"> <!-- 必须添加:Android 12+ 要求显式声明 exported -->
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.yalantis.ucrop.UCropActivity"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
|
||||
android:exported="true">
|
||||
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
|
||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import cc.winboll.studio.powerbell.model.BackgroundBean;
|
||||
import cc.winboll.studio.powerbell.models.BackgroundBean;
|
||||
import cc.winboll.studio.powerbell.receivers.GlobalApplicationReceiver;
|
||||
import cc.winboll.studio.powerbell.utils.AppCacheUtils;
|
||||
import cc.winboll.studio.powerbell.utils.AppConfigUtils;
|
||||
|
||||
@@ -37,7 +37,7 @@ import cc.winboll.studio.powerbell.activities.ClearRecordActivity;
|
||||
import cc.winboll.studio.powerbell.activities.SettingsActivity;
|
||||
import cc.winboll.studio.powerbell.activities.WinBoLLActivity;
|
||||
import cc.winboll.studio.powerbell.fragments.MainViewFragment;
|
||||
import cc.winboll.studio.powerbell.model.BackgroundBean;
|
||||
import cc.winboll.studio.powerbell.models.BackgroundBean;
|
||||
import cc.winboll.studio.powerbell.services.ControlCenterService;
|
||||
import cc.winboll.studio.powerbell.unittest.MainUnitTestActivity;
|
||||
import cc.winboll.studio.powerbell.utils.AppConfigUtils;
|
||||
|
||||
@@ -24,13 +24,13 @@ import cc.winboll.studio.powerbell.App;
|
||||
import cc.winboll.studio.powerbell.R;
|
||||
import cc.winboll.studio.powerbell.dialogs.BackgroundPicturePreviewDialog;
|
||||
import cc.winboll.studio.powerbell.dialogs.YesNoAlertDialog;
|
||||
import cc.winboll.studio.powerbell.model.BackgroundBean;
|
||||
import cc.winboll.studio.powerbell.models.BackgroundBean;
|
||||
import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils;
|
||||
import cc.winboll.studio.powerbell.utils.BitmapCacheUtils;
|
||||
import cc.winboll.studio.powerbell.utils.FileUtils;
|
||||
import cc.winboll.studio.powerbell.utils.ImageCropUtils;
|
||||
import cc.winboll.studio.powerbell.utils.PermissionUtils;
|
||||
import cc.winboll.studio.powerbell.utils.UriUtil;
|
||||
import cc.winboll.studio.powerbell.utils.UriUtils;
|
||||
import cc.winboll.studio.powerbell.views.BackgroundView;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
@@ -38,7 +38,7 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class BackgroundSettingsActivity extends WinBoLLActivity implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener {
|
||||
public class BackgroundSettingsActivity extends WinBoLLActivity {
|
||||
|
||||
// ====================== 常量定义 ======================
|
||||
public static final String TAG = "BackgroundSettingsActivity";
|
||||
@@ -573,7 +573,12 @@ public class BackgroundSettingsActivity extends WinBoLLActivity implements Backg
|
||||
String action = intent.getAction();
|
||||
String type = intent.getType();
|
||||
if (Intent.ACTION_SEND.equals(action) && type != null && isImageType(type)) {
|
||||
BackgroundPicturePreviewDialog dlg = new BackgroundPicturePreviewDialog(this);
|
||||
BackgroundPicturePreviewDialog dlg = new BackgroundPicturePreviewDialog(this, new BackgroundPicturePreviewDialog.IOnRecivedPictureListener(){
|
||||
@Override
|
||||
public void onAcceptRecivedPicture(Uri uriRecivedPicture) {
|
||||
ToastUtils.show(String.format("uriRecivedPicture %s", uriRecivedPicture));
|
||||
}
|
||||
});
|
||||
dlg.show();
|
||||
LogUtils.d(TAG, "【分享处理】收到分享图片意图");
|
||||
return true;
|
||||
@@ -802,7 +807,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity implements Backg
|
||||
* 将 Uri 文件同步到预览 Bean
|
||||
*/
|
||||
boolean putUriFileToPreviewSource(Uri srcUriFile) {
|
||||
String filePath = UriUtil.getFilePathFromUri(this, srcUriFile);
|
||||
String filePath = UriUtils.getFilePathFromUri(this, srcUriFile);
|
||||
if (TextUtils.isEmpty(filePath)) {
|
||||
LogUtils.e(TAG, "putUriFileToPreviewSource: Uri解析路径为空");
|
||||
return false;
|
||||
@@ -876,12 +881,5 @@ public class BackgroundSettingsActivity extends WinBoLLActivity implements Backg
|
||||
handleOperationCancelOrFail();
|
||||
}
|
||||
}
|
||||
|
||||
// ====================== 接口实现 ======================
|
||||
@Override
|
||||
public void onAcceptRecivedPicture(String szPreRecivedPictureName) {
|
||||
ToastUtils.show("图片接收功能暂未实现");
|
||||
LogUtils.d(TAG, "【分享接收】图片名:" + szPreRecivedPictureName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import cc.winboll.studio.powerbell.App;
|
||||
import cc.winboll.studio.powerbell.R;
|
||||
import cc.winboll.studio.powerbell.model.BatteryInfoBean;
|
||||
import cc.winboll.studio.powerbell.models.BatteryInfoBean;
|
||||
import cc.winboll.studio.powerbell.receivers.ControlCenterServiceReceiver;
|
||||
import cc.winboll.studio.powerbell.utils.AppCacheUtils;
|
||||
import cc.winboll.studio.powerbell.utils.StringUtils;
|
||||
|
||||
@@ -26,7 +26,7 @@ import cc.winboll.studio.libappbase.GlobalApplication;
|
||||
import cc.winboll.studio.powerbell.R;
|
||||
import cc.winboll.studio.powerbell.activities.BackgroundSettingsActivity;
|
||||
import cc.winboll.studio.powerbell.activities.PixelPickerActivity;
|
||||
import cc.winboll.studio.powerbell.model.BackgroundBean;
|
||||
import cc.winboll.studio.powerbell.models.BackgroundBean;
|
||||
import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
||||
@@ -12,7 +12,7 @@ import android.widget.TextView;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import cc.winboll.studio.powerbell.R;
|
||||
import cc.winboll.studio.powerbell.adapters.BatteryAdapter;
|
||||
import cc.winboll.studio.powerbell.model.BatteryData;
|
||||
import cc.winboll.studio.powerbell.models.BatteryData;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -2,22 +2,19 @@ package cc.winboll.studio.powerbell.dialogs;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.powerbell.MainActivity;
|
||||
import cc.winboll.studio.powerbell.R;
|
||||
import cc.winboll.studio.powerbell.activities.BackgroundSettingsActivity;
|
||||
import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils;
|
||||
import cc.winboll.studio.powerbell.utils.FileUtils;
|
||||
import cc.winboll.studio.powerbell.utils.UriUtil;
|
||||
import cc.winboll.studio.powerbell.utils.UriUtils;
|
||||
import cc.winboll.studio.powerbell.views.BackgroundView;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||
@@ -29,21 +26,25 @@ public class BackgroundPicturePreviewDialog extends Dialog {
|
||||
public static final String TAG = "BackgroundPicturePreviewDialog";
|
||||
|
||||
Context mContext;
|
||||
BackgroundSourceUtils mBackgroundPictureUtils;
|
||||
//BackgroundSourceUtils mBackgroundPictureUtils;
|
||||
Button dialogbackgroundpicturepreviewButton1;
|
||||
Button dialogbackgroundpicturepreviewButton2;
|
||||
String mszPreReceivedFileName;
|
||||
//String mszPreReceivedFileName;
|
||||
IOnRecivedPictureListener mIOnRecivedPictureListener;
|
||||
Uri mUriRecivedPicture;
|
||||
BackgroundView mBackgroundView;
|
||||
|
||||
public BackgroundPicturePreviewDialog(Context context) {
|
||||
public BackgroundPicturePreviewDialog(Context context, IOnRecivedPictureListener iOnRecivedPictureListener) {
|
||||
super(context);
|
||||
setContentView(R.layout.dialog_backgroundpicturepreview);
|
||||
initEnv();
|
||||
mIOnRecivedPictureListener = iOnRecivedPictureListener;
|
||||
//initEnv();
|
||||
|
||||
mContext = context;
|
||||
mBackgroundPictureUtils = BackgroundSourceUtils.getInstance(mContext);
|
||||
//mBackgroundPictureUtils = BackgroundSourceUtils.getInstance(mContext);
|
||||
|
||||
ImageView imageView = findViewById(R.id.dialogbackgroundpicturepreviewImageView1);
|
||||
copyAndViewRecivePicture(imageView);
|
||||
mBackgroundView = findViewById(R.id.backgroundview);
|
||||
previewRecivedPicture();
|
||||
|
||||
dialogbackgroundpicturepreviewButton1 = findViewById(R.id.dialogbackgroundpicturepreviewButton1);
|
||||
dialogbackgroundpicturepreviewButton1.setOnClickListener(new View.OnClickListener() {
|
||||
@@ -53,6 +54,7 @@ public class BackgroundPicturePreviewDialog extends Dialog {
|
||||
// 跳转到主窗口
|
||||
Intent i = new Intent(mContext, MainActivity.class);
|
||||
mContext.startActivity(i);
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -62,79 +64,77 @@ public class BackgroundPicturePreviewDialog extends Dialog {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// 使用分享到的图片
|
||||
//
|
||||
//LogUtils.d(TAG, "mszReceivedFileName : " + mszReceivedFileName);
|
||||
((IOnRecivedPictureListener)mContext).onAcceptRecivedPicture(mszPreReceivedFileName);
|
||||
mIOnRecivedPictureListener.onAcceptRecivedPicture(mUriRecivedPicture);
|
||||
// 关闭对话框
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void initEnv() {
|
||||
LogUtils.d(TAG, "initEnv()");
|
||||
mszPreReceivedFileName = "PreReceived.data";
|
||||
}
|
||||
// void initEnv() {
|
||||
// LogUtils.d(TAG, "initEnv()");
|
||||
// mszPreReceivedFileName = "PreReceived.data";
|
||||
// }
|
||||
|
||||
void copyAndViewRecivePicture(ImageView imageView) {
|
||||
//AppConfigUtils appConfigUtils = AppConfigUtils.getInstance((GlobalApplication)mContext.getApplicationContext());
|
||||
void previewRecivedPicture() {
|
||||
BackgroundSettingsActivity activity = ((BackgroundSettingsActivity)mContext);
|
||||
|
||||
//取出文件uri
|
||||
Uri uri = activity.getIntent().getData();
|
||||
if (uri == null) {
|
||||
uri = activity.getIntent().getParcelableExtra(Intent.EXTRA_STREAM);
|
||||
mUriRecivedPicture = activity.getIntent().getData();
|
||||
if (mUriRecivedPicture == null) {
|
||||
mUriRecivedPicture = activity.getIntent().getParcelableExtra(Intent.EXTRA_STREAM);
|
||||
}
|
||||
//获取文件真实地址
|
||||
String szSrcImage = UriUtil.getFilePathFromUri(mContext, uri);
|
||||
String szSrcImage = UriUtils.getFilePathFromUri(mContext, mUriRecivedPicture);
|
||||
if (TextUtils.isEmpty(szSrcImage)) {
|
||||
Toast.makeText(mContext, "接收到的文件为空。", Toast.LENGTH_SHORT).show();
|
||||
dismiss();
|
||||
return;
|
||||
}
|
||||
|
||||
File fSrcImage = new File(szSrcImage);
|
||||
//mszPreReceivedFileName = DateUtils.getDateNowString() + "-" + fSrcImage.getName();
|
||||
File mfPreReceivedPhoto = new File(BackgroundSourceUtils.getInstance(mContext).getBackgroundSourceDirPath(), mszPreReceivedFileName);
|
||||
// 复制源图片到剪裁文件
|
||||
try {
|
||||
FileUtils.copyFileUsingFileChannels(fSrcImage, mfPreReceivedPhoto);
|
||||
LogUtils.d(TAG, "copyFileUsingFileChannels");
|
||||
Drawable drawable = Drawable.createFromPath(mfPreReceivedPhoto.getPath());
|
||||
imageView.setBackground(drawable);
|
||||
//LogUtils.d(TAG, "mszPreReceivedFileName : " + mszPreReceivedFileName);
|
||||
} catch (IOException e) {
|
||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||
}
|
||||
mBackgroundView.loadImage(szSrcImage);
|
||||
//
|
||||
// File fSrcImage = new File(szSrcImage);
|
||||
// //mszPreReceivedFileName = DateUtils.getDateNowString() + "-" + fSrcImage.getName();
|
||||
// File mfPreReceivedPhoto = new File(BackgroundSourceUtils.getInstance(mContext).getBackgroundSourceDirPath(), mszPreReceivedFileName);
|
||||
// // 复制源图片到剪裁文件
|
||||
// try {
|
||||
// FileUtils.copyFileUsingFileChannels(fSrcImage, mfPreReceivedPhoto);
|
||||
// LogUtils.d(TAG, "copyFileUsingFileChannels");
|
||||
// Drawable drawable = Drawable.createFromPath(mfPreReceivedPhoto.getPath());
|
||||
// imageView.setBackground(drawable);
|
||||
// //LogUtils.d(TAG, "mszPreReceivedFileName : " + mszPreReceivedFileName);
|
||||
// } catch (IOException e) {
|
||||
// LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 创建图片背景图片目录
|
||||
//
|
||||
boolean createBackgroundFolder2(String szBackgroundFolder) {
|
||||
// 文件路径参数为空值或无效值时返回false.
|
||||
if (szBackgroundFolder == null | szBackgroundFolder.equals("")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LogUtils.d(TAG, "Background Folder Is : " + szBackgroundFolder);
|
||||
File f = new File(szBackgroundFolder);
|
||||
if (f.exists()) {
|
||||
if (f.isDirectory()) {
|
||||
return true;
|
||||
} else {
|
||||
// 工作路径不是一个目录
|
||||
LogUtils.d(TAG, "createImageWorkFolder() error : szImageCacheFolder isDirectory return false. -->" + szBackgroundFolder);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return f.mkdirs();
|
||||
}
|
||||
}
|
||||
// boolean createBackgroundFolder2(String szBackgroundFolder) {
|
||||
// // 文件路径参数为空值或无效值时返回false.
|
||||
// if (szBackgroundFolder == null | szBackgroundFolder.equals("")) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// LogUtils.d(TAG, "Background Folder Is : " + szBackgroundFolder);
|
||||
// File f = new File(szBackgroundFolder);
|
||||
// if (f.exists()) {
|
||||
// if (f.isDirectory()) {
|
||||
// return true;
|
||||
// } else {
|
||||
// // 工作路径不是一个目录
|
||||
// LogUtils.d(TAG, "createImageWorkFolder() error : szImageCacheFolder isDirectory return false. -->" + szBackgroundFolder);
|
||||
// return false;
|
||||
// }
|
||||
// } else {
|
||||
// return f.mkdirs();
|
||||
// }
|
||||
// }
|
||||
|
||||
public interface IOnRecivedPictureListener {
|
||||
void onAcceptRecivedPicture(String szBackgroundFileName);
|
||||
void onAcceptRecivedPicture(Uri uriRecivedPicture);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.powerbell.App;
|
||||
import cc.winboll.studio.powerbell.R;
|
||||
import cc.winboll.studio.powerbell.activities.PixelPickerActivity;
|
||||
import cc.winboll.studio.powerbell.model.BackgroundBean;
|
||||
import cc.winboll.studio.powerbell.models.BackgroundBean;
|
||||
import cc.winboll.studio.powerbell.services.ControlCenterService;
|
||||
import cc.winboll.studio.powerbell.utils.AppConfigUtils;
|
||||
import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package cc.winboll.studio.powerbell.model;
|
||||
package cc.winboll.studio.powerbell.models;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||
@@ -1,4 +1,4 @@
|
||||
package cc.winboll.studio.powerbell.model;
|
||||
package cc.winboll.studio.powerbell.models;
|
||||
|
||||
import android.util.JsonReader;
|
||||
import android.util.JsonWriter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package cc.winboll.studio.powerbell.model;
|
||||
package cc.winboll.studio.powerbell.models;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||
@@ -1,4 +1,4 @@
|
||||
package cc.winboll.studio.powerbell.model;
|
||||
package cc.winboll.studio.powerbell.models;
|
||||
|
||||
import android.util.JsonReader;
|
||||
import android.util.JsonWriter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package cc.winboll.studio.powerbell.model;
|
||||
package cc.winboll.studio.powerbell.models;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||
@@ -1,4 +1,4 @@
|
||||
package cc.winboll.studio.powerbell.model;
|
||||
package cc.winboll.studio.powerbell.models;
|
||||
|
||||
// 应用消息结构
|
||||
//
|
||||
@@ -5,7 +5,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.powerbell.model.AppConfigBean;
|
||||
import cc.winboll.studio.powerbell.models.AppConfigBean;
|
||||
import cc.winboll.studio.powerbell.services.ControlCenterService;
|
||||
import cc.winboll.studio.powerbell.utils.AppConfigUtils;
|
||||
import cc.winboll.studio.powerbell.utils.BatteryUtils;
|
||||
|
||||
@@ -23,15 +23,15 @@ import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import cc.winboll.studio.powerbell.App;
|
||||
import cc.winboll.studio.powerbell.MainActivity;
|
||||
import cc.winboll.studio.powerbell.R;
|
||||
import cc.winboll.studio.powerbell.model.AppConfigBean;
|
||||
import cc.winboll.studio.powerbell.model.NotificationMessage;
|
||||
import cc.winboll.studio.powerbell.handlers.ControlCenterServiceHandler;
|
||||
import cc.winboll.studio.powerbell.models.AppConfigBean;
|
||||
import cc.winboll.studio.powerbell.models.NotificationMessage;
|
||||
import cc.winboll.studio.powerbell.receivers.ControlCenterServiceReceiver;
|
||||
import cc.winboll.studio.powerbell.services.AssistantService;
|
||||
import cc.winboll.studio.powerbell.threads.RemindThread;
|
||||
import cc.winboll.studio.powerbell.utils.AppCacheUtils;
|
||||
import cc.winboll.studio.powerbell.utils.AppConfigUtils;
|
||||
import cc.winboll.studio.powerbell.utils.NotificationHelper;
|
||||
import cc.winboll.studio.powerbell.utils.NotificationManagerUtils;
|
||||
import cc.winboll.studio.powerbell.utils.ServiceUtils;
|
||||
import cc.winboll.studio.powerbell.utils.StringUtils;
|
||||
|
||||
@@ -48,7 +48,7 @@ public class ControlCenterService extends Service {
|
||||
AppConfigUtils mAppConfigUtils;
|
||||
AppCacheUtils mAppCacheUtils;
|
||||
// 前台服务通知工具
|
||||
NotificationHelper mNotificationHelper;
|
||||
NotificationManagerUtils mNotificationManagerUtils;
|
||||
Notification notification;
|
||||
RemindThread mRemindThread;
|
||||
ControlCenterServiceHandler mControlCenterServiceHandler;
|
||||
@@ -72,7 +72,7 @@ public class ControlCenterService extends Service {
|
||||
isServiceRunning = false;
|
||||
mAppConfigUtils = App.getAppConfigUtils(this);
|
||||
mAppCacheUtils = App.getAppCacheUtils(this);
|
||||
mNotificationHelper = new NotificationHelper(ControlCenterService.this);
|
||||
mNotificationManagerUtils = new NotificationManagerUtils(ControlCenterService.this);
|
||||
|
||||
|
||||
if (mMyServiceConnection == null) {
|
||||
@@ -101,10 +101,10 @@ public class ControlCenterService extends Service {
|
||||
wakeupAndBindAssistant();
|
||||
// 显示前台通知栏
|
||||
// 在Service中
|
||||
NotificationHelper helper = new NotificationHelper(this);
|
||||
Intent intent = new Intent(this, MainActivity.class);
|
||||
notification = helper.showForegroundNotification(intent, getString(R.string.app_name), "Service Running, Click to open app");
|
||||
startForeground(NotificationHelper.FOREGROUND_NOTIFICATION_ID, notification);
|
||||
NotificationManagerUtils notificationManagerUtils = new NotificationManagerUtils(this);
|
||||
//Intent intent = new Intent(this, MainActivity.class);
|
||||
notificationManagerUtils.startForegroundServiceNotify(ControlCenterService.this, new NotificationMessage(getString(R.string.app_name), "Service Running, Click to open app"));
|
||||
//startForeground(NotificationHelper.FOREGROUND_NOTIFICATION_ID, notification);
|
||||
|
||||
// NotificationMessage notificationMessage=createNotificationMessage();
|
||||
// //Toast.makeText(getApplication(), "", Toast.LENGTH_SHORT).show();
|
||||
@@ -260,9 +260,9 @@ public class ControlCenterService extends Service {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
msg += szRemindMSG;
|
||||
}
|
||||
NotificationHelper helper = new NotificationHelper(ControlCenterService.this);
|
||||
NotificationManagerUtils notificationManagerUtils = new NotificationManagerUtils(ControlCenterService.this);
|
||||
Intent intent = new Intent(ControlCenterService.this, MainActivity.class);
|
||||
helper.showTemporaryNotification(intent, getString(R.string.app_name), msg);
|
||||
notificationManagerUtils.showTempAlertNotify(intent, getString(R.string.app_name), msg);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package cc.winboll.studio.powerbell.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.powerbell.model.BatteryInfoBean;
|
||||
import cc.winboll.studio.powerbell.models.BatteryInfoBean;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class AppCacheUtils {
|
||||
|
||||
@@ -5,8 +5,8 @@ import android.content.Context;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.powerbell.App;
|
||||
import cc.winboll.studio.powerbell.MainActivity;
|
||||
import cc.winboll.studio.powerbell.model.AppConfigBean;
|
||||
import cc.winboll.studio.powerbell.model.ControlCenterServiceBean;
|
||||
import cc.winboll.studio.powerbell.models.AppConfigBean;
|
||||
import cc.winboll.studio.powerbell.models.ControlCenterServiceBean;
|
||||
import cc.winboll.studio.powerbell.dialogs.YesNoAlertDialog;
|
||||
import cc.winboll.studio.powerbell.fragments.MainViewFragment;
|
||||
import cc.winboll.studio.powerbell.services.ControlCenterService;
|
||||
|
||||
@@ -11,7 +11,7 @@ import androidx.core.content.FileProvider;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import cc.winboll.studio.powerbell.BuildConfig;
|
||||
import cc.winboll.studio.powerbell.model.BackgroundBean;
|
||||
import cc.winboll.studio.powerbell.models.BackgroundBean;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@@ -226,7 +226,7 @@ public class BackgroundSourceUtils {
|
||||
return true;
|
||||
}
|
||||
|
||||
Uri uri = UriUtil.getUriForFile(mContext, oldPreviewBackgroundBean.getBackgroundFilePath());
|
||||
Uri uri = UriUtils.getUriForFile(mContext, oldPreviewBackgroundBean.getBackgroundFilePath());
|
||||
String fileSuffix = FileUtils.getFileSuffix(mContext, uri);
|
||||
String newCropFileName = UUID.randomUUID().toString() + System.currentTimeMillis();
|
||||
mCropSourceFile = new File(fCropCacheDir, newCropFileName + "." + fileSuffix);
|
||||
|
||||
@@ -6,7 +6,7 @@ import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import androidx.core.content.FileProvider;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.powerbell.model.BackgroundBean;
|
||||
import cc.winboll.studio.powerbell.models.BackgroundBean;
|
||||
import com.yalantis.ucrop.UCrop;
|
||||
import com.yalantis.ucrop.UCropActivity;
|
||||
import java.io.File;
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
package cc.winboll.studio.powerbell.utils;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||
* @Date 2025/03/22 04:39:40
|
||||
* @Describe 通知工具类
|
||||
*/
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Build;
|
||||
import android.widget.RemoteViews;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import cc.winboll.studio.powerbell.R;
|
||||
|
||||
public class NotificationHelper {
|
||||
public static final String TAG = "NotificationHelper";
|
||||
|
||||
// 渠道ID和名称
|
||||
private static final String CHANNEL_ID_FOREGROUND = "foreground_channel";
|
||||
private static final String CHANNEL_NAME_FOREGROUND = "Foreground Service";
|
||||
private static final String CHANNEL_ID_TEMPORARY = "temporary_channel";
|
||||
private static final String CHANNEL_NAME_TEMPORARY = "Temporary Notifications";
|
||||
|
||||
// 通知ID
|
||||
public static final int FOREGROUND_NOTIFICATION_ID = 1001;
|
||||
public static final int TEMPORARY_NOTIFICATION_ID = 2001;
|
||||
|
||||
private final Context mContext;
|
||||
private final NotificationManager mNotificationManager;
|
||||
|
||||
public NotificationHelper(Context context) {
|
||||
mContext = context;
|
||||
mNotificationManager = context.getSystemService(NotificationManager.class);
|
||||
createNotificationChannels();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
private void createNotificationChannels() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
createForegroundChannel();
|
||||
createTemporaryChannel();
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
private void createForegroundChannel() {
|
||||
NotificationChannel channel = new NotificationChannel(
|
||||
CHANNEL_ID_FOREGROUND,
|
||||
CHANNEL_NAME_FOREGROUND,
|
||||
NotificationManager.IMPORTANCE_LOW
|
||||
);
|
||||
channel.setDescription("Persistent service notifications");
|
||||
channel.setSound(null, null);
|
||||
channel.enableVibration(false);
|
||||
mNotificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
private void createTemporaryChannel() {
|
||||
NotificationChannel channel = new NotificationChannel(
|
||||
CHANNEL_ID_TEMPORARY,
|
||||
CHANNEL_NAME_TEMPORARY,
|
||||
NotificationManager.IMPORTANCE_HIGH
|
||||
);
|
||||
channel.setDescription("Temporary alert notifications");
|
||||
channel.setSound(null, null);
|
||||
channel.enableVibration(true);
|
||||
channel.setVibrationPattern(new long[]{100, 200, 300, 400});
|
||||
channel.setBypassDnd(true);
|
||||
mNotificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
|
||||
// 显示常驻通知(通常用于前台服务)
|
||||
public Notification showForegroundNotification(Intent intent, String title, String content) {
|
||||
PendingIntent pendingIntent = createPendingIntent(intent);
|
||||
|
||||
Notification notification = new NotificationCompat.Builder(mContext, CHANNEL_ID_FOREGROUND)
|
||||
.setSmallIcon(R.drawable.ic_launcher)
|
||||
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher))
|
||||
//.setContentTitle(title + "\n" + content)
|
||||
.setContentTitle(content)
|
||||
//.setContentText(content)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
.setOngoing(true)
|
||||
.build();
|
||||
|
||||
mNotificationManager.notify(FOREGROUND_NOTIFICATION_ID, notification);
|
||||
return notification;
|
||||
}
|
||||
|
||||
// 显示临时通知(自动消失)
|
||||
public void showTemporaryNotification(Intent intent, String title, String content) {
|
||||
PendingIntent pendingIntent = createPendingIntent(intent);
|
||||
|
||||
Notification notification = new NotificationCompat.Builder(mContext, CHANNEL_ID_TEMPORARY)
|
||||
.setSmallIcon(R.drawable.ic_launcher)
|
||||
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher))
|
||||
.setContentTitle(title)
|
||||
.setContentText(content)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setAutoCancel(true)
|
||||
.setVibrate(new long[]{100, 200, 300, 400})
|
||||
.build();
|
||||
|
||||
mNotificationManager.notify(TEMPORARY_NOTIFICATION_ID, notification);
|
||||
}
|
||||
|
||||
// 创建自定义布局通知(可扩展)
|
||||
public void showCustomNotification(Intent intent, RemoteViews contentView, RemoteViews bigContentView) {
|
||||
PendingIntent pendingIntent = createPendingIntent(intent);
|
||||
|
||||
Notification notification = new NotificationCompat.Builder(mContext, CHANNEL_ID_TEMPORARY)
|
||||
.setSmallIcon(R.drawable.ic_launcher)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setContent(contentView)
|
||||
.setCustomBigContentView(bigContentView)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setAutoCancel(true)
|
||||
.build();
|
||||
|
||||
mNotificationManager.notify(TEMPORARY_NOTIFICATION_ID + 1, notification);
|
||||
}
|
||||
|
||||
// 取消所有通知
|
||||
public void cancelAllNotifications() {
|
||||
mNotificationManager.cancelAll();
|
||||
}
|
||||
|
||||
// 创建PendingIntent(兼容不同API版本)
|
||||
private PendingIntent createPendingIntent(Intent intent) {
|
||||
int flags = PendingIntent.FLAG_UPDATE_CURRENT;
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
// flags |= PendingIntent.FLAG_IMMUTABLE;
|
||||
// }
|
||||
return PendingIntent.getActivity(
|
||||
mContext,
|
||||
0,
|
||||
intent,
|
||||
flags
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,422 @@
|
||||
package cc.winboll.studio.powerbell.utils;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.media.RingtoneManager;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.powerbell.MainActivity;
|
||||
import cc.winboll.studio.powerbell.R;
|
||||
import cc.winboll.studio.powerbell.models.NotificationMessage;
|
||||
import cc.winboll.studio.powerbell.services.ControlCenterService;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
* @Date 2025/12/13 20:44
|
||||
* @Describe 全局通知管理工具类(整合所有通知能力,适配API29-30,兼容Java7)
|
||||
*/
|
||||
public class NotificationManagerUtils {
|
||||
// ====================== 常量定义(统一管理,避免冲突,首屏可见)======================
|
||||
public static final String TAG = "NotificationManagerUtils";
|
||||
// 通知渠道(4大渠道,场景隔离,API26+必填)
|
||||
// 1. 前台服务保活渠道(低优先级,无打扰)
|
||||
private static final String CHANNEL_ID_FOREGROUND_SERVICE = "channel_foreground_service";
|
||||
private static final String CHANNEL_NAME_FOREGROUND_SERVICE = "前台服务保活通知";
|
||||
private static final String CHANNEL_DESC_FOREGROUND_SERVICE = "后台服务运行状态,无声音无震动,不打扰用户";
|
||||
// 2. 电量提醒渠道(高优先级,闹钟铃声+震动,强提醒)
|
||||
private static final String CHANNEL_ID_BATTERY_REMIND = "channel_battery_remind";
|
||||
private static final String CHANNEL_NAME_BATTERY_REMIND = "电量异常提醒通知";
|
||||
private static final String CHANNEL_DESC_BATTERY_REMIND = "电量过高/过低提醒,强震动+闹钟铃声,突破免打扰";
|
||||
// 3. 通用临时通知渠道(高优先级,仅震动,普通告警)
|
||||
private static final String CHANNEL_ID_TEMP_ALERT = "channel_temp_alert";
|
||||
private static final String CHANNEL_NAME_TEMP_ALERT = "通用临时提醒通知";
|
||||
private static final String CHANNEL_DESC_TEMP_ALERT = "普通即时告警,仅震动提醒,自动取消";
|
||||
// 通知ID(唯一区分,避免覆盖,按场景分段)
|
||||
public static final int NOTIFY_ID_FOREGROUND_SERVICE = 1001; // 前台服务
|
||||
public static final int NOTIFY_ID_BATTERY_REMIND = 1002; // 电量提醒
|
||||
public static final int NOTIFY_ID_TEMP_ALERT = 1003; // 通用临时通知
|
||||
public static final int NOTIFY_ID_CUSTOM_LAYOUT = 1004; // 自定义布局通知
|
||||
// 通用配置
|
||||
private static final int PENDING_INTENT_FLAGS = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
|
||||
: PendingIntent.FLAG_UPDATE_CURRENT; // API30安全标志
|
||||
private static final long[] VIBRATE_PATTERN = new long[]{100, 200, 300, 400}; // 标准震动节奏
|
||||
private static final String DEFAULT_JUMP_PACKAGE = "cc.winboll.studio.powerbell"; // 默认跳转包名(API29+必填)
|
||||
|
||||
// ====================== 成员变量(按场景分组,私有封装,避免外部篡改)======================
|
||||
private final Context mContext;
|
||||
private final NotificationManager mNotificationManager;
|
||||
// 前台服务通知专属
|
||||
private Notification mForegroundServiceNotify;
|
||||
private RemoteViews mForegroundServiceRemoteViews;
|
||||
// 电量提醒通知专属
|
||||
private Notification mBatteryRemindNotify;
|
||||
private RemoteViews mBatteryRemindRemoteViews;
|
||||
|
||||
// ====================== 构造方法(单例思想/实例化通用,自动初始化渠道)======================
|
||||
public NotificationManagerUtils(Context context) {
|
||||
LogUtils.d(TAG, "【初始化】全局通知管理工具类 构造方法调用");
|
||||
this.mContext = context.getApplicationContext(); // 用应用上下文,避免内存泄漏
|
||||
this.mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
createAllNotificationChannels(); // 自动创建所有渠道(API26+)
|
||||
LogUtils.d(TAG, "【初始化】全局通知管理工具类 完成,渠道创建状态:" + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? "已创建4个渠道" : "无需创建"));
|
||||
}
|
||||
|
||||
// ====================== 核心基础能力(渠道创建+Intent构建,复用逻辑,减少冗余)======================
|
||||
/**
|
||||
* 创建所有通知渠道(API26+专属,低版本自动跳过,确保通知正常显示)
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void createAllNotificationChannels() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
LogUtils.d(TAG, "【渠道管理】开始创建所有通知渠道");
|
||||
createForegroundServiceChannel();
|
||||
createBatteryRemindChannel();
|
||||
createTempAlertChannel();
|
||||
LogUtils.d(TAG, "【渠道管理】4个通知渠道创建完成(含3个核心渠道+预留扩展)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建前台服务保活渠道(IMPORTANCE_LOW,无声音无震动,不打扰用户)
|
||||
*/
|
||||
private void createForegroundServiceChannel() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
NotificationChannel channel = new NotificationChannel(
|
||||
CHANNEL_ID_FOREGROUND_SERVICE,
|
||||
CHANNEL_NAME_FOREGROUND_SERVICE,
|
||||
NotificationManager.IMPORTANCE_LOW
|
||||
);
|
||||
channel.setDescription(CHANNEL_DESC_FOREGROUND_SERVICE);
|
||||
channel.setSound(null, null);
|
||||
channel.enableVibration(false);
|
||||
channel.setShowBadge(false); // 不显示应用角标
|
||||
channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET); // 锁屏隐藏
|
||||
mNotificationManager.createNotificationChannel(channel);
|
||||
LogUtils.d(TAG, "【渠道管理】前台服务保活渠道创建成功:" + CHANNEL_NAME_FOREGROUND_SERVICE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建电量提醒渠道(IMPORTANCE_HIGH,闹钟铃声+震动,突破免打扰)
|
||||
*/
|
||||
private void createBatteryRemindChannel() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
NotificationChannel channel = new NotificationChannel(
|
||||
CHANNEL_ID_BATTERY_REMIND,
|
||||
CHANNEL_NAME_BATTERY_REMIND,
|
||||
NotificationManager.IMPORTANCE_HIGH
|
||||
);
|
||||
channel.setDescription(CHANNEL_DESC_BATTERY_REMIND);
|
||||
channel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM), null); // 闹钟铃声
|
||||
channel.enableVibration(true);
|
||||
channel.setVibrationPattern(VIBRATE_PATTERN);
|
||||
channel.setBypassDnd(true); // 突破免打扰
|
||||
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); // 锁屏可见
|
||||
channel.setShowBadge(true);
|
||||
mNotificationManager.createNotificationChannel(channel);
|
||||
LogUtils.d(TAG, "【渠道管理】电量提醒渠道创建成功:" + CHANNEL_NAME_BATTERY_REMIND);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建通用临时通知渠道(IMPORTANCE_HIGH,仅震动,普通告警)
|
||||
*/
|
||||
private void createTempAlertChannel() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
NotificationChannel channel = new NotificationChannel(
|
||||
CHANNEL_ID_TEMP_ALERT,
|
||||
CHANNEL_NAME_TEMP_ALERT,
|
||||
NotificationManager.IMPORTANCE_HIGH
|
||||
);
|
||||
channel.setDescription(CHANNEL_DESC_TEMP_ALERT);
|
||||
channel.setSound(null, null); // 仅震动,不发声
|
||||
channel.enableVibration(true);
|
||||
channel.setVibrationPattern(VIBRATE_PATTERN);
|
||||
channel.setBypassDnd(false); // 不突破免打扰
|
||||
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
|
||||
channel.setShowBadge(true);
|
||||
mNotificationManager.createNotificationChannel(channel);
|
||||
LogUtils.d(TAG, "【渠道管理】通用临时通知渠道创建成功:" + CHANNEL_NAME_TEMP_ALERT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建通用跳转PendingIntent(适配API29-30安全规范,支持自定义跳转目标)
|
||||
* @param targetIntent 自定义跳转意图(传null则默认跳MainActivity)
|
||||
* @return 安全的PendingIntent,避免跳转失败/泄露
|
||||
*/
|
||||
private PendingIntent buildPendingIntent(Intent targetIntent) {
|
||||
Intent intent = targetIntent;
|
||||
// 传null则默认跳MainActivity(兼容旧逻辑)
|
||||
if (intent == null) {
|
||||
intent = new Intent(mContext, MainActivity.class);
|
||||
LogUtils.d(TAG, "【Intent构建】未传自定义Intent,默认跳转:MainActivity");
|
||||
}
|
||||
// API29+ 强制要求:明确包名,避免跳转目标模糊
|
||||
intent.setPackage(DEFAULT_JUMP_PACKAGE);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 确保跳转生效
|
||||
LogUtils.d(TAG, "【Intent构建】跳转包名:" + DEFAULT_JUMP_PACKAGE + ",目标:" + intent.getComponent().getClassName());
|
||||
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(
|
||||
mContext,
|
||||
0,
|
||||
intent,
|
||||
PENDING_INTENT_FLAGS
|
||||
);
|
||||
LogUtils.d(TAG, "【Intent构建】PendingIntent创建成功,安全标志:" + PENDING_INTENT_FLAGS);
|
||||
return pendingIntent;
|
||||
}
|
||||
|
||||
// ====================== 场景1:前台服务保活通知(支持自定义布局+更新)======================
|
||||
/**
|
||||
* 初始化前台服务通知自定义布局(RemoteViews)
|
||||
*/
|
||||
private void initForegroundServiceRemoteViews(ControlCenterService service, NotificationMessage msg) {
|
||||
LogUtils.d(TAG, "【布局初始化】开始初始化前台服务通知布局,标题:" + msg.getTitle());
|
||||
mForegroundServiceRemoteViews = new RemoteViews(service.getPackageName(), R.layout.view_servicenotification);
|
||||
mForegroundServiceRemoteViews.setTextViewText(R.id.remoteviewTextView1, msg.getTitle());
|
||||
mForegroundServiceRemoteViews.setTextViewText(R.id.remoteviewTextView3, msg.getContent());
|
||||
mForegroundServiceRemoteViews.setImageViewResource(R.id.remoteviewImageView1, R.drawable.ic_launcher);
|
||||
LogUtils.d(TAG, "【布局初始化】前台服务通知布局填充完成");
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动前台服务保活通知(ControlCenterService专用,API26+强制要求,保活后台服务)
|
||||
*/
|
||||
public void startForegroundServiceNotify(ControlCenterService service, NotificationMessage msg) {
|
||||
LogUtils.d(TAG, "【前台服务通知】开始构建保活通知,内容:" + msg.getContent());
|
||||
if (service == null || msg == null) {
|
||||
LogUtils.e(TAG, "【前台服务通知】构建失败:Service/NotificationMessage为空");
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 构建跳转Intent
|
||||
PendingIntent pendingIntent = buildPendingIntent(null); // 默认跳MainActivity
|
||||
// 2. 构建基础通知(兼容API26+渠道,低版本用Builder)
|
||||
Notification.Builder builder;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
builder = new Notification.Builder(service, CHANNEL_ID_FOREGROUND_SERVICE);
|
||||
} else {
|
||||
builder = new Notification.Builder(service);
|
||||
}
|
||||
mForegroundServiceNotify = builder
|
||||
.setSmallIcon(R.drawable.ic_launcher)
|
||||
.setLargeIcon(BitmapFactory.decodeResource(service.getResources(), R.drawable.ic_launcher))
|
||||
.setContentTitle(msg.getTitle())
|
||||
.setContentText(msg.getContent())
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setColor(Color.parseColor("#F00606")) // 小图标背景色
|
||||
.setContentIntent(pendingIntent)
|
||||
.setOngoing(true) // 常驻通知,不可滑动取消(保活关键)
|
||||
.setAutoCancel(false) // 禁止点击取消
|
||||
.build();
|
||||
// 3. 设置自定义布局
|
||||
initForegroundServiceRemoteViews(service, msg);
|
||||
mForegroundServiceNotify.contentView = mForegroundServiceRemoteViews;
|
||||
mForegroundServiceNotify.bigContentView = mForegroundServiceRemoteViews;
|
||||
// 4. 启动前台服务(必须调用,否则Service易被回收)
|
||||
service.startForeground(NOTIFY_ID_FOREGROUND_SERVICE, mForegroundServiceNotify);
|
||||
LogUtils.d(TAG, "【前台服务通知】保活通知启动成功,通知ID:" + NOTIFY_ID_FOREGROUND_SERVICE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新前台服务保活通知内容(无需重启服务,直接刷新布局)
|
||||
*/
|
||||
public void updateForegroundServiceNotify(ControlCenterService service, NotificationMessage msg) {
|
||||
LogUtils.d(TAG, "【前台服务通知】开始更新保活通知,新内容:" + msg.getContent());
|
||||
if (mForegroundServiceNotify == null || mForegroundServiceRemoteViews == null) {
|
||||
LogUtils.e(TAG, "【前台服务通知】更新失败:通知对象未初始化,先调用startForegroundServiceNotify");
|
||||
return;
|
||||
}
|
||||
// 更新自定义布局数据
|
||||
initForegroundServiceRemoteViews(service, msg);
|
||||
mForegroundServiceNotify.contentView = mForegroundServiceRemoteViews;
|
||||
mForegroundServiceNotify.bigContentView = mForegroundServiceRemoteViews;
|
||||
// 发送更新
|
||||
mNotificationManager.notify(NOTIFY_ID_FOREGROUND_SERVICE, mForegroundServiceNotify);
|
||||
LogUtils.d(TAG, "【前台服务通知】保活通知更新成功");
|
||||
}
|
||||
|
||||
// ====================== 场景2:电量提醒通知(支持自定义布局+更新+单独取消)======================
|
||||
/**
|
||||
* 初始化电量提醒通知自定义布局(RemoteViews,支持充电/耗电切换)
|
||||
*/
|
||||
private void initBatteryRemindRemoteViews(ControlCenterService service, NotificationMessage msg) {
|
||||
LogUtils.d(TAG, "【布局初始化】开始初始化电量提醒布局,提醒类型:" + msg.getRemindMSG());
|
||||
mBatteryRemindRemoteViews = new RemoteViews(service.getPackageName(), R.layout.view_remindnotification);
|
||||
mBatteryRemindRemoteViews.setTextViewText(R.id.viewremindnotificationTextView1, msg.getTitle());
|
||||
mBatteryRemindRemoteViews.setImageViewResource(R.id.remoteviewImageView1, R.drawable.ic_launcher);
|
||||
// 切换布局(+:充电提醒,-:耗电提醒)
|
||||
String remindType = msg.getRemindMSG() != null ? msg.getRemindMSG().trim() : "";
|
||||
if ("+".equals(remindType)) {
|
||||
mBatteryRemindRemoteViews.setViewVisibility(R.id.remoteviewUsege, View.GONE);
|
||||
mBatteryRemindRemoteViews.setViewVisibility(R.id.remoteviewCharge, View.VISIBLE);
|
||||
LogUtils.d(TAG, "【布局初始化】电量提醒布局切换:充电提醒");
|
||||
} else if ("-".equals(remindType)) {
|
||||
mBatteryRemindRemoteViews.setViewVisibility(R.id.remoteviewCharge, View.GONE);
|
||||
mBatteryRemindRemoteViews.setViewVisibility(R.id.remoteviewUsege, View.VISIBLE);
|
||||
LogUtils.d(TAG, "【布局初始化】电量提醒布局切换:耗电提醒");
|
||||
} else {
|
||||
mBatteryRemindRemoteViews.setViewVisibility(R.id.remoteviewCharge, View.GONE);
|
||||
mBatteryRemindRemoteViews.setViewVisibility(R.id.remoteviewUsege, View.VISIBLE);
|
||||
LogUtils.w(TAG, "【布局初始化】未知电量提醒类型:" + remindType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化电量提醒通知(仅构建,不发送,配合update触发提醒)
|
||||
*/
|
||||
public void initBatteryRemindNotify(ControlCenterService service, NotificationMessage msg) {
|
||||
LogUtils.d(TAG, "【电量提醒通知】开始初始化提醒通知,标题:" + msg.getTitle());
|
||||
if (service == null || msg == null) {
|
||||
LogUtils.e(TAG, "【电量提醒通知】初始化失败:Service/NotificationMessage为空");
|
||||
return;
|
||||
}
|
||||
// 1. 构建跳转Intent
|
||||
PendingIntent pendingIntent = buildPendingIntent(null);
|
||||
// 2. 构建基础通知
|
||||
Notification.Builder builder;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
builder = new Notification.Builder(service, CHANNEL_ID_BATTERY_REMIND);
|
||||
} else {
|
||||
builder = new Notification.Builder(service);
|
||||
}
|
||||
mBatteryRemindNotify = builder
|
||||
.setSmallIcon(R.drawable.ic_launcher)
|
||||
.setLargeIcon(BitmapFactory.decodeResource(service.getResources(), R.drawable.ic_launcher))
|
||||
.setContentTitle(msg.getTitle())
|
||||
.setContentText(msg.getContent())
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setColor(Color.parseColor("#F00606"))
|
||||
.setContentIntent(pendingIntent)
|
||||
.setAutoCancel(true) // 点击取消
|
||||
.build();
|
||||
// 3. 初始化自定义布局
|
||||
initBatteryRemindRemoteViews(service, msg);
|
||||
mBatteryRemindNotify.contentView = mBatteryRemindRemoteViews;
|
||||
mBatteryRemindNotify.bigContentView = mBatteryRemindRemoteViews;
|
||||
LogUtils.d(TAG, "【电量提醒通知】初始化完成");
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送/更新电量提醒通知(初始化后调用,触发强提醒)
|
||||
*/
|
||||
public void sendOrUpdateBatteryRemindNotify() {
|
||||
LogUtils.d(TAG, "【电量提醒通知】开始发送/更新提醒");
|
||||
if (mBatteryRemindNotify == null || mBatteryRemindRemoteViews == null) {
|
||||
LogUtils.e(TAG, "【电量提醒通知】发送失败:通知未初始化,先调用initBatteryRemindNotify");
|
||||
return;
|
||||
}
|
||||
mNotificationManager.notify(NOTIFY_ID_BATTERY_REMIND, mBatteryRemindNotify);
|
||||
LogUtils.d(TAG, "【电量提醒通知】发送/更新成功,通知ID:" + NOTIFY_ID_BATTERY_REMIND);
|
||||
}
|
||||
|
||||
/**
|
||||
* 单独取消电量提醒通知(静态方法,外部可直接调用,无需实例化)
|
||||
*/
|
||||
public static void cancelBatteryRemindNotify(Context context) {
|
||||
LogUtils.d(TAG, "【电量提醒通知】开始取消提醒,通知ID:" + NOTIFY_ID_BATTERY_REMIND);
|
||||
if (context == null) {
|
||||
LogUtils.e(TAG, "【电量提醒通知】取消失败:Context为空");
|
||||
return;
|
||||
}
|
||||
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
manager.cancel(NOTIFY_ID_BATTERY_REMIND);
|
||||
LogUtils.d(TAG, "【电量提醒通知】取消成功");
|
||||
}
|
||||
|
||||
// ====================== 场景3:通用临时通知(简单文本,自动取消,无需自定义布局)======================
|
||||
/**
|
||||
* 显示通用临时通知(普通告警,仅震动,自动取消,支持自定义跳转目标)
|
||||
* @param targetIntent 自定义跳转Intent(传null默认跳MainActivity)
|
||||
* @param title 通知标题
|
||||
* @param content 通知内容
|
||||
*/
|
||||
public void showTempAlertNotify(Intent targetIntent, String title, String content) {
|
||||
LogUtils.d(TAG, "【通用临时通知】开始构建,标题:" + title + ",内容:" + content);
|
||||
if (title == null || content == null) {
|
||||
LogUtils.e(TAG, "【通用临时通知】构建失败:标题/内容为空");
|
||||
return;
|
||||
}
|
||||
// 1. 构建跳转Intent
|
||||
PendingIntent pendingIntent = buildPendingIntent(targetIntent);
|
||||
// 2. 用NotificationCompat.Builder(兼容所有版本,简化逻辑)
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, CHANNEL_ID_TEMP_ALERT)
|
||||
.setSmallIcon(R.drawable.ic_launcher)
|
||||
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher))
|
||||
.setContentTitle(title)
|
||||
.setContentText(content)
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setContentIntent(pendingIntent)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setAutoCancel(true)
|
||||
.setVibrate(VIBRATE_PATTERN);
|
||||
// 3. 发送通知
|
||||
Notification notification = builder.build();
|
||||
mNotificationManager.notify(NOTIFY_ID_TEMP_ALERT, notification);
|
||||
LogUtils.d(TAG, "【通用临时通知】显示成功,通知ID:" + NOTIFY_ID_TEMP_ALERT);
|
||||
}
|
||||
|
||||
// ====================== 场景4:自定义布局通知(灵活扩展,支持复杂样式)======================
|
||||
/**
|
||||
* 显示自定义布局通知(支持普通布局+大布局,通用所有场景,可自定义跳转)
|
||||
* @param targetIntent 自定义跳转Intent
|
||||
* @param contentView 普通自定义布局(必填)
|
||||
* @param bigContentView 下拉大布局(可选)
|
||||
*/
|
||||
public void showCustomLayoutNotify(Intent targetIntent, RemoteViews contentView, RemoteViews bigContentView) {
|
||||
LogUtils.d(TAG, "【自定义布局通知】开始构建,布局ID:" + (contentView != null ? contentView.getLayoutId() : null));
|
||||
if (contentView == null) {
|
||||
LogUtils.e(TAG, "【自定义布局通知】构建失败:普通布局contentView为空");
|
||||
return;
|
||||
}
|
||||
// 1. 构建跳转Intent
|
||||
PendingIntent pendingIntent = buildPendingIntent(targetIntent);
|
||||
// 2. 构建自定义布局通知
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, CHANNEL_ID_TEMP_ALERT)
|
||||
.setSmallIcon(R.drawable.ic_launcher) // 必传,不可省略
|
||||
.setContentIntent(pendingIntent)
|
||||
.setContent(contentView)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setAutoCancel(true);
|
||||
// 添加大布局(可选)
|
||||
if (bigContentView != null) {
|
||||
builder.setCustomBigContentView(bigContentView);
|
||||
LogUtils.d(TAG, "【自定义布局通知】已添加下拉大布局,布局ID:" + bigContentView.getLayoutId());
|
||||
}
|
||||
// 3. 发送通知
|
||||
Notification notification = builder.build();
|
||||
mNotificationManager.notify(NOTIFY_ID_CUSTOM_LAYOUT, notification);
|
||||
LogUtils.d(TAG, "【自定义布局通知】显示成功,通知ID:" + NOTIFY_ID_CUSTOM_LAYOUT);
|
||||
}
|
||||
|
||||
// ====================== 通知取消工具(支持精准取消/全取消)======================
|
||||
/**
|
||||
* 取消指定ID的通知(精准取消,灵活控制)
|
||||
*/
|
||||
public void cancelNotifyById(int notifyId) {
|
||||
LogUtils.d(TAG, "【通知管理】开始取消通知,ID:" + notifyId);
|
||||
mNotificationManager.cancel(notifyId);
|
||||
LogUtils.d(TAG, "【通知管理】通知取消成功,ID:" + notifyId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消所有通知(谨慎使用,会清除所有场景的通知)
|
||||
*/
|
||||
public void cancelAllNotifies() {
|
||||
LogUtils.d(TAG, "【通知管理】开始取消所有通知");
|
||||
mNotificationManager.cancelAll();
|
||||
LogUtils.d(TAG, "【通知管理】所有通知取消完成");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,247 +0,0 @@
|
||||
package cc.winboll.studio.powerbell.utils;
|
||||
|
||||
/*
|
||||
* 参考:
|
||||
* https://blog.csdn.net/qq_35507234/article/details/90676587
|
||||
* https://blog.csdn.net/qq_16628781/article/details/51548324
|
||||
*/
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.media.RingtoneManager;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import cc.winboll.studio.powerbell.MainActivity;
|
||||
import cc.winboll.studio.powerbell.R;
|
||||
import cc.winboll.studio.powerbell.model.NotificationMessage;
|
||||
import cc.winboll.studio.powerbell.services.ControlCenterService;
|
||||
|
||||
public class NotificationUtils2 {
|
||||
|
||||
public static final String TAG = NotificationHelper.class.getSimpleName();
|
||||
|
||||
Context mContext;
|
||||
NotificationManager mNotificationManager;
|
||||
|
||||
Notification mForegroundNotification;
|
||||
PendingIntent mForegroundPendingIntent;
|
||||
Notification mRemindNotification;
|
||||
PendingIntent mRemindPendingIntent;
|
||||
RemoteViews mrvServiceNotificationView;
|
||||
RemoteViews mrvRemindNotificationView;
|
||||
|
||||
static enum NotificationType { MIN, MAX };
|
||||
private static int _mnServiceNotificationID = 1;
|
||||
private static int _mnRemindNotificationID = 2;
|
||||
private static String _mszChannelIDService = "1";
|
||||
private static String _mszChannelNameService = "Service";
|
||||
private static String _mszChannelIDRemind = "2";
|
||||
private static String _mszChannelNameRemind = "Remind";
|
||||
|
||||
// public NotificationUtils(Context context) {
|
||||
// mContext = context;
|
||||
// mNotificationManager = (NotificationManager) context.getSystemService(
|
||||
// Context.NOTIFICATION_SERVICE);
|
||||
// }
|
||||
|
||||
public NotificationUtils2(Context context) {
|
||||
mContext = context;
|
||||
mNotificationManager = context.getSystemService(NotificationManager.class);
|
||||
//createNotificationChannels();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
public void createNotificationChannels() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
createServiceChannel();
|
||||
createRemindChannel();
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
private void createServiceChannel() {
|
||||
NotificationChannel channel = new NotificationChannel(
|
||||
_mszChannelIDService,
|
||||
_mszChannelNameService,
|
||||
NotificationManager.IMPORTANCE_LOW
|
||||
);
|
||||
channel.setDescription("Background service updates");
|
||||
channel.setSound(null, null);
|
||||
channel.enableVibration(false);
|
||||
mNotificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
private void createRemindChannel() {
|
||||
NotificationChannel channel = new NotificationChannel(
|
||||
_mszChannelIDRemind,
|
||||
_mszChannelNameRemind,
|
||||
NotificationManager.IMPORTANCE_HIGH
|
||||
);
|
||||
channel.setDescription("Critical reminders");
|
||||
channel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM), null);
|
||||
channel.enableVibration(true);
|
||||
channel.setVibrationPattern(new long[]{100, 200, 300, 400});
|
||||
channel.setBypassDnd(true);
|
||||
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
|
||||
mNotificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
|
||||
// 创建并发送服务通知
|
||||
//
|
||||
public void createForegroundNotification(ControlCenterService service, NotificationMessage notificationMessage) {
|
||||
//创建Notification,传入Context和channelId
|
||||
Intent intent = new Intent();//这个intent会传给目标,可以使用getIntent来获取
|
||||
intent.setPackage(service.getPackageName());
|
||||
//LogUtils.d(TAG, "mService.getPackageName() : " + service.getPackageName());
|
||||
intent.setClass(service, MainActivity.class);
|
||||
//LogUtils.d(TAG, "MainActivity.class.getName() : " + MainActivity.class.getName());
|
||||
//这里放一个count用来区分每一个通知
|
||||
//intent.putExtra("intent", "intent--->" + count);//这里设置一个数据,带过去
|
||||
|
||||
//参数1:context 上下文对象
|
||||
//参数2:发送者私有的请求码(Private request code for the sender)
|
||||
//参数3:intent 意图对象
|
||||
//参数4:必须为FLAG_ONE_SHOT,FLAG_NO_CREATE,FLAG_CANCEL_CURRENT,FLAG_UPDATE_CURRENT,中的一个
|
||||
//mForegroundPendingIntent = PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
mForegroundPendingIntent = PendingIntent.getActivity(service,
|
||||
1, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
||||
} else {
|
||||
mForegroundPendingIntent = PendingIntent.getActivity(service,
|
||||
1, intent, PendingIntent.FLAG_IMMUTABLE);
|
||||
}
|
||||
|
||||
mForegroundNotification = new Notification.Builder(service, _mszChannelIDService)
|
||||
.setAutoCancel(true)
|
||||
.setContentTitle(notificationMessage.getTitle())
|
||||
.setContentText(notificationMessage.getContent())
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setSmallIcon(R.drawable.ic_launcher)
|
||||
//设置红色
|
||||
.setColor(Color.parseColor("#F00606"))
|
||||
.setLargeIcon(BitmapFactory.decodeResource(service.getResources(), R.drawable.ic_launcher))
|
||||
.setContentIntent(mForegroundPendingIntent)
|
||||
.build();
|
||||
|
||||
setForegroundNotificationRemoteViews(service, notificationMessage);
|
||||
service.startForeground(_mnServiceNotificationID, mForegroundNotification);
|
||||
}
|
||||
|
||||
void initmrvRemindNotificationView(ControlCenterService service, NotificationMessage notificationMessage) {
|
||||
mrvRemindNotificationView = new RemoteViews(service.getPackageName(), R.layout.view_remindnotification);
|
||||
mrvRemindNotificationView.setTextViewText(R.id.viewremindnotificationTextView1, notificationMessage.getTitle());
|
||||
String szRemindMSG = notificationMessage.getRemindMSG();
|
||||
//LogUtils.d(TAG, "szRemindMSG : " + szRemindMSG);
|
||||
//mrvRemindNotificationView.setTextViewText(R.id.remoteviewTextView2, szRemindMSG);
|
||||
if (szRemindMSG != null) {
|
||||
if (szRemindMSG.trim().equals("-")) {
|
||||
//LogUtils.d(TAG, "-");
|
||||
mrvRemindNotificationView.setViewVisibility(R.id.remoteviewCharge, View.GONE);
|
||||
mrvRemindNotificationView.setViewVisibility(R.id.remoteviewUsege, View.VISIBLE);
|
||||
} else if (szRemindMSG.trim().equals("+")) {
|
||||
//LogUtils.d(TAG, "+");
|
||||
mrvRemindNotificationView.setViewVisibility(R.id.remoteviewUsege, View.GONE);
|
||||
mrvRemindNotificationView.setViewVisibility(R.id.remoteviewCharge, View.VISIBLE);
|
||||
}
|
||||
mrvRemindNotificationView.setImageViewResource(R.id.remoteviewImageView1, R.drawable.ic_launcher);
|
||||
//给我remoteViews上的控件tv_content添加监听事件
|
||||
//remoteViews.setOnClickPendingIntent(R.id.remoteviewLinearLayout1, pi);
|
||||
//return mrvServiceNotificationView;
|
||||
}
|
||||
}
|
||||
|
||||
void initmrvServiceNotificationView(ControlCenterService service, NotificationMessage notificationMessage) {
|
||||
mrvServiceNotificationView = new RemoteViews(service.getPackageName(), R.layout.view_servicenotification);
|
||||
mrvServiceNotificationView.setTextViewText(R.id.remoteviewTextView1, notificationMessage.getTitle());
|
||||
//String szRemindMSG = notificationMessage.getRemindMSG();
|
||||
//mrvServiceNotificationView.setTextViewText(R.id.remoteviewTextView2, szRemindMSG);
|
||||
//rvServiceNotificationView.setTextViewText(R.id.remoteviewTextView3, notificationMessage.getContent() + Integer.toString(nTest));
|
||||
mrvServiceNotificationView.setTextViewText(R.id.remoteviewTextView3, notificationMessage.getContent());
|
||||
mrvServiceNotificationView.setImageViewResource(R.id.remoteviewImageView1, R.drawable.ic_launcher);
|
||||
//给我remoteViews上的控件tv_content添加监听事件
|
||||
//remoteViews.setOnClickPendingIntent(R.id.remoteviewLinearLayout1, pi);
|
||||
//return mrvServiceNotificationView;
|
||||
}
|
||||
|
||||
void setForegroundNotificationRemoteViews(ControlCenterService service, NotificationMessage notificationMessage) {
|
||||
initmrvServiceNotificationView(service, notificationMessage);
|
||||
mForegroundNotification.contentView = mrvServiceNotificationView;
|
||||
mForegroundNotification.bigContentView = mrvServiceNotificationView;
|
||||
}
|
||||
|
||||
void setRemindNotificationRemoteViews(ControlCenterService service, NotificationMessage notificationMessage) {
|
||||
initmrvRemindNotificationView(service, notificationMessage);
|
||||
mRemindNotification.contentView = mrvRemindNotificationView;
|
||||
mRemindNotification.bigContentView = mrvRemindNotificationView;
|
||||
}
|
||||
|
||||
// 更新服务通知
|
||||
//
|
||||
public void updateForegroundNotification(ControlCenterService service, NotificationMessage notificationMessage) {
|
||||
setForegroundNotificationRemoteViews(service, notificationMessage);
|
||||
mNotificationManager.notify(_mnServiceNotificationID, mForegroundNotification);
|
||||
|
||||
}
|
||||
|
||||
// 创建并发送电量提醒通知
|
||||
//
|
||||
public void updateRemindNotification(ControlCenterService service, NotificationMessage notificationMessage) {
|
||||
//LogUtils.d(TAG, "updateRemindNotification : " + notificationMessage.getRemindMSG());
|
||||
setRemindNotificationRemoteViews(service, notificationMessage);
|
||||
mNotificationManager.notify(_mnRemindNotificationID, mRemindNotification);
|
||||
}
|
||||
|
||||
public void createRemindNotification(ControlCenterService service, NotificationMessage notificationMessage) {
|
||||
//LogUtils.d(TAG, "notificationMessage : " + notificationMessage.getRemindMSG());
|
||||
//创建Notification,传入Context和channelId
|
||||
Intent intent = new Intent();//这个intent会传给目标,可以使用getIntent来获取
|
||||
intent.setPackage(service.getPackageName());
|
||||
intent.setClass(service, MainActivity.class);
|
||||
//这里放一个count用来区分每一个通知
|
||||
//intent.putExtra("intent", "intent--->" + count);//这里设置一个数据,带过去
|
||||
|
||||
//参数1:context 上下文对象
|
||||
//参数2:发送者私有的请求码(Private request code for the sender)
|
||||
//参数3:intent 意图对象
|
||||
//参数4:必须为FLAG_ONE_SHOT,FLAG_NO_CREATE,FLAG_CANCEL_CURRENT,FLAG_UPDATE_CURRENT,中的一个
|
||||
//mRemindPendingIntent = PendingIntent.getActivity(mService, 1, intent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
mRemindPendingIntent = PendingIntent.getActivity(service,
|
||||
1, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
||||
} else {
|
||||
mRemindPendingIntent = PendingIntent.getActivity(service,
|
||||
1, intent, PendingIntent.FLAG_IMMUTABLE);
|
||||
}
|
||||
|
||||
mRemindNotification = new Notification.Builder(service, _mszChannelIDRemind)
|
||||
.setAutoCancel(true)
|
||||
.setContentTitle(notificationMessage.getTitle())
|
||||
.setContentText(notificationMessage.getContent())
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setSmallIcon(R.drawable.ic_launcher)
|
||||
//设置红色
|
||||
.setColor(Color.parseColor("#F00606"))
|
||||
.setLargeIcon(BitmapFactory.decodeResource(service.getResources(), R.drawable.ic_launcher))
|
||||
.setContentIntent(mRemindPendingIntent)
|
||||
.build();
|
||||
setRemindNotificationRemoteViews(service, notificationMessage);
|
||||
}
|
||||
|
||||
public static void cancelRemindNotification(Context context){
|
||||
// 获取 NotificationManager 实例
|
||||
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
// 撤回指定 ID 的通知栏消息
|
||||
notificationManager.cancel(_mnRemindNotificationID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package cc.winboll.studio.powerbell.utils;
|
||||
|
||||
import cc.winboll.studio.powerbell.model.BatteryInfoBean;
|
||||
import cc.winboll.studio.powerbell.models.BatteryInfoBean;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class StringUtils {
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class UriUtil {
|
||||
public class UriUtils {
|
||||
|
||||
public static final String TAG = "UriUtil";
|
||||
|
||||
@@ -14,7 +14,7 @@ import android.widget.RelativeLayout;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import cc.winboll.studio.powerbell.App;
|
||||
import cc.winboll.studio.powerbell.model.BackgroundBean;
|
||||
import cc.winboll.studio.powerbell.models.BackgroundBean;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical|center_horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:scaleType="centerCrop"
|
||||
android:id="@+id/dialogbackgroundpicturepreviewImageView1"/>
|
||||
<cc.winboll.studio.powerbell.views.BackgroundView
|
||||
android:orientation="vertical"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="200dp"
|
||||
android:id="@+id/backgroundview"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user