Skip to content

Commit 2006235

Browse files
committed
Update GenieAPIService apk.
1 parent 0fd5c57 commit 2006235

File tree

10 files changed

+480
-140
lines changed

10 files changed

+480
-140
lines changed

samples/genie/c++/Android/app/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ android {
4646
}
4747
defaultConfig {
4848
applicationId = "com.example.genieapiservice"
49-
minSdk = 29
49+
minSdk = 30
5050
targetSdk = 31
5151
versionCode = 1
5252
versionName = "2.0.0"

samples/genie/c++/Android/app/src/main/AndroidManifest.xml

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3-
xmlns:tools="http://schemas.android.com/tools">
3+
xmlns:tools="http://schemas.android.com/tools" >
44

55
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
66
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
77
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
88
<uses-permission android:name="android.permission.INTERNET" />
99
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
10-
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
11-
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
10+
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
11+
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
1212
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
1313
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
14+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
15+
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
1416

1517
<application
1618
android:allowBackup="true"
@@ -19,22 +21,16 @@
1921
android:icon="@drawable/ic_launcher_qai"
2022
android:label="@string/app_name"
2123
android:largeHeap="true"
24+
android:persistent="true"
2225
android:roundIcon="@drawable/ic_launcher_round"
2326
android:supportsRtl="true"
2427
android:theme="@style/Theme.GenieAPIService"
2528
android:usesCleartextTraffic="true"
26-
android:persistent="true"
27-
tools:targetApi="31">
28-
<receiver
29-
android:name=".GenieReceiver"
30-
android:enabled="true"
31-
android:exported="true">
32-
<intent-filter>
33-
<action android:name="android.intent.action.BOOT_COMPLETED"/>
34-
<action android:name="com.example.genieapiservice.UPDATE_WEBVIEW"/>
35-
<action android:name="com.example.genieapiservice.RESTART"/>
36-
</intent-filter>
37-
</receiver>
29+
tools:targetApi="31" >
30+
<service
31+
android:name=".FloatingService"
32+
android:exported="false" >
33+
</service>
3834

3935
<activity
4036
android:name=".LogContentActivity"
@@ -44,16 +40,14 @@
4440
android:name=".ForegroundService"
4541
android:enabled="true"
4642
android:exported="true"
47-
android:foregroundServiceType="mediaPlayback">
48-
43+
android:foregroundServiceType="mediaPlayback" >
4944
</service>
5045

5146
<activity
5247
android:name=".MainActivity"
53-
android:exported="true">
48+
android:exported="true" >
5449
<intent-filter>
5550
<action android:name="android.intent.action.MAIN" />
56-
5751
<category android:name="android.intent.category.LAUNCHER" />
5852
</intent-filter>
5953
</activity>
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
package com.example.genieapiservice;
2+
3+
import android.animation.ValueAnimator;
4+
import android.app.Service;
5+
import android.content.Context;
6+
import android.content.Intent;
7+
import android.content.SharedPreferences;
8+
import android.content.res.Configuration;
9+
import android.os.Handler;
10+
import android.os.IBinder;
11+
import android.graphics.PixelFormat;
12+
import android.os.Message;
13+
import android.view.Gravity;
14+
import android.view.LayoutInflater;
15+
import android.view.MotionEvent;
16+
import android.view.View;
17+
import android.view.WindowManager;
18+
import android.view.animation.Animation;
19+
import android.view.animation.AnimationUtils;
20+
import android.widget.ImageView;
21+
22+
import androidx.annotation.NonNull;
23+
24+
25+
public class FloatingService extends Service {
26+
27+
private final String TAG = "FloatingService";
28+
private WindowManager windowManager;
29+
private ImageView floatingView;
30+
private final long MaxClickTime = 200;
31+
private long startTouchTime;
32+
private int screenWidth;
33+
private WindowManager.LayoutParams layoutParams;
34+
private boolean isHidden = false;
35+
private boolean isMoving;
36+
private boolean isAligning;
37+
private Handler mHandler = new Handler() {
38+
@Override
39+
public void handleMessage(@NonNull Message msg) {
40+
super.handleMessage(msg);
41+
switch (msg.what) {
42+
case 0:
43+
isHidden = true;
44+
floatingView.animate().translationX(-floatingView.getWidth() * 4f / 5f).setDuration(300).start();
45+
break;
46+
case 1:
47+
isHidden = true;
48+
floatingView.animate().translationX(floatingView.getWidth() * 4f / 5f).setDuration(300).start();
49+
break;
50+
case 3:
51+
isHidden = false;
52+
floatingView.animate().translationX(0).setDuration(300).start();
53+
break;
54+
default:
55+
break;
56+
}
57+
}
58+
};
59+
60+
@Override
61+
public void onConfigurationChanged(Configuration newConfig) {
62+
super.onConfigurationChanged(newConfig);
63+
screenWidth = this.getResources().getDisplayMetrics().widthPixels;
64+
autoAlignAndHide();
65+
}
66+
67+
@Override
68+
public void onCreate() {
69+
super.onCreate();
70+
SharedPreferences sharedPref = this.getSharedPreferences("position",Context.MODE_PRIVATE);
71+
screenWidth = this.getResources().getDisplayMetrics().widthPixels;
72+
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
73+
floatingView = (ImageView) LayoutInflater.from(this).inflate(R.layout.layout_floating, null);
74+
layoutParams = new WindowManager.LayoutParams(
75+
120,
76+
120,
77+
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
78+
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
79+
PixelFormat.TRANSLUCENT
80+
);
81+
layoutParams.gravity = Gravity.TOP | Gravity.START;
82+
layoutParams.x = sharedPref.getInt("x",0);
83+
layoutParams.y = sharedPref.getInt("y",100);
84+
windowManager.addView(floatingView, layoutParams);
85+
if (layoutParams.x == 0) {
86+
mHandler.sendEmptyMessageDelayed(0,2000);
87+
} else {
88+
mHandler.sendEmptyMessageDelayed(1,2000);
89+
}
90+
floatingView.setOnTouchListener(new View.OnTouchListener() {
91+
private float initialTouchX,initialTouchY;
92+
@Override
93+
public boolean onTouch(View v, MotionEvent event) {
94+
switch (event.getAction()){
95+
case MotionEvent.ACTION_DOWN:
96+
isMoving = false;
97+
startTouchTime = System.currentTimeMillis();
98+
initialTouchX = event.getRawX();
99+
initialTouchY = event.getRawY();
100+
return true;
101+
case MotionEvent.ACTION_MOVE:
102+
isMoving = true;
103+
if (mHandler.hasMessages(0)) {
104+
mHandler.removeMessages(0);
105+
}
106+
if (mHandler.hasMessages(1)) {
107+
mHandler.removeMessages(1);
108+
}
109+
if (isHidden) {
110+
restoreIcon();
111+
}
112+
int detailX = (int) (event.getRawX()-initialTouchX);
113+
int detailY = (int) (event.getRawY()-initialTouchY);
114+
layoutParams.x +=detailX;
115+
layoutParams.y +=detailY;
116+
windowManager.updateViewLayout(floatingView,layoutParams);
117+
initialTouchX = event.getRawX();
118+
initialTouchY = event.getRawY();
119+
return true;
120+
case MotionEvent.ACTION_UP:
121+
isMoving = false;
122+
long touchTime = System.currentTimeMillis()-startTouchTime;
123+
if(touchTime < MaxClickTime){
124+
v.performClick();
125+
} else {
126+
autoAlignAndHide();
127+
}
128+
}
129+
return false;
130+
}
131+
});
132+
floatingView.setOnClickListener(v -> {
133+
if (isHidden) {
134+
restore();
135+
} else {
136+
if (!isMoving && !isAligning) {
137+
Intent intent = new Intent(FloatingService.this, MainActivity.class);
138+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
139+
startActivity(intent);
140+
}
141+
}
142+
});
143+
}
144+
145+
private void autoAlignAndHide() {
146+
int targetX;
147+
if (layoutParams.x < screenWidth / 2) {
148+
// align left → move left
149+
targetX = 0;
150+
animateWindow(layoutParams.x, targetX);
151+
} else {
152+
// align right → move right
153+
targetX = screenWidth - layoutParams.width;
154+
animateWindow(layoutParams.x, targetX);
155+
}
156+
}
157+
158+
private void restore() {
159+
int targetX;
160+
if (layoutParams.x < screenWidth / 2) {
161+
targetX = 0;
162+
} else {
163+
targetX = screenWidth - layoutParams.width;
164+
}
165+
animateWindow(layoutParams.x, targetX);
166+
mHandler.sendEmptyMessage(3);
167+
}
168+
169+
private void restoreIcon() {
170+
//floatingView.animate().translationX(0).setDuration(1).start();
171+
restore();
172+
}
173+
174+
private void animateWindow(int fromX, int toX) {
175+
ValueAnimator animator = ValueAnimator.ofInt(fromX, toX);
176+
animator.setDuration(300);
177+
animator.addUpdateListener(animation -> {
178+
layoutParams.x = (int) animation.getAnimatedValue();
179+
if (floatingView.isAttachedToWindow()) {
180+
windowManager.updateViewLayout(floatingView, layoutParams);
181+
}
182+
if (layoutParams.x == toX) {
183+
if (layoutParams.x == 0) {
184+
mHandler.sendEmptyMessageDelayed(0, 2000);
185+
} else {
186+
mHandler.sendEmptyMessageDelayed(1, 2000);
187+
}
188+
isAligning = false;
189+
}
190+
});
191+
isAligning = true;
192+
animator.start();
193+
}
194+
195+
196+
@Override
197+
public IBinder onBind(Intent intent) {
198+
return null;
199+
}
200+
201+
@Override
202+
public void onDestroy() {
203+
super.onDestroy();
204+
try {
205+
SharedPreferences sharedPref = this.getSharedPreferences("position",Context.MODE_PRIVATE);
206+
SharedPreferences.Editor editor = sharedPref.edit();
207+
editor.putInt("x", layoutParams.x);
208+
editor.putInt("y", layoutParams.y);
209+
editor.apply();
210+
windowManager.removeView(floatingView);
211+
stopSelf();
212+
} catch (Exception exception) {
213+
exception.printStackTrace();
214+
}
215+
LogUtils.logDebug(TAG,"call onDestroy",LogUtils.LOG_DEBUG);
216+
}
217+
}

0 commit comments

Comments
 (0)