diff --git a/README.md b/README.md index 9f167b2..7682a64 100644 --- a/README.md +++ b/README.md @@ -108,11 +108,11 @@ String ticker = "您有一条新通知"; String title = "冰冰"; ArrayList messageList = new ArrayList(); - messageList.add("文明,今晚有空吗?"); + messageList.add("Kelly,今晚有空吗?"); messageList.add("晚上跟我一起去玩吧?"); - messageList.add("怎么不回复我??我生气了!!"); + messageList.add("怎么不回复我?我生气了!!"); messageList.add("我真生气了!!!!!你听见了吗!"); - messageList.add("文明,别不理我!!!"); + messageList.add("Kelly,别不理我!!!"); String content = "[" + messageList.size() + "条]" + title + ": " + messageList.get(0); //实例化工具类,并且调用接口 NotifyUtil notify3 = new NotifyUtil(mContext, 3); @@ -262,7 +262,7 @@ int largeIcon = R.drawable.fbb_largeicon; String ticker = "您有一条新通知"; String title = "范冰冰"; - String content = "文明,今晚在希尔顿酒店2016号房哈"; + String content = "kelly,今晚在希尔顿酒店2016号房哈"; Intent intent = new Intent(mContext, OtherActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(mContext, diff --git a/build.gradle b/build.gradle index 5bd4f52..79baff4 100644 --- a/build.gradle +++ b/build.gradle @@ -3,9 +3,10 @@ buildscript { repositories { jcenter() + google() } dependencies { - classpath 'com.android.tools.build:gradle:1.3.0' + classpath 'com.android.tools.build:gradle:3.1.3' // } @@ -14,6 +15,7 @@ buildscript { allprojects { repositories { jcenter() + google() } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f23df6e..fc5468e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip diff --git a/library/build.gradle b/library/build.gradle index 0402f44..0596555 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 23 - buildToolsVersion "23.0.2" + compileSdkVersion 26 + buildToolsVersion "26.0.3" defaultConfig { - minSdkVersion 14 - targetSdkVersion 23 + minSdkVersion 15 + targetSdkVersion 26 versionCode 1 versionName "1.0" } @@ -21,5 +21,5 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' - compile 'com.android.support:appcompat-v7:23.1.1' + compile 'com.android.support:appcompat-v7:26.1.0' } diff --git a/library/src/main/java/com/wenming/library/NotifyUtil.java b/library/src/main/java/com/wenming/library/NotifyUtil.java index c1da124..ecd8601 100644 --- a/library/src/main/java/com/wenming/library/NotifyUtil.java +++ b/library/src/main/java/com/wenming/library/NotifyUtil.java @@ -3,6 +3,7 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.app.Notification; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; @@ -24,7 +25,7 @@ public class NotifyUtil { private int NOTIFICATION_ID; private NotificationManager nm; private Notification notification; - private NotificationCompat.Builder cBuilder; + private Notification.Builder cBuilder; private Notification.Builder nBuilder; private Context mContext; @@ -33,9 +34,21 @@ public NotifyUtil(Context context, int ID) { this.NOTIFICATION_ID = ID; mContext = context; // 获取系统服务来初始化对象 - nm = (NotificationManager) mContext - .getSystemService(Activity.NOTIFICATION_SERVICE); - cBuilder = new NotificationCompat.Builder(mContext); + nm = (NotificationManager) mContext.getSystemService(Activity.NOTIFICATION_SERVICE); + cBuilder = new Notification.Builder(mContext); + + if (Build.VERSION.SDK_INT >= 26) { + //当sdk版本大于26 + String id = "channel_1"; + String description = "143"; + int importance = NotificationManager.IMPORTANCE_LOW; + NotificationChannel channel = new NotificationChannel(id, description, importance); + channel.enableLights(true); + channel.enableVibration(true); + nm.createNotificationChannel(channel); + cBuilder = new Notification.Builder(mContext, id); + cBuilder.setCategory(Notification.CATEGORY_MESSAGE); + } } /** @@ -62,25 +75,25 @@ private void setCompatBuilder(PendingIntent pendingIntent, int smallIcon, String cBuilder.setContentText(content);// 设置通知中心中的内容 cBuilder.setWhen(System.currentTimeMillis()); - /* + /* * 将AutoCancel设为true后,当你点击通知栏的notification后,它会自动被取消消失, - * 不设置的话点击消息后也不清除,但可以滑动删除 - */ + * 不设置的话点击消息后也不清除,但可以滑动删除 + */ cBuilder.setAutoCancel(true); // 将Ongoing设为true 那么notification将不能滑动删除 // notifyBuilder.setOngoing(true); /* * 从Android4.1开始,可以通过以下方法,设置notification的优先级, - * 优先级越高的,通知排的越靠前,优先级低的,不会在手机最顶部的状态栏显示图标 - */ - cBuilder.setPriority(NotificationCompat.PRIORITY_MAX); + * 优先级越高的,通知排的越靠前,优先级低的,不会在手机最顶部的状态栏显示图标 + */ + cBuilder.setPriority(Notification.PRIORITY_MAX); /* * Notification.DEFAULT_ALL:铃声、闪光、震动均系统默认。 - * Notification.DEFAULT_SOUND:系统默认铃声。 - * Notification.DEFAULT_VIBRATE:系统默认震动。 - * Notification.DEFAULT_LIGHTS:系统默认闪光。 - * notifyBuilder.setDefaults(Notification.DEFAULT_ALL); - */ + * Notification.DEFAULT_SOUND:系统默认铃声。 + * Notification.DEFAULT_VIBRATE:系统默认震动。 + * Notification.DEFAULT_LIGHTS:系统默认闪光。 + * notifyBuilder.setDefaults(Notification.DEFAULT_ALL); + */ int defaults = 0; if (sound) { @@ -116,7 +129,7 @@ private void setBuilder(PendingIntent pendingIntent, int smallIcon, String ticke nBuilder.setTicker(ticker); nBuilder.setWhen(System.currentTimeMillis()); - nBuilder.setPriority(NotificationCompat.PRIORITY_MAX); + nBuilder.setPriority(Notification.PRIORITY_MAX); int defaults = 0; @@ -176,7 +189,6 @@ public void notify_mailbox(PendingIntent pendingIntent, int smallIcon, int large PendingIntent deletePendingIntent = PendingIntent.getService(mContext, deleteCode, deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT); cBuilder.setDeleteIntent(deletePendingIntent); - **/ Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), largeIcon); @@ -189,7 +201,7 @@ public void notify_mailbox(PendingIntent pendingIntent, int smallIcon, int large // 设置通知样式为收件箱样式,在通知中心中两指往外拉动,就能出线更多内容,但是很少见 //cBuilder.setNumber(messageList.size()); - NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); + Notification.InboxStyle inboxStyle = new Notification.InboxStyle(); for (String msg : messageList) { inboxStyle.addLine(msg); } @@ -226,7 +238,7 @@ public void notify_customview(RemoteViews remoteViews, PendingIntent pendingInte * @param title * @param content */ - public void notify_normail_moreline(PendingIntent pendingIntent, int smallIcon, String ticker, + public void notify_normal_multiline(PendingIntent pendingIntent, int smallIcon, String ticker, String title, String content, boolean sound, boolean vibrate, boolean lights) { final int sdk = Build.VERSION.SDK_INT; @@ -234,11 +246,8 @@ public void notify_normail_moreline(PendingIntent pendingIntent, int smallIcon, notify_normal_singline(pendingIntent, smallIcon, ticker, title, content, sound, vibrate, lights); Toast.makeText(mContext, "您的手机低于Android 4.1.2,不支持多行通知显示!!", Toast.LENGTH_SHORT).show(); } else { - setBuilder(pendingIntent, smallIcon, ticker, true, true, false); - nBuilder.setContentTitle(title); - nBuilder.setContentText(content); - nBuilder.setPriority(Notification.PRIORITY_HIGH); - notification = new Notification.BigTextStyle(nBuilder).bigText(content).build(); + setCompatBuilder(pendingIntent, smallIcon, ticker, title, content, sound, vibrate, lights); + notification = new Notification.BigTextStyle(cBuilder).bigText(content).build(); // 发送该通知 nm.notify(NOTIFICATION_ID, notification); } @@ -259,8 +268,8 @@ public void notify_progress(PendingIntent pendingIntent, int smallIcon, setCompatBuilder(pendingIntent, smallIcon, ticker, title, content, sound, vibrate, lights); /* * 因为进度条要实时更新通知栏也就说要不断的发送新的提示,所以这里不建议开启通知声音。 - * 这里是作为范例,给大家讲解下原理。所以发送通知后会听到多次的通知声音。 - */ + * 这里是作为范例,给大家讲解下原理。所以发送通知后会听到多次的通知声音。 + */ new Thread(new Runnable() { @Override @@ -295,14 +304,12 @@ public void run() { */ public void notify_bigPic(PendingIntent pendingIntent, int smallIcon, String ticker, String title, String content, int bigPic, boolean sound, boolean vibrate, boolean lights) { - setCompatBuilder(pendingIntent, smallIcon, ticker, title, null, sound, vibrate, lights); - NotificationCompat.BigPictureStyle picStyle = new NotificationCompat.BigPictureStyle(); + Notification.BigPictureStyle picStyle = new Notification.BigPictureStyle(); final BitmapFactory.Options options = new BitmapFactory.Options(); options.inScaled = true; options.inSampleSize = 2; - Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), - bigPic, options); + Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), bigPic, options); picStyle.bigPicture(bitmap); picStyle.bigLargeIcon(bitmap); cBuilder.setContentText(content); diff --git a/sample-debug.apk b/sample-debug.apk index 40c5f43..415e84a 100644 Binary files a/sample-debug.apk and b/sample-debug.apk differ diff --git a/sample/build.gradle b/sample/build.gradle index 3a28a7a..677dffe 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -1,13 +1,13 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 23 - buildToolsVersion "23.0.2" + compileSdkVersion 26 + buildToolsVersion "26.0.3" defaultConfig { applicationId "com.whee.wheetalklollipop" minSdkVersion 15 - targetSdkVersion 20 + targetSdkVersion 26 versionCode 1 versionName "1.0" } @@ -22,9 +22,10 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' - compile 'com.android.support:appcompat-v7:23.1.1' - compile 'com.android.support:design:23.1.1' - compile 'com.android.support:support-v13:23.1.1' + implementation 'com.android.support.constraint:constraint-layout:1.1.3' + compile 'com.android.support:appcompat-v7:26.1.0' + compile 'com.android.support:design:26.1.0' + compile 'com.android.support:support-v13:26.1.0' compile 'com.commit451:PhotoView:1.2.4' compile project(':library') } diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index 9ccc9a6..14a2bd9 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -1,17 +1,20 @@ + android:theme="@style/MyMaterialTheme" + tools:ignore="GoogleAppIndexingWarning"> @@ -19,7 +22,14 @@ - + + + + diff --git a/sample/src/main/java/com/wenming/notify/MyApplication.java b/sample/src/main/java/com/wenming/notify/MyApplication.java new file mode 100644 index 0000000..e3aaaf3 --- /dev/null +++ b/sample/src/main/java/com/wenming/notify/MyApplication.java @@ -0,0 +1,17 @@ +package com.wenming.notify; + +import android.app.Application; +import android.os.Build; + +import com.wenming.notify.notification.NotificationChannels; + +public class MyApplication extends Application { + + @Override + public void onCreate() { + super.onCreate(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannels.createAllNotificationChannels(this); + } + } +} diff --git a/sample/src/main/java/com/wenming/notify/activity/MainActivity.java b/sample/src/main/java/com/wenming/notify/activity/MainActivity.java index fb28bb0..a26d1b3 100644 --- a/sample/src/main/java/com/wenming/notify/activity/MainActivity.java +++ b/sample/src/main/java/com/wenming/notify/activity/MainActivity.java @@ -12,6 +12,7 @@ import com.wenming.notify.adapter.ViewPagerAdapter; import com.wenming.notify.fragment.OneFragment; import com.wenming.notify.fragment.ProfileFragment; +import com.wenming.notify.fragment.TwoFragment; public class MainActivity extends AppCompatActivity { @@ -43,6 +44,7 @@ private void initTabViewPager() { viewPager = (ViewPager) findViewById(R.id.viewpager); ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); adapter.addFragment(new OneFragment(mContext), getString(R.string.tab2)); + adapter.addFragment(new TwoFragment(), getString(R.string.tab4)); adapter.addFragment(new ProfileFragment(), getString(R.string.tab3)); viewPager.setAdapter(adapter); tabLayout = (TabLayout) findViewById(R.id.tabs); diff --git a/sample/src/main/java/com/wenming/notify/fragment/OneFragment.java b/sample/src/main/java/com/wenming/notify/fragment/OneFragment.java index c3e48fd..36cbbad 100644 --- a/sample/src/main/java/com/wenming/notify/fragment/OneFragment.java +++ b/sample/src/main/java/com/wenming/notify/fragment/OneFragment.java @@ -1,12 +1,22 @@ package com.wenming.notify.fragment; 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.Bitmap; +import android.graphics.BitmapFactory; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.SystemClock; import android.support.v4.app.Fragment; +import android.support.v4.app.NotificationCompat; +import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.text.style.ForegroundColorSpan; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -24,6 +34,8 @@ import uk.co.senab.photoview.PhotoView; +import static android.content.Context.NOTIFICATION_SERVICE; + /** * Created by wenmingvs on 2016/1/14. */ @@ -192,7 +204,7 @@ private void notify_normal_moreLine() { String content = "据台湾“中央社”报道,国民党主席朱立伦今天(18日)向中常会报告,为败选请辞党主席一职,他感谢各位中常委的指教包容,也宣布未来党务工作由副主席黄敏惠暂代,完成未来所有补选工作。"; //实例化工具类,并且调用接口 NotifyUtil notify2 = new NotifyUtil(mContext, 2); - notify2.notify_normail_moreline(pIntent, smallIcon, ticker, title, content, true, true, false); + notify2.notify_normal_multiline(pIntent, smallIcon, ticker, title, content, true, true, false); currentNotify = notify2; } @@ -210,11 +222,11 @@ private void notify_mailbox() { String ticker = "您有一条新通知"; String title = "冰冰"; ArrayList messageList = new ArrayList(); - messageList.add("文明,今晚有空吗?"); + messageList.add("Kelly,今晚有空吗?"); messageList.add("晚上跟我一起去玩吧?"); messageList.add("怎么不回复我??我生气了!!"); messageList.add("我真生气了!!!!!你听见了吗!"); - messageList.add("文明,别不理我!!!"); + messageList.add("Kelly,别不理我!!!"); String content = "[" + messageList.size() + "条]" + title + ": " + messageList.get(0); //实例化工具类,并且调用接口 NotifyUtil notify3 = new NotifyUtil(mContext, 3); @@ -230,8 +242,7 @@ private void notify_bigPic() { //设置想要展示的数据内容 Intent intent = new Intent(mContext, OtherActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); - PendingIntent pIntent = PendingIntent.getActivity(mContext, - requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent pIntent = PendingIntent.getActivity(mContext, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); int smallIcon = R.drawable.xc_smaillicon; int largePic = R.drawable.screenshot; String ticker = "您有一条新通知"; @@ -243,6 +254,69 @@ private void notify_bigPic() { currentNotify = notify4; } + /** + * 此方法可作为简单测试使用 + */ + private void notifyTest() { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.baidu.com")); + PendingIntent pendingIntent = PendingIntent.getActivity(getActivity(), 0, intent, 0); + NotificationManager manager = (NotificationManager) getActivity().getSystemService(NOTIFICATION_SERVICE); + if (manager == null) + return; + Notification notification; + + if (Build.VERSION.SDK_INT >= 26) { + //当sdk版本大于26 + Notification.BigPictureStyle picStyle = new Notification.BigPictureStyle(); + final BitmapFactory.Options options = new BitmapFactory.Options(); + options.inScaled = true; + options.inSampleSize = 2; + Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.screenshot, options); + picStyle.bigPicture(bitmap); + picStyle.bigLargeIcon(bitmap); + + String id = "channel_1"; + String description = "143"; + int importance = NotificationManager.IMPORTANCE_DEFAULT; + NotificationChannel channel = new NotificationChannel(id, description, importance); + channel.enableLights(true); + channel.enableVibration(true); + manager.createNotificationChannel(channel); + + //设置字体颜色span + SpannableStringBuilder ssb = new SpannableStringBuilder("This is a content title"); + ssb.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.colorPrimary)), 0, 7, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); + + notification = new Notification.Builder(getActivity(), id) + .setCategory(Notification.CATEGORY_MESSAGE) + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle(ssb) + .setContentText(ssb) + .setContentIntent(pendingIntent) + .setAutoCancel(true) + .setStyle(picStyle) + .build(); + } else { + //当sdk版本小于26 + NotificationCompat.BigPictureStyle picStyle = new NotificationCompat.BigPictureStyle(); + final BitmapFactory.Options options = new BitmapFactory.Options(); + options.inScaled = true; + options.inSampleSize = 2; + Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.screenshot, options); + picStyle.bigPicture(bitmap); + picStyle.bigLargeIcon(bitmap); + + notification = new NotificationCompat.Builder(getActivity()) + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("This is content title") + .setContentText("This is content text") + .setContentIntent(pendingIntent) + .setStyle(picStyle) + .build(); + } + manager.notify(1, notification); + } + /** * 高仿应用宝 @@ -330,7 +404,7 @@ private void notify_headUp() { int largeIcon = R.drawable.fbb_largeicon; String ticker = "您有一条新通知"; String title = "范冰冰"; - String content = "文明,今晚在希尔顿酒店2016号房哈"; + String content = "Kelly,今晚在希尔顿酒店2019号房哈"; Intent intent = new Intent(mContext, OtherActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(mContext, diff --git a/sample/src/main/java/com/wenming/notify/fragment/ProfileFragment.java b/sample/src/main/java/com/wenming/notify/fragment/ProfileFragment.java index 7668833..279c9a8 100644 --- a/sample/src/main/java/com/wenming/notify/fragment/ProfileFragment.java +++ b/sample/src/main/java/com/wenming/notify/fragment/ProfileFragment.java @@ -39,7 +39,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, private void initWebView() { if (Features.showProfile) { mContentWv.getSettings().setJavaScriptEnabled(true); - mContentWv.loadUrl("https://github.com/wenmingvs"); + mContentWv.loadUrl("https://github.com/zongkaili/NotifyUtil"); mContentWv.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { diff --git a/sample/src/main/java/com/wenming/notify/fragment/TwoFragment.java b/sample/src/main/java/com/wenming/notify/fragment/TwoFragment.java new file mode 100644 index 0000000..280ef44 --- /dev/null +++ b/sample/src/main/java/com/wenming/notify/fragment/TwoFragment.java @@ -0,0 +1,142 @@ +package com.wenming.notify.fragment; + +import android.app.NotificationManager; +import android.content.Context; +import android.content.Intent; +import android.graphics.BitmapFactory; +import android.os.Build; +import android.os.Bundle; +import android.support.annotation.RequiresApi; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; + +import com.wenming.notify.R; +import com.wenming.notify.notification.Notificaitons; +import com.wenming.notify.notification.NotificationContentWrapper; +import com.wenming.notify.notification.NotificationService; + + +/** + * @author zongkl + * @date 2020/1/8 + * @desc + */ +public class TwoFragment extends Fragment implements View.OnClickListener { + private View mView; + private Context mContext; + private Button mSimple; + private Button mAction; + private Button mRemoteInput; + private Button mBigPictureStyle; + private Button mBigTextStyle; + private Button mInboxStyle; + private Button mMediaStyle; + private Button mMessagingStyle; + private Button mProgress; + private Button mCustomHeadsUp; + private Button mCustom; + private Button mClearAll; + + private NotificationManager mNM; + + public TwoFragment() { + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + mView = inflater.inflate(R.layout.fragment_two, container, false); + mContext = this.getContext(); + + mNM = (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE); + + mSimple = mView.findViewById(R.id.btn_simple); + mAction = mView.findViewById(R.id.btn_action); + mRemoteInput = mView.findViewById(R.id.btn_remote_input); + mBigPictureStyle = mView.findViewById(R.id.btn_big_picture_style); + mBigTextStyle = mView.findViewById(R.id.btn_big_text_style); + mInboxStyle = mView.findViewById(R.id.btn_inbox_style); + mMediaStyle = mView.findViewById(R.id.btn_media_style); + mMessagingStyle = mView.findViewById(R.id.btn_messaging_style); + mProgress = mView.findViewById(R.id.btn_progress); + mCustomHeadsUp = mView.findViewById(R.id.btn_custom_heads_up); + mCustom = mView.findViewById(R.id.btn_custom); + mClearAll = mView.findViewById(R.id.btn_clear_all); + + mSimple.setOnClickListener(this); + mAction.setOnClickListener(this); + mRemoteInput.setOnClickListener(this); + mBigPictureStyle.setOnClickListener(this); + mBigTextStyle.setOnClickListener(this); + mInboxStyle.setOnClickListener(this); + mMediaStyle.setOnClickListener(this); + mMessagingStyle.setOnClickListener(this); + mProgress.setOnClickListener(this); + mCustomHeadsUp.setOnClickListener(this); + mCustom.setOnClickListener(this); + mClearAll.setOnClickListener(this); + return mView; + } + + @RequiresApi(api = Build.VERSION_CODES.O) + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.btn_simple: + Notificaitons.getInstance().sendSimpleNotification(mContext, mNM); + break; + case R.id.btn_action: + Notificaitons.getInstance().sendActionNotification(mContext, mNM); + break; + case R.id.btn_remote_input: + Notificaitons.getInstance().sendRemoteInputNotification(mContext, mNM); + break; + case R.id.btn_big_picture_style: + Notificaitons.getInstance().sendBigPictureStyleNotification(mContext, mNM); + break; + case R.id.btn_big_text_style: + Notificaitons.getInstance().sendBigTextStyleNotification(mContext, mNM); + break; + case R.id.btn_inbox_style: + Notificaitons.getInstance().sendInboxStyleNotification(mContext, mNM); + break; + case R.id.btn_media_style: + Notificaitons.getInstance().sendMediaStyleNotification(mContext, mNM, false); + break; + case R.id.btn_messaging_style: + Notificaitons.getInstance().sendMessagingStyleNotification(mContext, mNM); + break; + case R.id.btn_progress: + Intent intent = new Intent(getActivity(), NotificationService.class); + intent.setAction(NotificationService.ACTION_SEND_PROGRESS_NOTIFICATION); + getActivity().startService(intent); + break; + case R.id.btn_custom_heads_up: + Notificaitons.getInstance().sendCustomHeadsUpViewNotification(mContext, mNM); + break; + case R.id.btn_custom: + Notificaitons.getInstance().sendCustomViewNotification( + mContext, + mNM, + new NotificationContentWrapper( + BitmapFactory.decodeResource(mContext.getResources(), + R.drawable.custom_view_picture_current), + "最美的期待", + "周笔畅 - 最美的期待"), + false, + true); + break; + case R.id.btn_clear_all: + Notificaitons.getInstance().clearAllNotification(mNM); + break; + default: + //do nothing + } + } +} diff --git a/sample/src/main/java/com/wenming/notify/notification/LaunchActivity.java b/sample/src/main/java/com/wenming/notify/notification/LaunchActivity.java new file mode 100644 index 0000000..9b1d09b --- /dev/null +++ b/sample/src/main/java/com/wenming/notify/notification/LaunchActivity.java @@ -0,0 +1,15 @@ +package com.wenming.notify.notification; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; + +import com.wenming.notify.R; + +public class LaunchActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_launch); + } +} diff --git a/sample/src/main/java/com/wenming/notify/notification/Notificaitons.java b/sample/src/main/java/com/wenming/notify/notification/Notificaitons.java new file mode 100644 index 0000000..9858a07 --- /dev/null +++ b/sample/src/main/java/com/wenming/notify/notification/Notificaitons.java @@ -0,0 +1,543 @@ +package com.wenming.notify.notification; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.RemoteInput; +import android.content.Context; +import android.content.Intent; +import android.graphics.BitmapFactory; +import android.graphics.drawable.Icon; +import android.os.Build; +import android.support.annotation.RequiresApi; +import android.widget.RemoteViews; + +import com.wenming.notify.BuildConfig; +import com.wenming.notify.R; + +public class Notificaitons { + public final static int NOTIFICATION_SAMPLE = 0; + public final static int NOTIFICATION_ACTION = 1; + public final static int NOTIFICATION_REMOTE_INPUT = 2; + public final static int NOTIFICATION_BIG_PICTURE_STYLE = 3; + public final static int NOTIFICATION_BIG_TEXT_STYLE = 4; + public final static int NOTIFICATION_INBOX_STYLE = 5; + public final static int NOTIFICATION_MEDIA_STYLE = 6; + public final static int NOTIFICATION_MESSAGING_STYLE = 7; + public final static int NOTIFICATION_PROGRESS = 8; + public final static int NOTIFICATION_CUSTOM_HEADS_UP = 9; + public final static int NOTIFICATION_CUSTOM = 10; + + public final static String ACTION_SIMPLE = BuildConfig.APPLICATION_ID + ".ACTION_SIMPLE"; + public final static String ACTION_ACTION = BuildConfig.APPLICATION_ID + ".ACTION_ACTION"; + public final static String ACTION_REMOTE_INPUT = BuildConfig.APPLICATION_ID + ".ACTION_REMOTE_INPUT"; + public final static String ACTION_BIG_PICTURE_STYLE = BuildConfig.APPLICATION_ID + ".ACTION_BIG_PICTURE_STYLE"; + public final static String ACTION_BIG_TEXT_STYLE = BuildConfig.APPLICATION_ID + ".ACTION_BIG_TEXT_STYLE"; + public final static String ACTION_INBOX_STYLE = BuildConfig.APPLICATION_ID + ".ACTION_INBOX_STYLE"; + public final static String ACTION_MEDIA_STYLE = BuildConfig.APPLICATION_ID + ".ACTION_MEDIA_STYLE"; + public final static String ACTION_MESSAGING_STYLE = BuildConfig.APPLICATION_ID + ".ACTION_MESSAGING_STYLE"; + public final static String ACTION_PROGRESS = BuildConfig.APPLICATION_ID + ".ACTION_PROGRESS"; + public final static String ACTION_CUSTOM_HEADS_UP_VIEW = BuildConfig.APPLICATION_ID + ".ACTION_CUSTOM_HEADS_UP_VIEW"; + public final static String ACTION_CUSTOM_VIEW = BuildConfig.APPLICATION_ID + ".ACTION_CUSTOM_VIEW"; + public final static String ACTION_CUSTOM_VIEW_OPTIONS_LOVE = BuildConfig.APPLICATION_ID + ".ACTION_CUSTOM_VIEW_OPTIONS_LOVE"; + public final static String ACTION_CUSTOM_VIEW_OPTIONS_PRE = BuildConfig.APPLICATION_ID + ".ACTION_CUSTOM_VIEW_OPTIONS_PRE"; + public final static String ACTION_CUSTOM_VIEW_OPTIONS_PLAY_OR_PAUSE = BuildConfig.APPLICATION_ID + ".ACTION_CUSTOM_VIEW_OPTIONS_PLAY_OR_PAUSE"; + public final static String ACTION_CUSTOM_VIEW_OPTIONS_NEXT = BuildConfig.APPLICATION_ID + ".ACTION_CUSTOM_VIEW_OPTIONS_NEXT"; + public final static String ACTION_CUSTOM_VIEW_OPTIONS_LYRICS = BuildConfig.APPLICATION_ID + ".ACTION_CUSTOM_VIEW_OPTIONS_LYRICS"; + public final static String ACTION_CUSTOM_VIEW_OPTIONS_CANCEL = BuildConfig.APPLICATION_ID + ".ACTION_CUSTOM_VIEW_OPTIONS_CANCEL"; + + public final static String ACTION_YES = BuildConfig.APPLICATION_ID + ".ACTION_YES"; + public final static String ACTION_NO = BuildConfig.APPLICATION_ID + ".ACTION_NO"; + public final static String ACTION_DELETE = BuildConfig.APPLICATION_ID + ".ACTION_DELETE"; + public final static String ACTION_REPLY = BuildConfig.APPLICATION_ID + ".ACTION_REPLY"; + public final static String REMOTE_INPUT_RESULT_KEY = "remote_input_content"; + + public final static String EXTRA_OPTIONS = "options"; + public final static String MEDIA_STYLE_ACTION_DELETE = "action_delete"; + public final static String MEDIA_STYLE_ACTION_PLAY = "action_play"; + public final static String MEDIA_STYLE_ACTION_PAUSE = "action_pause"; + public final static String MEDIA_STYLE_ACTION_NEXT = "action_next"; + public final static String ACTION_ANSWER = "action_answer"; + public final static String ACTION_REJECT = "action_reject"; + + + private static volatile Notificaitons sInstance = null; + + private Notificaitons() { + } + + public static Notificaitons getInstance() { + if (sInstance == null) { + synchronized (Notificaitons.class) { + if (sInstance == null) { + sInstance = new Notificaitons(); + } + } + } + + return sInstance; + } + + @RequiresApi(api = Build.VERSION_CODES.O) + public void sendSimpleNotification(Context context, NotificationManager nm) { + //创建点击通知时发送的广播 + Intent intent = new Intent(context, NotificationService.class); + intent.setAction(ACTION_SIMPLE); + PendingIntent pi = PendingIntent.getService(context, 0, intent, 0); + //创建删除通知时发送的广播 + Intent deleteIntent = new Intent(context, NotificationService.class); + deleteIntent.setAction(ACTION_DELETE); + PendingIntent deletePendingIntent = PendingIntent.getService(context, 0, deleteIntent, 0); + //创建通知 + Notification.Builder nb = new Notification.Builder(context, NotificationChannels.LOW) + //设置通知左侧的小图标 + .setSmallIcon(R.drawable.ic_notification) + //设置通知标题 + .setContentTitle("Simple notification") + //设置通知内容 + .setContentText("Demo for simple notification !") + //设置点击通知后自动删除通知 + .setAutoCancel(true) + //设置显示通知时间 + .setShowWhen(true) + //设置通知右侧的大图标 + .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_notifiation_big)) + //设置点击通知时的响应事件 + .setContentIntent(pi) + //设置删除通知时的响应事件 + .setDeleteIntent(deletePendingIntent); + //发送通知 + nm.notify(NOTIFICATION_SAMPLE, nb.build()); + } + + @RequiresApi(api = Build.VERSION_CODES.O) + public void sendActionNotification(Context context, NotificationManager nm) { + //创建点击通知时发送的广播 + Intent intent = new Intent(context, NotificationService.class); + intent.setAction(ACTION_ACTION); + PendingIntent pi = PendingIntent.getService(context, 0, intent, 0); + //创建通知 + Notification.Builder nb = new Notification.Builder(context, NotificationChannels.DEFAULT) + //设置通知左侧的小图标 + .setSmallIcon(R.drawable.ic_notification) + //设置通知标题 + .setContentTitle("Action notification") + //设置通知内容 + .setContentText("Demo for action notification !") + //设置点击通知后自动删除通知 + .setAutoCancel(true) + //设置显示通知时间 + .setShowWhen(true) + //设置点击通知时的响应事件 + .setContentIntent(pi); + //创建点击通知 YES 按钮时发送的广播 + Intent yesIntent = new Intent(context, NotificationService.class); + yesIntent.setAction(ACTION_YES); + PendingIntent yesPendingIntent = PendingIntent.getService(context, 0, yesIntent, 0); + Notification.Action yesActionBuilder = new Notification.Action.Builder( + Icon.createWithResource("", R.drawable.ic_yes), + "YES", + yesPendingIntent) + .build(); + //创建点击通知 NO 按钮时发送的广播 + Intent noIntent = new Intent(context, NotificationService.class); + noIntent.setAction(ACTION_NO); + PendingIntent noPendingIntent = PendingIntent.getService(context, 0, noIntent, 0); + Notification.Action noActionBuilder = new Notification.Action.Builder( + Icon.createWithResource("", R.drawable.ic_no), + "NO", + noPendingIntent) + .build(); + //为通知添加按钮 + nb.setActions(yesActionBuilder, noActionBuilder); + //发送通知 + nm.notify(NOTIFICATION_ACTION, nb.build()); + } + + @RequiresApi(api = Build.VERSION_CODES.O) + public void sendRemoteInputNotification(Context context, NotificationManager nm) { + //创建点击通知时发送的广播 + Intent intent = new Intent(context, NotificationService.class); + intent.setAction(ACTION_REMOTE_INPUT); + PendingIntent pi = PendingIntent.getService(context, 0, intent, 0); + //创建通知 + Notification.Builder nb = new Notification.Builder(context, NotificationChannels.IMPORTANCE) + //设置通知左侧的小图标 + .setSmallIcon(R.drawable.ic_notification) + //设置通知标题 + .setContentTitle("Remote input notification") + //设置通知内容 + .setContentText("Demo for remote input notification !") + //设置点击通知后自动删除通知 + .setAutoCancel(true) + //设置显示通知时间 + .setShowWhen(true) + //设置点击通知时的响应事件 + .setContentIntent(pi); + //创建带输入框的按钮 + RemoteInput remoteInput = new RemoteInput.Builder(REMOTE_INPUT_RESULT_KEY) + .setLabel("Reply").build(); + Intent remoteInputIntent = new Intent(context, NotificationService.class); + remoteInputIntent.setAction(ACTION_REPLY); + PendingIntent replyPendingIntent = PendingIntent.getService(context, 2, remoteInputIntent, 0); + Notification.Action replyAction = new Notification.Action.Builder( + Icon.createWithResource("", R.drawable.ic_reply), + "Reply", + replyPendingIntent) + .addRemoteInput(remoteInput) + .build(); + //为通知添加按钮 + nb.setActions(replyAction); + //发送通知 + nm.notify(NOTIFICATION_REMOTE_INPUT, nb.build()); + } + + @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) + public void sendBigPictureStyleNotification(Context context, NotificationManager nm) { + //创建点击通知时发送的广播 + Intent intent = new Intent(context, NotificationService.class); + intent.setAction(ACTION_BIG_PICTURE_STYLE); + PendingIntent pi = PendingIntent.getService(context, 0, intent, 0); + //创建大视图样式 + Notification.BigPictureStyle bigPictureStyle = new Notification.BigPictureStyle() + .setBigContentTitle("Big picture style notification ~ Expand title") + .setSummaryText("Demo for big picture style notification ! ~ Expand summery") + .bigPicture(BitmapFactory.decodeResource(context.getResources(), R.drawable.big_style_picture)); + //创建通知 + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + Notification.Builder nb = new Notification.Builder(context, NotificationChannels.DEFAULT) + //设置通知左侧的小图标 + .setSmallIcon(R.drawable.ic_notification) + //设置通知标题 + .setContentTitle("Big picture style notification") + //设置通知内容 + .setContentText("Demo for big picture style notification !") + //设置点击通知后自动删除通知 + .setAutoCancel(true) + //设置显示通知时间 + .setShowWhen(true) + //设置点击通知时的响应事件 + .setContentIntent(pi) + //设置大视图样式通知 + .setStyle(bigPictureStyle); + //发送通知 + nm.notify(NOTIFICATION_BIG_PICTURE_STYLE, nb.build()); + } + } + + @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) + public void sendBigTextStyleNotification(Context context, NotificationManager nm) { + //创建点击通知时发送的广播 + Intent intent = new Intent(context, NotificationService.class); + intent.setAction(ACTION_BIG_TEXT_STYLE); + PendingIntent pi = PendingIntent.getService(context, 0, intent, 0); + //创建大文字样式 + Notification.BigTextStyle bigTextStyle = new Notification.BigTextStyle() + .setBigContentTitle("Big text style notification ~ Expand title") + .setSummaryText("Demo for big text style notification ! ~ Expand summery") + .bigText("We are the champions \n" + + "We are the champions \n" + + "No time for losers \n" + + "Cause we are the champions of the World"); + + //创建通知 + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + Notification.Builder nb = new Notification.Builder(context, NotificationChannels.DEFAULT) + //设置通知左侧的小图标 + .setSmallIcon(R.drawable.ic_notification) + //设置通知标题 + .setContentTitle("Big text style notification") + //设置通知内容 + .setContentText("Demo for big text style notification !") + //设置点击通知后自动删除通知 + .setAutoCancel(true) + //设置显示通知时间 + .setShowWhen(true) + //设置点击通知时的响应事件 + .setContentIntent(pi) + //设置大文字样式通知 + .setStyle(bigTextStyle); + //发送通知 + nm.notify(NOTIFICATION_BIG_TEXT_STYLE, nb.build()); + } + } + + @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) + public void sendInboxStyleNotification(Context context, NotificationManager nm) { + //创建点击通知时发送的广播 + Intent intent = new Intent(context, NotificationService.class); + intent.setAction(ACTION_INBOX_STYLE); + PendingIntent pi = PendingIntent.getService(context, 0, intent, 0); + //创建信箱样式 + Notification.InboxStyle inboxStyle = new Notification.InboxStyle() + .setBigContentTitle("Inbox style notification ~ Expand title") + .setSummaryText("Demo for inbox style notification ! ~ Expand summery") + //最多六行 + .addLine("1. I am email content.") + .addLine("2. I am email content.") + .addLine("3. I am email content.") + .addLine("4. I am email content.") + .addLine("5. I am email content.") + .addLine("6. I am email content."); + //创建通知 + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + Notification.Builder nb = new Notification.Builder(context, NotificationChannels.DEFAULT) + //设置通知左侧的小图标 + .setSmallIcon(R.drawable.ic_notification) + //设置通知标题 + .setContentTitle("Inbox style notification") + //设置通知内容 + .setContentText("Demo for inbox style notification !") + //设置点击通知后自动删除通知 + .setAutoCancel(true) + //设置显示通知时间 + .setShowWhen(true) + //设置点击通知时的响应事件 + .setContentIntent(pi) + //设置信箱样式通知 + .setStyle(inboxStyle); + //发送通知 + nm.notify(NOTIFICATION_INBOX_STYLE, nb.build()); + } + } + + @RequiresApi(api = Build.VERSION_CODES.M) + public void sendMediaStyleNotification(Context context, NotificationManager nm, boolean isPlaying) { + //创建点击通知时发送的广播 + Intent intent = new Intent(context, NotificationService.class); + intent.setAction(ACTION_MEDIA_STYLE); + PendingIntent pi = PendingIntent.getService(context, 0, intent, 0); + //创建Action按钮 + Intent playOrPauseIntent = new Intent(context, NotificationService.class); + playOrPauseIntent.setAction(ACTION_MEDIA_STYLE); + playOrPauseIntent.putExtra(EXTRA_OPTIONS, isPlaying ? MEDIA_STYLE_ACTION_PAUSE : MEDIA_STYLE_ACTION_PLAY); + PendingIntent playOrPausePendingIntent = PendingIntent.getService(context, 0, playOrPauseIntent, PendingIntent.FLAG_UPDATE_CURRENT); + Notification.Action playOrPauseAction = new Notification.Action.Builder( + Icon.createWithResource(context, isPlaying ? R.drawable.ic_pause : R.drawable.ic_play), + isPlaying ? "PAUSE" : "PLAY", + playOrPausePendingIntent) + .build(); + Intent nextIntent = new Intent(context, NotificationService.class); + nextIntent.setAction(ACTION_MEDIA_STYLE); + nextIntent.putExtra(EXTRA_OPTIONS, MEDIA_STYLE_ACTION_NEXT); + PendingIntent nextPendingIntent = PendingIntent.getService(context, 1, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT); + Notification.Action nextAction = new Notification.Action.Builder( + Icon.createWithResource(context, R.drawable.ic_next), + "Next", + nextPendingIntent) + .build(); + Intent deleteIntent = new Intent(context, NotificationService.class); + deleteIntent.setAction(ACTION_MEDIA_STYLE); + deleteIntent.putExtra(EXTRA_OPTIONS, MEDIA_STYLE_ACTION_DELETE); + PendingIntent deletePendingIntent = PendingIntent.getService(context, 2, deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT); + Notification.Action deleteAction = new Notification.Action.Builder( + Icon.createWithResource(context, R.drawable.ic_delete), + "Delete", + deletePendingIntent) + .build(); + //创建媒体样式 + Notification.MediaStyle mediaStyle = new Notification.MediaStyle() + //最多三个Action + .setShowActionsInCompactView(0, 1, 2); + //创建通知 + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + Notification.Builder nb = new Notification.Builder(context, NotificationChannels.MEDIA) + //设置通知左侧的小图标 + .setSmallIcon(R.drawable.ic_notification) + //设置通知标题 + .setContentTitle("Media style notification") + //设置通知内容 + .setContentText("Demo for media style notification !") + //设置通知不可删除 + .setOngoing(true) + //设置显示通知时间 + .setShowWhen(true) + //设置点击通知时的响应事件 + .setContentIntent(pi) + //设置Action按钮 + .setActions(playOrPauseAction, nextAction, deleteAction) + //设置信箱样式通知 + .setStyle(mediaStyle); + //发送通知 + nm.notify(NOTIFICATION_MEDIA_STYLE, nb.build()); + } + + } + + @RequiresApi(api = Build.VERSION_CODES.N) + public void sendMessagingStyleNotification(Context context, NotificationManager nm) { + //创建点击通知时发送的广播 + Intent intent = new Intent(context, NotificationService.class); + intent.setAction(ACTION_MESSAGING_STYLE); + PendingIntent pi = PendingIntent.getService(context, 0, intent, 0); + //创建信息样式 + Notification.MessagingStyle messagingStyle = new Notification.MessagingStyle("peter") + .setConversationTitle("Messaging style notification") + .addMessage("This is a message for you", System.currentTimeMillis(), "peter"); + //创建通知 + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + Notification.Builder nb = new Notification.Builder(context, NotificationChannels.DEFAULT) + //设置通知左侧的小图标 + .setSmallIcon(R.drawable.ic_notification) + //设置通知标题 + .setContentTitle("Messaging style notification") + //设置通知内容 + .setContentText("Demo for messaging style notification !") + //设置点击通知后自动删除通知 + .setAutoCancel(true) + //设置显示通知时间 + .setShowWhen(true) + //设置点击通知时的响应事件 + .setContentIntent(pi) + //设置信箱样式通知 + .setStyle(messagingStyle); + //发送通知 + nm.notify(NOTIFICATION_MESSAGING_STYLE, nb.build()); + } + } + + @RequiresApi(api = Build.VERSION_CODES.O) + public void sendProgressViewNotification(Context context, NotificationManager nm, int progress) { + //创建点击通知时发送的广播 + Intent intent = new Intent(context, NotificationService.class); + intent.setAction(ACTION_PROGRESS); + PendingIntent pi = PendingIntent.getService(context, 0, intent, 0); + //创建通知 + Notification.Builder nb = new Notification.Builder(context, NotificationChannels.LOW) + //设置通知左侧的小图标 + .setSmallIcon(R.drawable.ic_notification) + //设置通知标题 + .setContentTitle("Downloading...") + //设置通知内容 + .setContentText(String.valueOf(progress) + "%") + //设置通知不可删除 + .setOngoing(true) + //设置显示通知时间 + .setShowWhen(true) + //设置点击通知时的响应事件 + .setContentIntent(pi) + .setProgress(100, progress, false); + //发送通知 + nm.notify(NOTIFICATION_PROGRESS, nb.build()); + } + + @RequiresApi(api = Build.VERSION_CODES.O) + public void sendCustomHeadsUpViewNotification(Context context, NotificationManager nm) { + //创建点击通知时发送的广播 + Intent intent = new Intent(context, LaunchActivity.class); + PendingIntent pi = PendingIntent.getActivity(context, 0, intent, 0); + //创建自定义顶部提醒视图 + Intent answerIntent = new Intent(context, NotificationService.class); + answerIntent.setAction(ACTION_CUSTOM_HEADS_UP_VIEW); + answerIntent.putExtra(EXTRA_OPTIONS, ACTION_ANSWER); + PendingIntent answerPendingIntent = PendingIntent.getService(context, 0, answerIntent, PendingIntent.FLAG_UPDATE_CURRENT); + Intent rejectIntent = new Intent(context, NotificationService.class); + rejectIntent.setAction(ACTION_CUSTOM_HEADS_UP_VIEW); + rejectIntent.putExtra(EXTRA_OPTIONS, ACTION_REJECT); + PendingIntent rejectPendingIntent = PendingIntent.getService(context, 1, rejectIntent, PendingIntent.FLAG_UPDATE_CURRENT); + RemoteViews headsUpView = new RemoteViews(context.getPackageName(), R.layout.custom_heads_up_layout); + headsUpView.setOnClickPendingIntent(R.id.iv_answer, answerPendingIntent); + headsUpView.setOnClickPendingIntent(R.id.iv_reject, rejectPendingIntent); + //创建通知 + Notification.Builder nb = new Notification.Builder(context, NotificationChannels.CRITICAL) + //设置通知左侧的小图标 + .setSmallIcon(R.drawable.ic_notification) + //设置通知标题 + .setContentTitle("Custom heads up notification") + //设置通知内容 + .setContentText("Demo for custom heads up notification !") + //设置点击通知后自动删除通知 + .setAutoCancel(true) + //设置显示通知时间 + .setShowWhen(true) + //设置点击通知时的响应事件 + .setContentIntent(pi) + //设置全屏响应事件; + .setFullScreenIntent(pi, true) + //设置自定义顶部提醒视图 + .setCustomHeadsUpContentView(headsUpView); + //发送通知 + nm.notify(NOTIFICATION_CUSTOM_HEADS_UP, nb.build()); + } + + @RequiresApi(api = Build.VERSION_CODES.O) + public void sendCustomViewNotification(Context context, NotificationManager nm, NotificationContentWrapper content, Boolean isLoved, Boolean isPlaying) { + //创建点击通知时发送的广播 + Intent intent = new Intent(context, LaunchActivity.class); + PendingIntent pi = PendingIntent.getActivity(context, 0, intent, 0); + //创建各个按钮的点击响应广播 + Intent intentLove = new Intent(context, NotificationService.class); + intentLove.setAction(ACTION_CUSTOM_VIEW_OPTIONS_LOVE); + PendingIntent piLove = PendingIntent.getService(context, 0, intentLove, PendingIntent.FLAG_UPDATE_CURRENT); + + Intent intentPre = new Intent(context, NotificationService.class); + intentPre.setAction(ACTION_CUSTOM_VIEW_OPTIONS_PRE); + PendingIntent piPre = PendingIntent.getService(context, 0, intentPre, PendingIntent.FLAG_UPDATE_CURRENT); + + Intent intentPlayOrPause = new Intent(context, NotificationService.class); + intentPlayOrPause.setAction(ACTION_CUSTOM_VIEW_OPTIONS_PLAY_OR_PAUSE); + PendingIntent piPlayOrPause = PendingIntent.getService(context, 0, intentPlayOrPause, PendingIntent.FLAG_UPDATE_CURRENT); + + Intent intentNext = new Intent(context, NotificationService.class); + intentNext.setAction(ACTION_CUSTOM_VIEW_OPTIONS_NEXT); + PendingIntent piNext = PendingIntent.getService(context, 0, intentNext, PendingIntent.FLAG_UPDATE_CURRENT); + + Intent intentLyrics = new Intent(context, NotificationService.class); + intentLyrics.setAction(ACTION_CUSTOM_VIEW_OPTIONS_LYRICS); + PendingIntent piLyrics = PendingIntent.getService(context, 0, intentLyrics, PendingIntent.FLAG_UPDATE_CURRENT); + + Intent intentCancel = new Intent(context, NotificationService.class); + intentCancel.setAction(ACTION_CUSTOM_VIEW_OPTIONS_CANCEL); + PendingIntent piCancel = PendingIntent.getService(context, 0, intentCancel, PendingIntent.FLAG_UPDATE_CURRENT); + //创建自定义小视图 + RemoteViews customView = new RemoteViews(context.getPackageName(), R.layout.custom_view_layout); + customView.setImageViewBitmap(R.id.iv_content, content.bitmap); + customView.setTextViewText(R.id.tv_title, content.title); + customView.setTextViewText(R.id.tv_summery, content.summery); + customView.setImageViewBitmap(R.id.iv_play_or_pause, BitmapFactory.decodeResource(context.getResources(), + isPlaying ? R.drawable.ic_pause : R.drawable.ic_play)); + customView.setOnClickPendingIntent(R.id.iv_play_or_pause, piPlayOrPause); + customView.setOnClickPendingIntent(R.id.iv_next, piNext); + customView.setOnClickPendingIntent(R.id.iv_lyrics, piLyrics); + customView.setOnClickPendingIntent(R.id.iv_cancel, piCancel); + //创建自定义大视图 + RemoteViews customBigView = new RemoteViews(context.getPackageName(), R.layout.custom_big_view_layout); + customBigView.setImageViewBitmap(R.id.iv_content_big, content.bitmap); + customBigView.setTextViewText(R.id.tv_title_big, content.title); + customBigView.setTextViewText(R.id.tv_summery_big, content.summery); + customBigView.setImageViewBitmap(R.id.iv_love_big, BitmapFactory.decodeResource(context.getResources(), + isLoved ? R.drawable.ic_loved : R.drawable.ic_love)); + customBigView.setImageViewBitmap(R.id.iv_play_or_pause_big, BitmapFactory.decodeResource(context.getResources(), + isPlaying ? R.drawable.ic_pause : R.drawable.ic_play)); + customBigView.setOnClickPendingIntent(R.id.iv_love_big, piLove); + customBigView.setOnClickPendingIntent(R.id.iv_pre_big, piPre); + customBigView.setOnClickPendingIntent(R.id.iv_play_or_pause_big, piPlayOrPause); + customBigView.setOnClickPendingIntent(R.id.iv_next_big, piNext); + customBigView.setOnClickPendingIntent(R.id.iv_lyrics_big, piLyrics); + customBigView.setOnClickPendingIntent(R.id.iv_cancel_big, piCancel); + //创建通知 + Notification.Builder nb = new Notification.Builder(context, NotificationChannels.MEDIA) + //设置通知左侧的小图标 + .setSmallIcon(R.drawable.ic_notification) + //设置通知标题 + .setContentTitle("Custom notification") + //设置通知内容 + .setContentText("Demo for custom notification !") + //设置通知不可删除 + .setOngoing(true) + //设置显示通知时间 + .setShowWhen(true) + //设置点击通知时的响应事件 + .setContentIntent(pi) + //设置自定义小视图 + .setCustomContentView(customView) + //设置自定义大视图 + .setCustomBigContentView(customBigView); + //发送通知 + nm.notify(NOTIFICATION_CUSTOM, nb.build()); + } + + public void clearAllNotification(NotificationManager nm) { + nm.cancelAll(); + } +} diff --git a/sample/src/main/java/com/wenming/notify/notification/NotificationChannels.java b/sample/src/main/java/com/wenming/notify/notification/NotificationChannels.java new file mode 100644 index 0000000..e314173 --- /dev/null +++ b/sample/src/main/java/com/wenming/notify/notification/NotificationChannels.java @@ -0,0 +1,57 @@ +package com.wenming.notify.notification; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.Context; +import android.os.Build; +import android.support.annotation.RequiresApi; + +import com.wenming.notify.R; + +import java.util.Arrays; + + +public class NotificationChannels { + public final static String CRITICAL = "critical"; + public final static String IMPORTANCE = "importance"; + public final static String DEFAULT = "default"; + public final static String LOW = "low"; + public final static String MEDIA = "media"; + + @RequiresApi(api = Build.VERSION_CODES.O) + public static void createAllNotificationChannels(Context context) { + NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + + if (nm == null) { + return; + } + + NotificationChannel mediaChannel = new NotificationChannel( + MEDIA, + context.getString(R.string.channel_media), + NotificationManager.IMPORTANCE_DEFAULT); + mediaChannel.setSound(null, null); + mediaChannel.setVibrationPattern(null); + + nm.createNotificationChannels(Arrays.asList( + new NotificationChannel( + CRITICAL, + context.getString(R.string.channel_critical), + NotificationManager.IMPORTANCE_HIGH), + new NotificationChannel( + IMPORTANCE, + context.getString(R.string.channel_importance), + NotificationManager.IMPORTANCE_DEFAULT), + new NotificationChannel( + DEFAULT, + context.getString(R.string.channel_default), + NotificationManager.IMPORTANCE_LOW), + new NotificationChannel( + LOW, + context.getString(R.string.channel_low), + NotificationManager.IMPORTANCE_MIN), + //custom notification channel + mediaChannel + )); + } +} diff --git a/sample/src/main/java/com/wenming/notify/notification/NotificationContentWrapper.java b/sample/src/main/java/com/wenming/notify/notification/NotificationContentWrapper.java new file mode 100644 index 0000000..8ce0172 --- /dev/null +++ b/sample/src/main/java/com/wenming/notify/notification/NotificationContentWrapper.java @@ -0,0 +1,16 @@ +package com.wenming.notify.notification; + +import android.graphics.Bitmap; + + +public class NotificationContentWrapper { + public Bitmap bitmap; + public String title; + public String summery; + + public NotificationContentWrapper(Bitmap bitmap, String title, String summery) { + this.bitmap = bitmap; + this.title = title; + this.summery = summery; + } +} diff --git a/sample/src/main/java/com/wenming/notify/notification/NotificationService.java b/sample/src/main/java/com/wenming/notify/notification/NotificationService.java new file mode 100644 index 0000000..c502762 --- /dev/null +++ b/sample/src/main/java/com/wenming/notify/notification/NotificationService.java @@ -0,0 +1,207 @@ +package com.wenming.notify.notification; + +import android.app.NotificationManager; +import android.app.RemoteInput; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.graphics.BitmapFactory; +import android.os.Build; +import android.os.Bundle; +import android.os.IBinder; +import android.support.annotation.Nullable; +import android.support.annotation.RequiresApi; +import android.util.Log; + +import com.wenming.notify.BuildConfig; +import com.wenming.notify.R; + +import java.util.ArrayList; +import java.util.List; + +public class NotificationService extends Service { + private final static String TAG = "NotificationService"; + + public final static String ACTION_SEND_PROGRESS_NOTIFICATION = BuildConfig.APPLICATION_ID + ".ACTION_SEND_PROGRESS_NOTIFICATION"; + + private Context mContext; + private NotificationManager mNM; + private boolean mIsLoved; + private boolean mIsPlaying = true; + + private List mContent = new ArrayList<>(); + private int mCurrentPosition = 1; + + @Override + public void onCreate() { + super.onCreate(); + mContext = this; + mNM = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + + initNotificationContent(); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + if (intent != null && intent.getAction() != null) { + Log.i(TAG, "onStartCommand action = " + intent.getAction()); + switch (intent.getAction()) { + case Notificaitons.ACTION_SIMPLE: + break; + case Notificaitons.ACTION_ACTION: + break; + case Notificaitons.ACTION_REMOTE_INPUT: + break; + case Notificaitons.ACTION_BIG_PICTURE_STYLE: + break; + case Notificaitons.ACTION_BIG_TEXT_STYLE: + break; + case Notificaitons.ACTION_INBOX_STYLE: + break; + case Notificaitons.ACTION_MEDIA_STYLE: + dealWithActionMediaStyle(intent); + break; + case Notificaitons.ACTION_MESSAGING_STYLE: + break; + case Notificaitons.ACTION_YES: + case Notificaitons.ACTION_NO: + mNM.cancel(Notificaitons.NOTIFICATION_ACTION); + break; + case Notificaitons.ACTION_DELETE: + break; + case Notificaitons.ACTION_REPLY: + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { + dealWithActionReplay(intent); + } + break; + case Notificaitons.ACTION_PROGRESS: + break; + case ACTION_SEND_PROGRESS_NOTIFICATION: + dealWithActionSendProgressNotification(); + break; + case Notificaitons.ACTION_CUSTOM_HEADS_UP_VIEW: + dealWithActionCustomHeadsUpView(intent); + break; + case Notificaitons.ACTION_CUSTOM_VIEW: + break; + case Notificaitons.ACTION_CUSTOM_VIEW_OPTIONS_LOVE: + Notificaitons.getInstance().sendCustomViewNotification(this, mNM, mContent.get(mCurrentPosition), !mIsLoved, mIsPlaying); + mIsLoved = !mIsLoved; + break; + case Notificaitons.ACTION_CUSTOM_VIEW_OPTIONS_PRE: + --mCurrentPosition; + Notificaitons.getInstance().sendCustomViewNotification(this, mNM, getNotificationContent(), mIsLoved, mIsPlaying); + break; + case Notificaitons.ACTION_CUSTOM_VIEW_OPTIONS_PLAY_OR_PAUSE: + Notificaitons.getInstance().sendCustomViewNotification(this, mNM, mContent.get(mCurrentPosition), mIsLoved, !mIsPlaying); + mIsPlaying = !mIsPlaying; + break; + case Notificaitons.ACTION_CUSTOM_VIEW_OPTIONS_NEXT: + ++mCurrentPosition; + Notificaitons.getInstance().sendCustomViewNotification(this, mNM, getNotificationContent(), mIsLoved, mIsPlaying); + break; + case Notificaitons.ACTION_CUSTOM_VIEW_OPTIONS_LYRICS: + break; + case Notificaitons.ACTION_CUSTOM_VIEW_OPTIONS_CANCEL: + mNM.cancel(Notificaitons.NOTIFICATION_CUSTOM); + break; + default: + //do nothing + } + } + return START_STICKY; + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } + + private void initNotificationContent() { + mContent.clear(); + mContent.add(new NotificationContentWrapper(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.custom_view_picture_pre), "远走高飞", "金志文")); + mContent.add(new NotificationContentWrapper(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.custom_view_picture_current), "最美的期待", "周笔畅 - 最美的期待")); + mContent.add(new NotificationContentWrapper(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.custom_view_picture_next), "你打不过我吧", "跟风超人")); + } + + private void dealWithActionMediaStyle(Intent intent) { + String option = intent.getStringExtra(Notificaitons.EXTRA_OPTIONS); + Log.i(TAG, "media option = " + option); + if (option == null) { + return; + } + switch (option) { + case Notificaitons.MEDIA_STYLE_ACTION_PAUSE: + Notificaitons.getInstance().sendMediaStyleNotification(this, mNM, false); + break; + case Notificaitons.MEDIA_STYLE_ACTION_PLAY: + Notificaitons.getInstance().sendMediaStyleNotification(this, mNM, true); + break; + case Notificaitons.MEDIA_STYLE_ACTION_NEXT: + break; + case Notificaitons.MEDIA_STYLE_ACTION_DELETE: + mNM.cancel(Notificaitons.NOTIFICATION_MEDIA_STYLE); + break; + default: + //do nothing + } + } + + @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) + private void dealWithActionReplay(Intent intent) { + Bundle result = RemoteInput.getResultsFromIntent(intent); + if (result != null) { + String content = result.getString(Notificaitons.REMOTE_INPUT_RESULT_KEY); + Log.i(TAG, "content = " + content); + mNM.cancel(Notificaitons.NOTIFICATION_REMOTE_INPUT); + } + } + + private void dealWithActionSendProgressNotification() { + new Thread(new Runnable() { + @Override + public void run() { + for (int i = 0; i <= 100; i++) { + Notificaitons.getInstance().sendProgressViewNotification(mContext, mNM, i); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }).start(); + } + + private void dealWithActionCustomHeadsUpView(Intent intent) { + String headsUpOption = intent.getStringExtra(Notificaitons.EXTRA_OPTIONS); + Log.i(TAG, "heads up option = " + headsUpOption); + if (headsUpOption == null) { + return; + } + switch (headsUpOption) { + case Notificaitons.ACTION_ANSWER: + case Notificaitons.ACTION_REJECT: + mNM.cancel(Notificaitons.NOTIFICATION_CUSTOM_HEADS_UP); + break; + default: + //do nothing + } + } + + private NotificationContentWrapper getNotificationContent() { + switch (mCurrentPosition) { + case -1: + mCurrentPosition = 2; + break; + case 3: + mCurrentPosition = 0; + break; + default: + // do nothing + } + + return mContent.get(mCurrentPosition); + } +} diff --git a/sample/src/main/res/drawable-xhdpi/image1.PNG b/sample/src/main/res/drawable-xhdpi/image1.PNG index c396855..5f2bada 100644 Binary files a/sample/src/main/res/drawable-xhdpi/image1.PNG and b/sample/src/main/res/drawable-xhdpi/image1.PNG differ diff --git a/sample/src/main/res/drawable-xhdpi/image2.PNG b/sample/src/main/res/drawable-xhdpi/image2.PNG index a79acdf..c5654d7 100644 Binary files a/sample/src/main/res/drawable-xhdpi/image2.PNG and b/sample/src/main/res/drawable-xhdpi/image2.PNG differ diff --git a/sample/src/main/res/drawable-xhdpi/image3.PNG b/sample/src/main/res/drawable-xhdpi/image3.PNG index d41f302..d86d87f 100644 Binary files a/sample/src/main/res/drawable-xhdpi/image3.PNG and b/sample/src/main/res/drawable-xhdpi/image3.PNG differ diff --git a/sample/src/main/res/drawable-xhdpi/image4.PNG b/sample/src/main/res/drawable-xhdpi/image4.PNG index 00f0a21..2b8c3c1 100644 Binary files a/sample/src/main/res/drawable-xhdpi/image4.PNG and b/sample/src/main/res/drawable-xhdpi/image4.PNG differ diff --git a/sample/src/main/res/drawable-xhdpi/image5.PNG b/sample/src/main/res/drawable-xhdpi/image5.PNG index 8d4d691..203a242 100644 Binary files a/sample/src/main/res/drawable-xhdpi/image5.PNG and b/sample/src/main/res/drawable-xhdpi/image5.PNG differ diff --git a/sample/src/main/res/drawable-xhdpi/image6.PNG b/sample/src/main/res/drawable-xhdpi/image6.PNG index b51ad5f..d1bdd71 100644 Binary files a/sample/src/main/res/drawable-xhdpi/image6.PNG and b/sample/src/main/res/drawable-xhdpi/image6.PNG differ diff --git a/sample/src/main/res/drawable-xhdpi/image7.PNG b/sample/src/main/res/drawable-xhdpi/image7.PNG index 137f9d3..cc210cf 100644 Binary files a/sample/src/main/res/drawable-xhdpi/image7.PNG and b/sample/src/main/res/drawable-xhdpi/image7.PNG differ diff --git a/sample/src/main/res/drawable-xhdpi/image8.PNG b/sample/src/main/res/drawable-xhdpi/image8.PNG index 22a41c4..1c9a44f 100644 Binary files a/sample/src/main/res/drawable-xhdpi/image8.PNG and b/sample/src/main/res/drawable-xhdpi/image8.PNG differ diff --git a/sample/src/main/res/drawable-xhdpi/image9.PNG b/sample/src/main/res/drawable-xhdpi/image9.PNG index 85a3fa3..1dd4057 100644 Binary files a/sample/src/main/res/drawable-xhdpi/image9.PNG and b/sample/src/main/res/drawable-xhdpi/image9.PNG differ diff --git a/sample/src/main/res/drawable-xhdpi/showdemo.PNG b/sample/src/main/res/drawable-xhdpi/showdemo.PNG index 22db4d3..807d756 100644 Binary files a/sample/src/main/res/drawable-xhdpi/showdemo.PNG and b/sample/src/main/res/drawable-xhdpi/showdemo.PNG differ diff --git a/sample/src/main/res/drawable-xxhdpi/big_style_picture.jpg b/sample/src/main/res/drawable-xxhdpi/big_style_picture.jpg new file mode 100644 index 0000000..86598af Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/big_style_picture.jpg differ diff --git a/sample/src/main/res/drawable-xxhdpi/custom_view_picture_current.jpg b/sample/src/main/res/drawable-xxhdpi/custom_view_picture_current.jpg new file mode 100644 index 0000000..fe051ec Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/custom_view_picture_current.jpg differ diff --git a/sample/src/main/res/drawable-xxhdpi/custom_view_picture_next.jpeg b/sample/src/main/res/drawable-xxhdpi/custom_view_picture_next.jpeg new file mode 100644 index 0000000..754bc64 Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/custom_view_picture_next.jpeg differ diff --git a/sample/src/main/res/drawable-xxhdpi/custom_view_picture_placeholder.png b/sample/src/main/res/drawable-xxhdpi/custom_view_picture_placeholder.png new file mode 100644 index 0000000..0940ef5 Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/custom_view_picture_placeholder.png differ diff --git a/sample/src/main/res/drawable-xxhdpi/custom_view_picture_pre.jpeg b/sample/src/main/res/drawable-xxhdpi/custom_view_picture_pre.jpeg new file mode 100644 index 0000000..e064026 Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/custom_view_picture_pre.jpeg differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_answer.png b/sample/src/main/res/drawable-xxhdpi/ic_answer.png new file mode 100644 index 0000000..1098b7f Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/ic_answer.png differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_delete.png b/sample/src/main/res/drawable-xxhdpi/ic_delete.png new file mode 100644 index 0000000..18ea046 Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/ic_delete.png differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_love.png b/sample/src/main/res/drawable-xxhdpi/ic_love.png new file mode 100644 index 0000000..c8774a0 Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/ic_love.png differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_loved.png b/sample/src/main/res/drawable-xxhdpi/ic_loved.png new file mode 100644 index 0000000..cf783bc Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/ic_loved.png differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_lyc.png b/sample/src/main/res/drawable-xxhdpi/ic_lyc.png new file mode 100644 index 0000000..4fddf6d Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/ic_lyc.png differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_next.png b/sample/src/main/res/drawable-xxhdpi/ic_next.png new file mode 100644 index 0000000..58f484f Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/ic_next.png differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_no.png b/sample/src/main/res/drawable-xxhdpi/ic_no.png new file mode 100644 index 0000000..2c2d5f9 Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/ic_no.png differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_notifiation_big.png b/sample/src/main/res/drawable-xxhdpi/ic_notifiation_big.png new file mode 100644 index 0000000..8ccc35b Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/ic_notifiation_big.png differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_notification.png b/sample/src/main/res/drawable-xxhdpi/ic_notification.png new file mode 100644 index 0000000..4140912 Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/ic_notification.png differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_pause.png b/sample/src/main/res/drawable-xxhdpi/ic_pause.png new file mode 100644 index 0000000..09322a3 Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/ic_pause.png differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_play.png b/sample/src/main/res/drawable-xxhdpi/ic_play.png new file mode 100644 index 0000000..a9ea4fb Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/ic_play.png differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_pre.png b/sample/src/main/res/drawable-xxhdpi/ic_pre.png new file mode 100644 index 0000000..b34bae4 Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/ic_pre.png differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_reject.png b/sample/src/main/res/drawable-xxhdpi/ic_reject.png new file mode 100644 index 0000000..a034d8e Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/ic_reject.png differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_reply.png b/sample/src/main/res/drawable-xxhdpi/ic_reply.png new file mode 100644 index 0000000..5c6b48f Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/ic_reply.png differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_yes.png b/sample/src/main/res/drawable-xxhdpi/ic_yes.png new file mode 100644 index 0000000..b40fafd Binary files /dev/null and b/sample/src/main/res/drawable-xxhdpi/ic_yes.png differ diff --git a/sample/src/main/res/layout/activity_launch.xml b/sample/src/main/res/layout/activity_launch.xml new file mode 100644 index 0000000..3287846 --- /dev/null +++ b/sample/src/main/res/layout/activity_launch.xml @@ -0,0 +1,14 @@ + + + + + + diff --git a/sample/src/main/res/layout/custom_big_view_layout.xml b/sample/src/main/res/layout/custom_big_view_layout.xml new file mode 100644 index 0000000..82d9011 --- /dev/null +++ b/sample/src/main/res/layout/custom_big_view_layout.xml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sample/src/main/res/layout/custom_heads_up_layout.xml b/sample/src/main/res/layout/custom_heads_up_layout.xml new file mode 100644 index 0000000..6804efa --- /dev/null +++ b/sample/src/main/res/layout/custom_heads_up_layout.xml @@ -0,0 +1,33 @@ + + + + + + \ No newline at end of file diff --git a/sample/src/main/res/layout/custom_view_layout.xml b/sample/src/main/res/layout/custom_view_layout.xml new file mode 100644 index 0000000..e34e343 --- /dev/null +++ b/sample/src/main/res/layout/custom_view_layout.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sample/src/main/res/layout/fragment_two.xml b/sample/src/main/res/layout/fragment_two.xml new file mode 100644 index 0000000..be31e7f --- /dev/null +++ b/sample/src/main/res/layout/fragment_two.xml @@ -0,0 +1,106 @@ + + + + + +