WindowManager addview无法在GcmListenerService中使用

时间:2015-09-23 14:08:31

标签: android google-cloud-messaging handler window-managers looper

我正在尝试构建一个应用程序,当从Google的GCM服务器接收GCM消息时,我可以在屏幕顶部显示通知,如Facebook的应用程序Messenger。

我的问题是: 代码

windowManager.addView(chatHead, params);
函数addView()中的

即使被调用也没有效果。 有谁知道问题是什么?谢谢你的帮助!

以下是我如何构建应用的详细信息:

首先我跟随 How to make a Facebook Messenger-like notification like this in Android

我已经通过创建一个新服务测试了函数“addView()”并在onCreate()中调用它并且它确实有效。 (即使我的活动暂停,它也会在我的HTC屏幕上显示一个图像。)

public void addView(){
    windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);

    chatHead = new ImageView(this);
    chatHead.setImageResource(R.drawable.climia);
    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);
    params.gravity = Gravity.TOP | Gravity.LEFT;
    params.x = 0;
    params.y = 0;

    windowManager.addView(chatHead, params);
    Log.i("addview","after windowManager.addView");
}

其次,我遇到了“GcmListenerService”没有任何looper来处理UI更新的问题;因此,我跟随 https://github.com/quakerntj/SendMesageToPhoneByGCM/blob/master/src/com/ntj/GcmTest/MyGcmListenerService.java 添加处理程序和循环程序来处理WindowManager。

class MyThread extends Thread {
    private Context mContext = null;
    private Handler mHandler = null;

    public MyThread(String s, Context context) {
        super(s);
        this.mContext = context;
    }
    public void setMessage(String message) {
        Message msg = Message.obtain(mHandler, 0, message);
        mHandler.sendMessage(msg);
    }
    @Override
    public void run() {
        Looper.prepare();
        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                Log.i("Handler", "start handleMessage");
                addView();
                getLooper().quit();
            }
        };
        Looper.loop();
    }
}

第三,我使用上面创建的线程在我的应用收到GCM消息时触发addView:

@Override
public void onMessageReceived(String from, Bundle data) {
    GCMData GCMdata = new GCMData();

    GCMdata.title = data.getString("title");
    GCMdata.body = data.getString("body");
    GCMdata.detail  = data.getString("detail");
    GCMdata.type  = data.getString("type");
 /*
     show a notification indicating to the user
     */ sendNotification(GCMdata);

    mThread = new MyThread("nitamaGCM", this);
    mThread.start();
    synchronized (this) {
        try {
            // Wait the looper begin
            wait(10);
        } catch (InterruptedException e) {
        }
    }
    mThread.setMessage(GCMdata.body);
}

PS:整个源代码如下:

public class MyGcmListenerService extends GcmListenerService {

public class GCMData{
    String title;
    String body;
    String detail;
    String type;
}

private static final String TAG = "MyGcmListenerService";
private WindowManager windowManager;
private ImageView chatHead;

private MyThread mThread = null;
/**
 * Called when message is received.
 *
 * @param from SenderID of the sender.
 * @param data Data bundle containing message data as key/value pairs.
 *             For Set of keys use data.keySet().
 */
// [START receive_message]
@Override
public void onMessageReceived(String from, Bundle data) {
    GCMData GCMdata = new GCMData();

    GCMdata.title = data.getString("title");
    GCMdata.body = data.getString("body");
    GCMdata.detail  = data.getString("detail");
    GCMdata.type  = data.getString("type");
 /*
     show a notification indicating to the user
     */ sendNotification(GCMdata);

    mThread = new MyThread("nitamaGCM", this);
    mThread.start();
    synchronized (this) {
        try {
            // Wait the looper begin
            wait(10);
        } catch (InterruptedException e) {
        }
    }
    mThread.setMessage(GCMdata.body);
}
// [END receive_message]

/**
 * Create and show a simple notification containing the received GCM message.
 *
 * @param message GCM message received.
 */
private void sendNotification(GCMData GCMdata) {

    Intent intent = new Intent(this, MainActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(
            this,
            0 /* Request code */,
            intent,
            PendingIntent.FLAG_ONE_SHOT
    );

    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.climia)                //required, small icon in notification area
            .setContentTitle(GCMdata.title)                      //required, notification title in notification drawer
            .setContentText(GCMdata.body)             //required, notification content in notification drawer
            .setContentInfo(GCMdata.detail)
            .setAutoCancel(true)                            //after clicking notification, dismiss notification
                    .setSound(defaultSoundUri)
            .setVibrate(new long[]{0, 100, 100, 200})   //Vibrate   format:  stop, vibrate, stop, vibrate, ...   unit: 1/1000 s
            //.setDeleteIntent(pendingIntent)                                        //trigger intent when the notification is cleared explicitly by the user
            .setContentIntent(pendingIntent)
            .setOnlyAlertOnce(true);                    //same notification ID  will not Vibrate or Sound again

    NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    notificationManager.notify(
            Integer.parseInt(GCMdata.type) /* ID of notification */,
            notificationBuilder.build());
}
public void addView(){
    windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);

    chatHead = new ImageView(this);
    chatHead.setImageResource(R.drawable.climia);
    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);
    params.gravity = Gravity.TOP | Gravity.LEFT;
    params.x = 0;
    params.y = 0;

    windowManager.addView(chatHead, params);
    Log.i("addview","after windowManager.addView");
}

class MyThread extends Thread {
    private Context mContext = null;
    private Handler mHandler = null;

    public MyThread(String s, Context context) {
        super(s);
        this.mContext = context;
    }
    public void setMessage(String message) {
        Message msg = Message.obtain(mHandler, 0, message);
        mHandler.sendMessage(msg);
    }
    @Override
    public void run() {
        Looper.prepare();
        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                Log.i("Handler", "start handleMessage");
                addView();
                getLooper().quit();
            }
        };
        Looper.loop();
    }
}}

0 个答案:

没有答案