commit 00c4b1dc9eebd0d4986c200c17f6a4db3f4f6da1 Author: 如果当时 <1017848709@qq.com> Date: Sat Nov 28 15:37:57 2020 +0800 初始备份。 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..fb7f4a8 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..5bd12c5 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..9422e84 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..23d2272 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,2 @@ +2020-11-28 V1.0 +暂无。 \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..b6c4a6c --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,39 @@ +plugins { + id 'com.android.application' +} + +android { + compileSdkVersion 29 + buildToolsVersion "30.0.2" + + defaultConfig { + applicationId "com.itrycn.tellmenotice" + minSdkVersion 23 + targetSdkVersion 29 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:2.0.1' + testImplementation 'junit:junit:4.+' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/itrycn/tellmenotice/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/itrycn/tellmenotice/ExampleInstrumentedTest.java new file mode 100644 index 0000000..bccbd47 --- /dev/null +++ b/app/src/androidTest/java/com/itrycn/tellmenotice/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.itrycn.tellmenotice; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.itrycn.tellmenotice", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..b5ce804 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/itrycn/tellmenotice/Alarm.java b/app/src/main/java/com/itrycn/tellmenotice/Alarm.java new file mode 100644 index 0000000..6fc5b3c --- /dev/null +++ b/app/src/main/java/com/itrycn/tellmenotice/Alarm.java @@ -0,0 +1,93 @@ +package com.itrycn.tellmenotice; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; + +import java.util.Calendar; +import java.util.TimeZone; + +import static android.content.Context.ALARM_SERVICE; + +public class Alarm { + private Calendar mCalendar; + /** + * + */ + private Context mContext; + /** + * 开启提醒 + */ + private void startRemind(){ + + //得到日历实例,主要是为了下面的获取时间 + mCalendar = Calendar.getInstance(); + mCalendar.setTimeInMillis(System.currentTimeMillis()); + + //获取当前毫秒值 + long systemTime = System.currentTimeMillis(); + + //是设置日历的时间,主要是让日历的年月日和当前同步 + mCalendar.setTimeInMillis(System.currentTimeMillis()); + // 这里时区需要设置一下,不然可能个别手机会有8个小时的时间差 + mCalendar.setTimeZone(TimeZone.getTimeZone("GMT+8")); + //设置在几点提醒 设置的为13点 + mCalendar.set(Calendar.HOUR_OF_DAY, 7); + //设置在几分提醒 设置的为25分 + mCalendar.set(Calendar.MINUTE, 58); + //下面这两个看字面意思也知道 + mCalendar.set(Calendar.SECOND, 0); + mCalendar.set(Calendar.MILLISECOND, 0); + + //上面设置的就是13点25分的时间点 + + //获取上面设置的13点25分的毫秒值 + long selectTime = mCalendar.getTimeInMillis(); + + // 如果当前时间大于设置的时间,那么就从第二天的设定时间开始 + if(systemTime > selectTime) { + mCalendar.add(Calendar.DAY_OF_MONTH, 1); + } + + //AlarmReceiver.class为广播接受者 + Intent intent = new Intent(mContext, BootBroadcastReceiver.class); + PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0); + //得到AlarmManager实例 + AlarmManager am = (AlarmManager)mContext.getSystemService(ALARM_SERVICE); + + //**********注意!!下面的两个根据实际需求任选其一即可********* + + /** + * 单次提醒 + * mCalendar.getTimeInMillis() 上面设置的13点25分的时间点毫秒值 + */ + am.set(AlarmManager.RTC_WAKEUP, mCalendar.getTimeInMillis(), pi); + + /** + * 重复提醒 + * 第一个参数是警报类型;下面有介绍 + * 第二个参数网上说法不一,很多都是说的是延迟多少毫秒执行这个闹钟,但是我用的刷了MIUI的三星手机的实际效果是与单次提醒的参数一样,即设置的13点25分的时间点毫秒值 + * 第三个参数是重复周期,也就是下次提醒的间隔 毫秒值 我这里是一天后提醒 + */ + am.setRepeating(AlarmManager.RTC_WAKEUP, mCalendar.getTimeInMillis(), (1000 * 60 * 60 * 24), pi); + + } + + + /** + * 关闭提醒 + */ + private void stopRemind(){ + + Intent intent = new Intent(mContext, BootBroadcastReceiver.class); + PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, + intent, 0); + AlarmManager am = (AlarmManager)mContext.getSystemService(ALARM_SERVICE); + //取消警报 + am.cancel(pi); + //Toast.makeText(this, "关闭了提醒", Toast.LENGTH_SHORT).show(); + + } + +} diff --git a/app/src/main/java/com/itrycn/tellmenotice/BootBroadcastReceiver.java b/app/src/main/java/com/itrycn/tellmenotice/BootBroadcastReceiver.java new file mode 100644 index 0000000..d7ffb39 --- /dev/null +++ b/app/src/main/java/com/itrycn/tellmenotice/BootBroadcastReceiver.java @@ -0,0 +1,25 @@ +package com.itrycn.tellmenotice; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.media.AudioManager; +import android.widget.Toast; + +import java.util.Calendar; + +public class BootBroadcastReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent){ + if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED) || intent.getAction().equals("android.intent.action.QUICKBOOT_POWERON")){ //开机广播 + Toast.makeText(context, "服务启动成功", Toast.LENGTH_SHORT).show(); + //Intent intent3 = new Intent(context,MainActivity.class); + //intent3.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + //context.startActivity(intent3); + Intent intent2 = new Intent(context,NoticeService.class); + intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startService(intent2); + } + + } +} diff --git a/app/src/main/java/com/itrycn/tellmenotice/FloatView.java b/app/src/main/java/com/itrycn/tellmenotice/FloatView.java new file mode 100644 index 0000000..63a9d1b --- /dev/null +++ b/app/src/main/java/com/itrycn/tellmenotice/FloatView.java @@ -0,0 +1,158 @@ +package com.itrycn.tellmenotice; + +import android.app.Notification; +import android.app.PendingIntent; +import android.content.Context; +import android.graphics.Color; +import android.graphics.PixelFormat; +import android.provider.Settings; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.WindowManager; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import java.text.SimpleDateFormat; +import java.util.Date; + +public class FloatView implements View.OnTouchListener { + private Context mContext; + private static WindowManager mWm; + private WindowManager.LayoutParams mWinParams; + private View view; + private float mDownX; + private float mDownY; + private float mMoveX; + private float mMoveY; + + public FloatView(Context context) { + this.mContext = context; + + view = View.inflate(mContext, R.layout.float_tip, null); + + mWm = (WindowManager) context.getApplicationContext().getSystemService( + Context.WINDOW_SERVICE); + + mWinParams = new WindowManager.LayoutParams(); + //mWinParams.height = WindowManager.LayoutParams.MATCH_PARENT; + //mWinParams.width = WindowManager.LayoutParams.MATCH_PARENT; + mWinParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; + mWinParams.format = PixelFormat.TRANSLUCENT; + // mParams.windowAnimations = + // com.android.internal.R.style.Animation_Toast;//动画设置 + //在小米手机的 5.0系统中,需要设置 type为 TYPE_TOAST,才能显示 + mWinParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; + mWinParams.x = 0; + mWinParams.y = 0; + mWinParams.width = dip2px(mContext,250); + mWinParams.height = dip2px(mContext,170); + view.setOnTouchListener(this); + } + /** + * 根据手机的分辨率从 dp 的单位 转成为 px(像素) + */ + public static int dip2px(Context context, float dpValue) { + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (dpValue * scale + 0.5f); + } + public void show() { + mWm.addView(view, mWinParams); + } + public void showFloatingWindow(Notification notice, String Title, String Content) { + showFloatingWindow(notice,Title,Content,-1); + } + public void showFloatingWindow(Notification notice, String Title, String Content, int TitleBackColor) { + if (Settings.canDrawOverlays(mContext)) { + LayoutInflater layoutInflater = LayoutInflater.from(mContext); + ImageView image=view.findViewById(R.id.IdIcon); + image.setImageIcon(notice.getSmallIcon()); + image.setOnClickListener(v -> { + //打开通知栏的intent,即打开对应的聊天界面 + PendingIntent pendingIntent = notice.contentIntent; + try { + pendingIntent.send(); + if (mWm != null) mWm.removeView(view); + } catch (PendingIntent.CanceledException e) { + Toast.makeText(mContext, "打开出错->"+e.getMessage(), Toast.LENGTH_SHORT).show(); + e.printStackTrace(); + } + }); + //image.setOnTouchListener(new FloatingOnTouchListener()); + ImageView image_close=view.findViewById(R.id.IdClose); + image_close.setImageResource(R.drawable.close); + image_close.setOnClickListener(v -> { + if (mWm != null) mWm.removeView(view); + }); + TextView idTitle = view.findViewById(R.id.IdTitle); + if(TitleBackColor!=-1) + { + image.setBackgroundColor(TitleBackColor); + idTitle.setBackgroundColor(TitleBackColor); + image_close.setBackgroundColor(TitleBackColor); + } + //idTitle.setOnTouchListener(new FloatingOnTouchListener()); + TextView idContent = view.findViewById(R.id.IdContent); + TextView idPostTime = view.findViewById(R.id.IdPostTime); + idTitle.setText(Title); + idContent.setText(Content); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");// HH:mm:ss + //获取当前时间 + Date date = new Date(System.currentTimeMillis()); + idPostTime.setText("时间:"+simpleDateFormat.format(date)); + //idContent.setOnTouchListener(new FloatingOnTouchListener()); + mWm.addView(view, mWinParams); + } + } + public void hide(){ + if(mWm != null){ + mWm.removeView(view); + } + } + + @Override + public boolean onTouch(View view, MotionEvent event) { + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + + mDownX = event.getRawX(); + mDownY = event.getRawY(); + + break; + case MotionEvent.ACTION_MOVE: + + /** + * 最为关键的就是拖动业务的坐标位置的计算 + */ + + mMoveX = event.getRawX(); + mMoveY = event.getRawY(); + + float difX = (mMoveX - mDownX); + float difY = (mMoveY - mDownY); + + mWinParams.x += difX; + mWinParams.y += difY; + mWm.updateViewLayout(view, mWinParams); + + mDownX = mMoveX; + mDownY = mMoveY; + + break; + case MotionEvent.ACTION_UP: + + break; + + default: + break; + } + + // 消费触摸事件 + return true; + } + +} diff --git a/app/src/main/java/com/itrycn/tellmenotice/MainActivity.java b/app/src/main/java/com/itrycn/tellmenotice/MainActivity.java new file mode 100644 index 0000000..3c35db3 --- /dev/null +++ b/app/src/main/java/com/itrycn/tellmenotice/MainActivity.java @@ -0,0 +1,136 @@ +package com.itrycn.tellmenotice; + +import androidx.appcompat.app.AppCompatActivity; + +import android.content.ActivityNotFoundException; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.media.AudioManager; +import android.net.Uri; +import android.os.Bundle; +import android.provider.Settings; +import android.text.TextUtils; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import java.util.Calendar; + +public class MainActivity extends AppCompatActivity { + ScreenListener screenlistener; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + if(!isNotificationListenersEnabled()) + { + gotoNotificationAccessSetting(MainActivity.this); + } + Intent intent2 = new Intent(MainActivity.this,NoticeService.class); + startService(intent2); + startFloatingButtonService(); + TextView tv=findViewById(R.id.IdState); + tv.setText("睿元智能管家,你的私人管家。\n" + + "1.帮你监控系统通知,自动筛选重要通知。\n" + + "2.不同通知展现不同的提醒界面和声音。\n" + + "3.支持免打扰功能,深夜自动免打扰。"); + ScreenListener screenlistener = new ScreenListener(this); + screenlistener.begin(new ScreenListener.ScreenStateListener() { + + @Override + public void onUserPresent() { + //Log.e("onUserPresent", "onUserPresent"); + } + + @Override + public void onScreenOn() { + //Log.e("onScreenOn", "onScreenOn"); + } + + @Override + public void onScreenOff() { + //region 关闭屏幕自动将通知音量调整到最大 + Calendar c = Calendar.getInstance(); + int hour = c.get(Calendar.HOUR_OF_DAY); // 时 + if(hour>=23 || hour<7) {return; } //23点到早上7点,免打扰时间段 + AudioManager audioManager = (AudioManager) MainActivity.this.getSystemService(Context.AUDIO_SERVICE); + int NoticeVolume= audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION); + int NoticeMaxVolume= audioManager.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION); + if(NoticeVolume= Build.VERSION_CODES.O) { + // layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; + // } else { + // layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE; + //} + //layoutParams.format = PixelFormat.TRANSLUCENT; + //layoutParams.gravity = Gravity.LEFT | Gravity.TOP; + //layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; + // layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT; + // layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT; + // layoutParams.x = 300; + // layoutParams.y = 300; + } + @Override + public void onDestroy() { + sp.unload(MP3_notice); + sp.unload(MP3_mm); + sp.unload(MP3_Ring); + sp.unload(MP3_kuaidi); + sp.unload(MP3_Dingding); + super.onDestroy(); + } + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.i("KEVIN", "Service is started" + "-----"); + // + //data = intent.getStringExtra("data"); + return super.onStartCommand(intent, flags, startId); + } + SoundPool sp; + int MP3_notice; + int MP3_mm; + int MP3_Ring; + int MP3_kuaidi; + int MP3_Dingding; + String Last_packageName=""; + String Last_Title=""; + String Last_Content=""; + long Last_UpdateTime=0; + /** + * 播放声音 + * @param SoundId 声音id + * @param loop 循环次数 + * @param DNDPlay 是否在免打扰时依旧播放 + */ + private void PlaySound(int SoundId,int loop,boolean DNDPlay) + { + if(!DNDPlay) //如果该声音未开启免打扰时允许播放,则检查当前是否属于免打扰 + { + Calendar c = Calendar.getInstance(); + //int year = c.get(Calendar.YEAR); // 获取当前年份 + //int month = c.get(Calendar.MONTH) + 1; // 获取当前月份 + //int day = c.get(Calendar.DAY_OF_MONTH); // 获取当日 + int dayOfWeek = c.get(Calendar.DAY_OF_WEEK); // 获取当前日期的星期,1 表示星期日、用 2 表示星期一 + int hour = c.get(Calendar.HOUR_OF_DAY); // 时 + //int minute = c.get(Calendar.MINUTE); // 分 + if(hour>=23 || hour<7) {return; } //23点到早上7点,免打扰时间段 + //if(hour>=23 && hour<7) {return; } + } + sp.play(SoundId, 1f, 1.0f,1,loop,1); + } + private long LastDoorRingTime=0; + @Override + public void onNotificationPosted(StatusBarNotification sbn) { + // super.onNotificationPosted(sbn); + try { + Notification notice=sbn.getNotification(); + if(notice==null){return;} + Bundle extras = notice.extras; + String packageName=sbn.getPackageName(); + String Title=""; + String Content=""; + //有些通知不能解析出TEXT内容,这里做个信息能判断 + if (extras == null && notice.tickerText!=null) { + Content=notice.tickerText.toString(); + } + else + { + Title=extras.getString(Notification.EXTRA_TITLE); + Content=extras.getString(Notification.EXTRA_TEXT); + } + if(Title==null){Title="";} + if(Content==null){Content="";} + if(Title.length()==0 && Content.length()==0){return;} + boolean haveTip=false;//该消息是否需要提醒。 + Calendar c = Calendar.getInstance(); + long NowTime=c.getTime().getTime(); + if(packageName.equals(Last_packageName) + && Title.equals(Last_Title) + && Content.equals(Last_Content) + && Last_UpdateTime+6000>NowTime + ) + { + return; + } + if(packageName.equals("com.tencent.mm")) //如果是微信 + { + //region 微信中有人提到自己 + String[] strArr = "鑫之风;大头;凤鑫;风鑫;封信;风兴;奉新;凤兴;阿香;凤新".split(";"); + boolean haveInfo=false; + for (int i = 0; i < strArr.length; ++i){ + if(Content.contains(strArr[i])) + { + FloatView fv=new FloatView(this); + fv.showFloatingWindow(notice,Title,Content); + //showFloatingWindow(notice,Title,Content); + PlaySound(MP3_mm,0,false); + haveInfo=true; + haveTip=true; + break; + } + } + //endregion + if(!haveInfo) + { + if(Title.contains("球球") || Content.contains("球球")) { + String[] strArr2 = "球球独家;口令;拍下;http;拍第;体验;福利;一单;元抢;内部;复制打开;漏洞;好评;0元;抢到;免单;独家".split(";"); + for (int i = 0; i < strArr2.length; ++i) { + if (Content.contains(strArr2[i])) { + FloatView fv = new FloatView(this); + fv.showFloatingWindow(notice, Title, Content, Color.parseColor("#FF0000")); + //showFloatingWindow(notice,Title,Content); + PlaySound(MP3_Dingding, 0, false); + haveTip=true; + break; + } + } + } + } + } + else if(packageName.equals("com.xiaomi.smarthome")) //如果是米家app + { + //region 米家app处理方式 + if(Title.equals("GroupSummary") ||Content.equals("GroupSummary")){return;}; + if(Title.contains("按门铃") || Content.contains("按门铃")) + { + if(LastDoorRingTime+60000>=NowTime){return;} //如果1分钟内有新的门铃提醒,则自动忽略 + LastDoorRingTime=c.getTime().getTime(); + FloatView fv=new FloatView(this); + fv.showFloatingWindow(notice,Content,Title, Color.parseColor("#02BD9D")); + PlaySound(MP3_Ring,2,false); + haveTip=true; + } + else + { + FloatView fv=new FloatView(this); + if(Title.equals("自动化通知")) + { + fv.showFloatingWindow(notice,Title, Content, Color.parseColor("#02BD9D")); + } + else { + if(Title.length()>=Content.length()) { + fv.showFloatingWindow(notice, Content, Title, Color.parseColor("#02BD9D")); + } + else { + fv.showFloatingWindow(notice,Title, Content, Color.parseColor("#02BD9D")); + } + } + haveTip=true; + PlaySound(MP3_Dingding,0,false); + } + //endregion + } + else if(packageName.equals("com.android.mms")) //如果是短信 + { + //region 短信中提取快递获取信息 + String[] strArr = "保安室;快递室;派送成功;代收;".split(";"); + for (int i = 0; i < strArr.length; ++i){ + if(Title.contains(strArr[i]) || Content.contains(strArr[i])) + { + FloatView fv=new FloatView(this); + fv.showFloatingWindow(notice,Title,Content); + PlaySound(MP3_kuaidi,0,false); + haveTip=true; + break; + } + } + //endregion + } + else if(packageName.equals("com.jingyao.easybike") //哈罗出行 + || packageName.equals("com.sdu.didi.psnger") //滴滴出行 + || packageName.equals("com.didapinche.booking")) //嘀嗒出行 + { + if(Title.contains("正在运行")){return;} + if(Title.contains("哈啰顺风车运行中") || Content.contains("哈啰顺风车运行中")){return;} + if(Title.contains("顺风车出行中") || Content.contains("顺风车出行中")){return;} + //region 如果是顺风车线路 + FloatView fv=new FloatView(this); + if(packageName.equals("com.jingyao.easybike")) + { + fv.showFloatingWindow(notice,Title, Content, Color.parseColor("#0391FF")); + } + else if(packageName.equals("com.sdu.didi.psnger")) + { + fv.showFloatingWindow(notice,Title, Content, Color.parseColor("#F8934C")); + } + else if(packageName.equals("com.didapinche.booking")) + { + fv.showFloatingWindow(notice,Title, Content, Color.parseColor("#FED051")); + } + else { + fv.showFloatingWindow(notice, Title, Content); + } + haveTip=true; + PlaySound(MP3_Dingding,0,false); + //endregion + } + else if(packageName.equals("com.taobao.taobao") + || packageName.equals("com.jingdong.app.mall") + || packageName.equals("com.xunmeng.pinduoduo")) //如果是淘宝或京东或拼多多 + { + //region 判断是否是物流信息 + String[] strArr = "签收;发货;派送;派件;".split(";"); + for (int i = 0; i < strArr.length; ++i){ + if(Title.contains(strArr[i]) || Content.contains(strArr[i])) + { + FloatView fv=new FloatView(this); + fv.showFloatingWindow(notice,Title,Content, Color.parseColor("#FD5C02")); + PlaySound(MP3_Dingding,0,false); + haveTip=true; + break; + } + } + //endregion + } + //else { + // Toast.makeText(this,packageName+"->"+Title+"-"+Content, Toast.LENGTH_SHORT).show(); + // sp.play(MP3_notice, 1f, 1.0f, 1, 0, 1); + //} + if(haveTip) + { + Last_packageName=packageName; + Last_Title=Title; + Last_Content=Content; + Last_UpdateTime=NowTime; + } + } catch (Exception e) { + Toast.makeText(this, "不可解析的通知->"+e.getMessage(), Toast.LENGTH_SHORT).show(); + } + } + private void showFloatingWindow(Notification notice, String Title, String Content) { + if (Settings.canDrawOverlays(this)) { + LayoutInflater layoutInflater = LayoutInflater.from(this); + View displayView = layoutInflater.inflate(R.layout.float_tip, null); + displayView.setOnTouchListener(new FloatingOnTouchListener()); + ImageView image=displayView.findViewById(R.id.IdIcon); + image.setImageIcon(notice.getSmallIcon()); + image.setOnClickListener(v -> { + //打开通知栏的intent,即打开对应的聊天界面 + PendingIntent pendingIntent = notice.contentIntent; + try { + pendingIntent.send(); + if (windowManager != null) windowManager.removeView(displayView); + } catch (PendingIntent.CanceledException e) { + Toast.makeText(this, "打开出错->"+e.getMessage(), Toast.LENGTH_SHORT).show(); + e.printStackTrace(); + } + }); + //image.setOnTouchListener(new FloatingOnTouchListener()); + ImageView image_close=displayView.findViewById(R.id.IdClose); + image_close.setImageResource(R.drawable.close); + image_close.setOnClickListener(v -> { + if (windowManager != null) windowManager.removeView(displayView); + }); + TextView idTitle = displayView.findViewById(R.id.IdTitle); + //idTitle.setOnTouchListener(new FloatingOnTouchListener()); + TextView idContent = displayView.findViewById(R.id.IdContent); + TextView idPostTime = displayView.findViewById(R.id.IdPostTime); + idTitle.setText(Title); + idContent.setText(Content); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");// HH:mm:ss + //获取当前时间 + Date date = new Date(System.currentTimeMillis()); + idPostTime.setText("时间:"+simpleDateFormat.format(date)); + //idContent.setOnTouchListener(new FloatingOnTouchListener()); + windowManager.addView(displayView, layoutParams); + } + } + private class FloatingOnTouchListener implements View.OnTouchListener { + private int x; + private int y; + + @Override + public boolean onTouch(View view, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + x = (int) event.getRawX(); + y = (int) event.getRawY(); + break; + case MotionEvent.ACTION_MOVE: + int nowX = (int) event.getRawX(); + int nowY = (int) event.getRawY(); + int movedX = nowX - x; + int movedY = nowY - y; + x = nowX; + y = nowY; + layoutParams.x = layoutParams.x + movedX; + layoutParams.y = layoutParams.y + movedY; + windowManager.updateViewLayout(view, layoutParams); + break; + default: + break; + } + return false; + } + } +} diff --git a/app/src/main/java/com/itrycn/tellmenotice/ScreenListener.java b/app/src/main/java/com/itrycn/tellmenotice/ScreenListener.java new file mode 100644 index 0000000..9a3c364 --- /dev/null +++ b/app/src/main/java/com/itrycn/tellmenotice/ScreenListener.java @@ -0,0 +1,91 @@ +package com.itrycn.tellmenotice; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.PowerManager; + +public class ScreenListener { + private Context mContext; + private ScreenBroadcastReceiver mScreenReceiver; + private ScreenStateListener mScreenStateListener; + + public ScreenListener(Context context) { + mContext = context; + mScreenReceiver = new ScreenBroadcastReceiver(); + } + + /** + * screen状态广播接收者 + */ + private class ScreenBroadcastReceiver extends BroadcastReceiver { + private String action = null; + + @Override + public void onReceive(Context context, Intent intent) { + action = intent.getAction(); + if (Intent.ACTION_SCREEN_ON.equals(action)) { // 开屏 + mScreenStateListener.onScreenOn(); + } else if (Intent.ACTION_SCREEN_OFF.equals(action)) { // 锁屏 + mScreenStateListener.onScreenOff(); + } else if (Intent.ACTION_USER_PRESENT.equals(action)) { // 解锁 + mScreenStateListener.onUserPresent(); + } + } + } + + /** + * 开始监听screen状态 + * + * @param listener + */ + public void begin(ScreenStateListener listener) { + mScreenStateListener = listener; + registerListener(); + getScreenState(); + } + + /** + * 获取screen状态 + */ + private void getScreenState() { + PowerManager manager = (PowerManager) mContext + .getSystemService(Context.POWER_SERVICE); + if (manager.isScreenOn()) { + if (mScreenStateListener != null) { + mScreenStateListener.onScreenOn(); + } + } else { + if (mScreenStateListener != null) { + mScreenStateListener.onScreenOff(); + } + } + } + + /** + * 停止screen状态监听 + */ + public void unregisterListener() { + mContext.unregisterReceiver(mScreenReceiver); + } + + /** + * 启动screen状态广播接收器 + */ + private void registerListener() { + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_SCREEN_ON); + filter.addAction(Intent.ACTION_SCREEN_OFF); + filter.addAction(Intent.ACTION_USER_PRESENT); + mContext.registerReceiver(mScreenReceiver, filter); + } + + public interface ScreenStateListener {// 返回给调用者屏幕状态信息 + public void onScreenOn(); + + public void onScreenOff(); + + public void onUserPresent(); + } +} diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/borderline.xml b/app/src/main/res/drawable/borderline.xml new file mode 100644 index 0000000..3d52e23 --- /dev/null +++ b/app/src/main/res/drawable/borderline.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/close.png b/app/src/main/res/drawable/close.png new file mode 100644 index 0000000..0bf7aa9 Binary files /dev/null and b/app/src/main/res/drawable/close.png differ diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..22969f7 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,23 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/float_tip.xml b/app/src/main/res/layout/float_tip.xml new file mode 100644 index 0000000..da68d07 --- /dev/null +++ b/app/src/main/res/layout/float_tip.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..a571e60 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..61da551 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..c41dd28 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..db5080a Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..6dba46d Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..da31a87 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..15ac681 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..b216f2d Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..f25a419 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..e96783c Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/raw/chattip.mp3 b/app/src/main/res/raw/chattip.mp3 new file mode 100644 index 0000000..08e8b54 Binary files /dev/null and b/app/src/main/res/raw/chattip.mp3 differ diff --git a/app/src/main/res/raw/dingding.mp3 b/app/src/main/res/raw/dingding.mp3 new file mode 100644 index 0000000..a19b3ad Binary files /dev/null and b/app/src/main/res/raw/dingding.mp3 differ diff --git a/app/src/main/res/raw/kuaidi.mp3 b/app/src/main/res/raw/kuaidi.mp3 new file mode 100644 index 0000000..1482837 Binary files /dev/null and b/app/src/main/res/raw/kuaidi.mp3 differ diff --git a/app/src/main/res/raw/notice.mp3 b/app/src/main/res/raw/notice.mp3 new file mode 100644 index 0000000..fe204e1 Binary files /dev/null and b/app/src/main/res/raw/notice.mp3 differ diff --git a/app/src/main/res/raw/ring.mp3 b/app/src/main/res/raw/ring.mp3 new file mode 100644 index 0000000..71a1280 Binary files /dev/null and b/app/src/main/res/raw/ring.mp3 differ diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml new file mode 100644 index 0000000..7b9f8b9 --- /dev/null +++ b/app/src/main/res/values-night/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..8c73c3c --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + 智能管家 + 睿元智能管家,你的私人管家。\n1.可以帮你监控系统通知,自动筛选对你有用的内容。\n2.不同通知展现不同的提醒界面和声音。 + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..19c1847 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/app/src/test/java/com/itrycn/tellmenotice/ExampleUnitTest.java b/app/src/test/java/com/itrycn/tellmenotice/ExampleUnitTest.java new file mode 100644 index 0000000..2575c23 --- /dev/null +++ b/app/src/test/java/com/itrycn/tellmenotice/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.itrycn.tellmenotice; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..e65e0e8 --- /dev/null +++ b/build.gradle @@ -0,0 +1,24 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + repositories { + google() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:4.2.0-alpha15' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..52f5917 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,19 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app"s APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Automatically convert third-party libraries to use AndroidX +android.enableJetifier=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..f6b961f Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..ad86d40 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sat Oct 03 18:50:49 CST 2020 +distributionBase=GRADLE_USER_HOME +distributionUrl=https://services.gradle.org/distributions/gradle-6.7-bin.zip +distributionPath=wrapper/dists +zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..aed8b83 --- /dev/null +++ b/readme.md @@ -0,0 +1,10 @@ +# 简介 # +TellMeNotice是一款重要通知提醒软件,对于重要通知进行语音和悬浮窗弹窗提醒。 +- 微信中提到自己名字的消息进行语音和悬浮窗提醒。 +- 快递派送提醒。 +- 米家app消息优化弹窗,支持按门铃提醒。 +- 支持深夜免打扰。 +- 支持顺风车软件提醒。 + +# 运行环境 # +android5.0及以上 diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..3b085e4 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = "TellMeNotice" +include ':app'