API apa yang digunakan untuk menarik aplikasi lain (seperti Kepala Obrolan Facebook)?

226

Bagaimana cara Facebook membuat Kepala Obrolan di Android? Apa API untuk membuat tampilan mengambang di atas semua tampilan lainnya?

Daniel A. White
sumber
6
Aplikasi ini juga memiliki "Kepala Obrolan" play.google.com/store/apps/details?id=com.ninja.sms
Oli
11
Jika Anda mencari contoh, lihat github.com/marshallino16/FloatingNotification
marshallino16
5
Anda dapat menemukan demo dan perpustakaan sederhana di sini: github.com/ericbhatti/floaties Menggunakan perpustakaan ini, Anda dapat membuat jendela apung hanya dengan 2 baris.
Eric B.

Jawaban:

217

Ini :

Mengizinkan aplikasi membuka windows menggunakan tipe TYPE_SYSTEM_ALERT, yang ditunjukkan di atas semua aplikasi lain. Sangat sedikit aplikasi yang harus menggunakan izin ini; windows ini dimaksudkan untuk interaksi tingkat sistem dengan pengguna.

Nilai Konstan: "android.permission.SYSTEM_ALERT_WINDOW"

// EDIT: Kode lengkap di sini :

public class ChatHeadService extends Service {

  private WindowManager windowManager;
  private ImageView chatHead;

  @Override public IBinder onBind(Intent intent) {
    // Not used
    return null;
  }

  @Override public void onCreate() {
    super.onCreate();

    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

    chatHead = new ImageView(this);
    chatHead.setImageResource(R.drawable.android_head);

    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 = 100;

    windowManager.addView(chatHead, params);
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    if (chatHead != null) windowManager.removeView(chatHead);
  }
}

Jangan lupa untuk memulai layanan entah bagaimana:

startService(new Intent(context, ChatHeadService.class));

.. Dan tambahkan layanan ini ke Manifest Anda.

Waza_Be
sumber
4
Ada banyak hal aneh, saya pikir. Bagaimana dengan penanganan input di luar "head" serta dragability? Saya pikir Anda setidaknya perlu FLAG_NOT_TOUCH_MODAL , serta beberapa logika pintar untuk memperbarui atribut Window (yaitu, pindahkan) saat Anda menyeretnya.
Delyan
2
bagaimana cara menghapus obrolan-kepala?
Nirav Mehta
6
Mengira layak menyebutkan SDK yang saya kembangkan untuk membuat UI mengambang: www.tooleap.com
Arik
@NiravMehta Apakah Anda dapat menghapus kepala obrolan?
KK_07k11A0585
cara menghapus margin kepala obrolan. Karena dalam kode di atas output lingkaran memiliki beberapa ruang dari perbatasan. Di Facebook gelembung tidak memiliki ruang itu
Debugger
51

Sebagai aturan, kegiatan Android adalah layar penuh, UI berdedikasi konseptual yang mengambil semua interaksi. Ada beberapa pengecualian untuk ini. Sebagai permulaan, ada dialog sembulan yang tidak memenuhi layar. Lainnya adalah roti bakar Android, yang merupakan sembulan non-interaktif - Anda tidak dapat menyentuhnya, dan jika Anda mencobanya akan menuju ke apa pun yang ada di bawahnya.

Anda juga dapat melakukan UI khusus Anda sendiri. Anda dapat menambahkan tampilan langsung ke WindowManager, menentukan jenis bendera. Kepala Obrolan mungkin menggunakan TYPE_PHONE . Ada beberapa tipe yang serupa, tetapi tujuannya sama: overlay tujuan khusus yang dapat muncul di atas hal lain tanpa aplikasi induk tampaknya ada.

Itu hanya membuat Anda sejauh ini, karena masalah dengan interaksi. Pada awalnya, hamparan Anda akan menyerap semua interaksi, sehingga tidak hanya kepala mendapatkan acara, tetapi Anda memblokir interaksi dengan semua yang ada di bawahnya.

Anda mengonfigurasi perilaku ini menggunakan LayoutParams . FLAG_NOT_TOUCH_MODALberarti bahwa acara di luar area tampilan Anda pergi ke UI yang mendasarinya. Anda sekarang akan menemukannya berfungsi, tetapi hal-hal buruk lainnya masih terjadi, seperti tombol kembali / menu tidak diarahkan ke aplikasi, plus tidak ada keyboard. Untuk mengatasi itu Anda perlu FLAG_NOT_FOCUSABLE.

Anda juga mendapatkan efek samping dari bit yang tidak dapat difokuskan, yang tidak lagi merupakan interaksi yang baik dengan overlay Anda, misalnya penekanan tombol. Anda bisa mendapatkan beberapa acara sentuh dasar, yang selalu bisa Anda hitung, dan itu mungkin cukup untuk Kepala Obrolan. Perlu diketahui bahwa ini membuat Anda sendirian di banyak area, seperti animasi UI.

Tinjauan umum detail yang baik, termasuk memungkinkan untuk interaksi interaksi selektif, dapat ditemukan di utas StackOverflow ini . Secara khusus, salah satu tautan jawaban pada akhirnya akan membawa Anda sini , yang merupakan contoh proyek yang bagus. Perhatikan bahwa ICS mengubah cara kerjanya sedikit, tetapi utas menjelaskannya.

Ini semua hal-hal API publik, tetapi itu tidak benar-benar tampak seperti hal umum yang harus dilakukan sebagai hal yang biasa. Dokumentasi dipenuhi dengan referensi untuk perilaku aplikasi sistem khusus, dan dengan alasan yang bagus; bagaimana jika semua orang melakukannya?

Rob Pridham
sumber
Bisakah saya memblokir perubahan orientasi untuk tampilan ini? Jika aktivitas yang mendasarinya beralih orientasi, pandangan saya juga mengubah orientasinya.
MG
1
Tidak. Perubahan orientasi di seluruh perangkat, tidak hanya untuk aktivitas.
Rob Pridham
7

Kepala Springy memberikan perilaku berbasis pegas dari kepala obrolan di luar kotak. Yang harus Anda tentukan adalah drawable untuk kepala obrolan dan fragmen untuk membuka setelah kepala obrolan diklik. Kepala obrolan runtuh saat diminimalkan dan ikuti jari saat diseret.

Proyek ini mencakup aplikasi demo yang menunjukkan semua fungsionalitas bawaan. Untuk menggunakannya, Anda perlu menambahkan ini ke dependensi gradle Anda.

compile 'com.flipkart.springyheads:library:0.9.6'
Kiran Kumar
sumber
Hai @KiranKumar, Anda telah membuat perpustakaan yang sangat jelas .. Saya sangat menyukainya .. Saya mencoba mempelajari berbagai aspek dari perpustakaan ini .. Saya telah mencoba menjalankannya di luar jendela aplikasi, entah bagaimana saya sedikit berhasil dalam melakukan begitu .. Tapi, masalah muncul ketika saya mengklik kepala obrolan di luar jendela aplikasi .. fragmen tidak akan dapat membuka dan mengembalikan java.lang.OutOfMemoryError .. jika mungkin dari sisi Anda ke beri saya jalan melalui ini .. Ini akan dengan senang hati dihormati ..
arraystack
@arraystack sekarang Anda dapat menjalankannya di layanan. Periksa daftar jika cabang di repo GitHub
Kiran Kumar
@KiranKumar Terima kasih, Masalah dengan Lib baru adalah izin Draw over application dalam Marshmallow Version
arraystack