[英]ChatHead Service is Not Working in Lollipop and Marshmallow on Nexus devices
I am Working on a service which will draw a overlay icon on some predefined applications eg WhatsApp, FB Messenger, Instagram etc. we set their packages predefined so that our service can detect. 我正在开发一种服务,它将在一些预定义的应用程序上绘制一个叠加图标,例如WhatsApp,FB Messenger,Instagram等。我们将它们的软件包预先设置好,以便我们的服务可以检测到。
*Its Working Totally Fine on till 19API (Before and Equal to Kitkat Api level) *它的工作完全没问题直到19API(之前和等于Kitkat Api水平)
But its not working on Lollipop and Marshmallow we are testing on Nexus 5,6,5x,6p and Hawaii Devices P8. 但是它没有在Lollipop和Marshmallow上工作,我们正在测试Nexus 5,6,5x,6p和Hawaii Devices P8。
in these devices we got error E/Surface: getSlotFromBufferLocked: unknown buffer: 0x9db36030
在这些设备中我们得到错误
E/Surface: getSlotFromBufferLocked: unknown buffer: 0x9db36030
Don't Know what does it mean and what the issue behind. 不知道它的含义是什么,背后的问题是什么。 Please Help me Here is my Service Code below
请帮帮我以下是我的服务代码
public class ChatHeadService extends Service implements OnClickListener { 公共类ChatHeadService extends Service实现OnClickListener {
private WindowManager windowManager;
private ImageView chatHead;
private LayoutParams params;
private Context context;
private BroadcastReceiver mReceiver;
private OnTouchListener mOnTouchlistener;
private Runnable handleIconVisibility;
private Handler mHandler;
private boolean mIsIconAttached;
public final String TAG = "CRAR";
private String mIm;
public ChatHeadService() {
handleIconVisibility = new Runnable() {
@Override
public void run() {
if (getResumedStatus()) {
addTopIcon();
} else {
removeTopIcon();
}
mHandler.postDelayed(handleIconVisibility, 500L);
}
};
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(
"android.intent.action.SCREEN_OFF")) {
stopTick();
} else if (intent.getAction().equals(
"android.intent.action.SCREEN_ON")) {
startTick();
}
}
};
mOnTouchlistener = new OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
// switch (event.getAction()) {
// case MotionEvent.ACTION_DOWN:
// initialX = params.x;
// initialY = params.y;
// initialTouchX = event.getRawX();
// initialTouchY = event.getRawY();
// case MotionEvent.ACTION_UP:
// case MotionEvent.ACTION_MOVE:
// params.x = initialX
// + (int) (event.getRawX() - initialTouchX);
// params.y = initialY
// + (int) (event.getRawY() - initialTouchY);
// windowManager.updateViewLayout(chatHead, params);
// }
Intent intent = new Intent(context, HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("im_name", mIm);
context.startActivity(intent);
return true;
}
};
}
private String[] getActivePackages() {
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
final Set<String> activePackages = new HashSet<String>();
final List<ActivityManager.RunningAppProcessInfo> processInfos = am
.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo processInfo : processInfos) {
if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
activePackages.addAll(Arrays.asList(processInfo.pkgList));
}
}
return activePackages.toArray(new String[activePackages.size()]);
}
private boolean isImResumedForLollipop() {
String[] activePackages = getActivePackages();
if (activePackages != null) {
for (String activePackage : activePackages) {
// WhatsApp
if (activePackage.equals("com.whatsapp")
|| activePackage.equals("com.whatsapp.HomeActivity")
|| activePackage.equals("com.whatsapp.Conversation")) {
mIm = activePackage;
return true;
}
// Viber
if (activePackage.equals("com.viber.voip")) {
mIm = activePackage;
return true;
}
// WeChat
if (activePackage.equals("com.tencent.mm")) {
mIm = activePackage;
return true;
}
// Facebook Massenger
if (activePackage
.equals("com.facebook.orca.auth.StartScreenActivity")
|| activePackage
.equals("com.facebook.orca.creation.CreateThreadActivity")
|| activePackage
.equals("com.facebook.messenger.neue.MainActivity")
|| activePackage
.equals("com.facebook.orca.threadview.ThreadViewActivity")) {
mIm = activePackage;
return true;
}
// Tango
if (activePackage.equals("com.sgiggle.production")) {
mIm = activePackage;
return true;
}
// MMS
if (activePackage.equalsIgnoreCase("com.android.mms")) {
mIm = activePackage;
return true;
}
// Textra
if (activePackage.equals("com.textra")) {
mIm = activePackage;
return true;
}
// Hangout
if (activePackage.equals("com.google.android.talk")) {
mIm = activePackage;
return true;
}
// Line
if (activePackage.equals("jp.naver.line.android")) {
mIm = activePackage;
return true;
}
// IMO
if (activePackage.equals("com.imo.android.imoim")) {
mIm = activePackage;
return true;
}
// SKYPE
if (activePackage.equals("com.skype.raider")) {
mIm = activePackage;
return true;
}
// KIK
if (activePackage.equals("kik.android")) {
mIm = activePackage;
return true;
}
// Google Messenger
if (activePackage.equals("com.google.android.apps.messaging")) {
mIm = activePackage;
return true;
}
// Instagram
if (activePackage.equals("com.instagram.android")
|| activePackage.equals("com.instagram.selfupdate")
|| activePackage
.equals("com.instagram.android.activity.MainTabActivity")) {
mIm = activePackage;
return true;
}
// YAHOO Messenger
if (activePackage.equals("com.yahoo.mobile.client.android.im")) {
mIm = activePackage;
return true;
}
// HIKE
if (activePackage.equals("com.bsb.hike")) {
mIm = activePackage;
return true;
}
// BBM
if (activePackage.equals("com.bbm")) {
mIm = activePackage;
return true;
}
// ICQ
if (activePackage.equals("com.icq.mobile.client")) {
mIm = activePackage;
return true;
}
// Nimbuzz
if (activePackage.equals("com.nimbuzz")) {
mIm = activePackage;
return true;
}
// Twitter
if (activePackage.equals("com.twitter.android")
|| activePackage
.equals("com.twitter.android.DMActivity")) {
mIm = activePackage;
return true;
}
}
}
return false;
}
private boolean getResumedStatus() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {
return isImResumedForLollipop();
} else {
return isImResumed();
}
}
@SuppressWarnings("deprecation")
private boolean isImResumed() {
try {
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> alltasks = am
.getRunningTasks(1);
for (ActivityManager.RunningTaskInfo aTask : alltasks) {
Log.d("TAG", aTask.topActivity.getClassName());
Log.d("TAG", aTask.topActivity.getPackageName());
String className = aTask.topActivity.getClassName();
// WhatsApp
if (className.equals("com.whatsapp.Conversation")
|| className.equals("com.whatsapp")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// Viber
if (className
.equals("com.viber.voip.messages.ui.ConversationActivity")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// WeChat
if (className.equals("com.tencent.mm.ui.LauncherUI")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// Facebook Massenger
if (className
.equals("com.facebook.orca.auth.StartScreenActivity")
|| className
.equals("com.facebook.orca.creation.CreateThreadActivity")
|| className
.equals("com.facebook.messenger.neue.MainActivity")
|| className
.equals("com.facebook.orca.threadview.ThreadViewActivity")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// Tango
if (className
.equals("com.sgiggle.app.screens.tc.ConversationDetailActivitySWIG")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// MMS
if (aTask.topActivity.getPackageName().equalsIgnoreCase(
"com.android.mms")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// Textra
if (className.equals("com.mplus.lib.ui.main.Main")
|| className
.equals("com.mplus.lib.ui.convo.ConvoActivity")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// Hangout
if (className
.equals("com.google.android.apps.hangouts.phone.ConversationActivity")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// Line
if (className
.equals("jp.naver.line.android.activity.chathistory.ChatHistoryActivity")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// IMO
if (className
.equals("com.imo.android.imoim.activities.IMActivity")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// SKYPE
if (className.equals("com.skype.android.app.chat.ChatActivity")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// KIK
if (className.equals("kik.android.chat.activity.ChatActivity")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// Google Messenger
if (className
.equals("com.google.android.apps.messaging.ui.ConversationListActivity")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// Instagram
if (className
.equals("com.instagram.android.activity.MainTabActivity")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// YAHOO Messenger
if (className
.equals("com.yahoo.mobile.client.android.im.ConversationActivity")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// HIKE
if (className
.equals("com.bsb.hike.chatthread.ChatThreadActivity")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// BBM
if (className.equals("com.bbm.ui.activities.MainActivity")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// ICQ
if (className
.equals("ru.mail.instantmessanger.flat.chat.IcqFlatChatActivity")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// Nimbuzz
if (className.equals("com.nimbuzz.ChatView")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
// Twitter
if (className.equals("com.twitter.android")
|| className.equals("com.twitter.android.DMActivity")) {
mIm = aTask.topActivity.getPackageName();
return true;
}
}
} catch (Throwable t) {
Log.i(TAG, "Throwable caught: " + t.getMessage(), t);
}
return false;
}
private void addTopIcon() {
if (mIsIconAttached) {
return;
} else {
drawIconView();
mIsIconAttached = true;
return;
}
}
@SuppressLint("RtlHardcoded")
private void drawIconView() {
params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, LayoutParams.TYPE_PHONE,
LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
if (mIm.equalsIgnoreCase("com.twitter.android")
|| mIm.equals("com.twitter.android.composer.ComposerActivity")) {
params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
params.y = 10;
params.x = -160;
} else {
params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
params.y = 10;
}
windowManager.addView(chatHead, params);
}
@SuppressLint("RtlHardcoded")
private void reDrawIconView() {
int i = getResources().getConfiguration().orientation;
Log.d("TAG", "" + i);
params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, LayoutParams.TYPE_PHONE,
LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
params.y = 10;
windowManager.updateViewLayout(chatHead, params);
}
private void removeTopIcon() {
if (!mIsIconAttached) {
return;
} else {
removeIconView();
mIsIconAttached = false;
return;
}
}
private void removeIconView() {
if (windowManager != null && chatHead != null) {
windowManager.removeViewImmediate(chatHead);
return;
}
}
private void stopTick() {
if (mHandler != null) {
mHandler.removeCallbacks(handleIconVisibility);
return;
} else {
Log.d("TAG", "mHandler is null");
return;
}
}
private void startTick() {
if (mHandler != null) {
mHandler.removeCallbacks(handleIconVisibility);
mHandler.postDelayed(handleIconVisibility, 1000L);
return;
} else {
Log.d("TAG", "mHandler is null");
return;
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (mIsIconAttached) {
reDrawIconView();
}
super.onConfigurationChanged(newConfig);
}
private void init() {
chatHead = new ImageView(context);
chatHead.setImageResource(R.drawable.chat_head);
chatHead.setOnTouchListener(mOnTouchlistener);
Log.e("Chat head", "On touch listner triggered");
chatHead.setOnClickListener(this);
Log.e("Chat head", "click listner triggered");
mHandler = new Handler();
}
private void registerIntentReceiver() {
IntentFilter intentfilter = new IntentFilter();
intentfilter.addAction("android.intent.action.SCREEN_ON");
intentfilter.addAction("android.intent.action.SCREEN_OFF");
registerReceiver(mReceiver, intentfilter);
}
private void unregisterIntentReceiver() {
unregisterReceiver(mReceiver);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
context = this;
registerIntentReceiver();
init();
super.onCreate();
}
@Override
public void onDestroy() {
stopTick();
unregisterIntentReceiver();
mHandler = null;
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startTick();
return START_STICKY;
}
@Override
public void onClick(View v) {
Log.e("Chat head", "on clickview function triggerd complete");
}
} }
Any Help would be great... 任何帮助都会很棒......
For Lollipop: 对于棒棒糖:
it works for me. 这个对我有用。 But You have to add this permission in your mainfest.
但您必须在主要节目中添加此权限。
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Anyway you can check if you got the permission before drowing: 无论如何,你可以在投掷之前检查你是否获得了许可:
if (Settings.canDrawOverlays(context)) {
// Here you go, you can draw you chathead view
}
For Marshmallow 对于棉花糖
Since it needs an extra permission, It does not work directly. 由于它需要额外的许可,因此无法直接使用。 I tried to find the settings and send user there.
我试图找到设置并在那里发送用户。 I found that you can send the user from your app directly to the permission page in the settings with this intent .
我发现您可以通过此意图将用户从您的应用程序直接发送到设置中的权限页面。
ACTION_MANAGE_OVERLAY_PERMISSION
montioned on in the documentation of Settings.canDrawOverlays(context) page 在Settings.canDrawOverlays(context)页面的文档中提到了
this may be helpful for you: 这可能对你有所帮助:
Android System overlay window - StackOverflow Android系统覆盖窗口 - StackOverflow
UPDATE: This is the documentation of canDrawOverlays : 更新:这是canDrawOverlays的文档:
Checks if the specified context can draw on top of other apps.
检查指定的上下文是否可以在其他应用程序之上绘制。 As of API level 23, an app cannot draw on top of other apps unless it declares the SYSTEM_ALERT_WINDOW permission in its manifest, and the user specifically grants the app this capability.
从API级别23开始,应用程序无法在其他应用程序之上绘制,除非它在其清单中声明了SYSTEM_ALERT_WINDOW权限,并且用户专门授予应用程序此功能。 To prompt the user to grant this approval, the app must send an intent with the action ACTION_MANAGE_OVERLAY_PERMISSION, which causes the system to display a permission management screen.
要提示用户授予此批准,应用程序必须使用操作ACTION_MANAGE_OVERLAY_PERMISSION发送意图,这会导致系统显示权限管理屏幕。
Settings.canDrawOverlays(context) documentation Settings.canDrawOverlays(context)文档
Hope this helps. 希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.