Я пытаюсь реализовать плавающий виджет в React Native (источник: https://thunderwiring.wordpress.com/2018/04/01/creating-floating-chat-head-like-messenger-in-android/)
Моя цель - использовать React Native для рендеринга этого виджета.
Когда я пытаюсь запустить этот плавающий виджет в MainActivity public class MainActivity extends ReactFragmentActivity
по этому коду startService(new Intent(MainActivity.this, FloatingCallingService.class));
, я получаю сообщение об ошибке:
java.lang.RuntimeException: невозможно запустить службу
com.tc.background.FloatingCallingService@d6c8a7b с намерением {
cmp = com.tc / .background.FloatingCallingService}:
android.view.InflateException: строка двоичного XML-файла # 17: двоичный XML
строка файла № 17: Ошибка надувания фрагмента класса
Вот мой исходный код:
public class FloatingCallingService extends Service {
private View floatingBubbleView;
private WindowManager windowManager;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
if (startId == Service.START_STICKY) {
handleStart();
}
}
return super.onStartCommand(intent, flags, startId);
}
private void handleStart() {
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
floatingBubbleView = LayoutInflater.from(this).inflate(R.layout.floating_layout, null);
int LAYOUT_FLAG;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
LAYOUT_FLAG,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 50;
params.y = 100;
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
windowManager.addView(floatingBubbleView, params);
floating_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/floating_bubble_root"
>
<!--Close button-->
<ImageView
android:id="@+id/close_button"
android:layout_width="26dp"
android:layout_height="26dp"
android:src="@drawable/cancel"
tools:ignore="ContentDescription"/>
<fragment android:name="com.tc.background.FloatingFragment"
android:id="@+id/main_fragment"
android:layout_width="200dp"
android:layout_height="200dp" />
</RelativeLayout>
FloatingFragment.java:
public class FloatingFragment extends ReactFragment {
@Override
public String getMainComponentName() {
return "Calling";
}
}
ReactFragment.java:
public abstract class ReactFragment extends Fragment {
private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager;
// This method returns the name of our top-level component to show
public abstract String getMainComponentName();
@Override
public void onAttach(Context context) {
super.onAttach(context);
mReactRootView = new ReactRootView(context);
mReactInstanceManager =
((MainApplication) getActivity().getApplication())
.getReactNativeHost()
.getReactInstanceManager();
}
@Override
public ReactRootView onCreateView(LayoutInflater inflater, ViewGroup group, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
return mReactRootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mReactRootView.startReactApplication(
mReactInstanceManager,
getMainComponentName(),
null
);
}
}
AndroidManifest.xml:
<service
android:name=".background.FloatingCallingService"
android:enabled="true"
android:exported="false"/>
Спасибо.