Skip to content
This repository was archived by the owner on Jun 8, 2024. It is now read-only.

Commit 285fd9d

Browse files
committed
ClipboardDetectService: Create
Signed-off-by: Fung <fython@163.com>
1 parent 4688a45 commit 285fd9d

14 files changed

Lines changed: 295 additions & 18 deletions

File tree

mobile/src/main/AndroidManifest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<uses-permission android:name="android.permission.CAMERA"/>
88
<uses-permission android:name="android.permission.READ_LOGS"/>
99
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
10+
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
1011

1112
<application
1213
android:allowBackup="true"
@@ -109,6 +110,8 @@
109110
</activity>
110111

111112
<service android:name="info.papdt.express.helper.services.ReminderService"/>
113+
<service android:name="info.papdt.express.helper.services.ClipboardDetectService"
114+
android:label="@string/label_clipboard_service"/>
112115
<service android:name="info.papdt.express.helper.services.AppWidgetService"
113116
android:permission="android.permission.BIND_REMOTEVIEWS"/>
114117
<service android:name="info.papdt.express.helper.services.DetectNumberService"

mobile/src/main/java/info/papdt/express/helper/Application.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package info.papdt.express.helper;
22

3+
import android.content.Intent;
34
import android.content.pm.PackageInfo;
45
import android.content.pm.PackageManager;
56
import android.support.v7.app.AppCompatDelegate;
67

78
import com.tencent.bugly.crashreport.CrashReport;
89

10+
import info.papdt.express.helper.services.ClipboardDetectService;
911
import info.papdt.express.helper.support.Settings;
1012

1113
public class Application extends android.app.Application {
@@ -32,6 +34,10 @@ public void onCreate() {
3234

3335
super.onCreate();
3436

37+
if (mSettings.getBoolean(Settings.KEY_DETECT_FROM_CLIPBOARD, false)) {
38+
startService(new Intent(getApplicationContext(), ClipboardDetectService.class));
39+
}
40+
3541
/** Init CrashReport */
3642
CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(getApplicationContext());
3743
strategy.setAppPackageName(getPackageName());
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package info.papdt.express.helper.services;
2+
3+
import android.animation.Animator;
4+
import android.app.Service;
5+
import android.content.ClipboardManager;
6+
import android.content.Context;
7+
import android.content.Intent;
8+
import android.graphics.PixelFormat;
9+
import android.os.Handler;
10+
import android.os.IBinder;
11+
import android.os.Message;
12+
import android.text.TextUtils;
13+
import android.view.Gravity;
14+
import android.view.MotionEvent;
15+
import android.view.View;
16+
import android.view.WindowManager;
17+
import android.view.animation.AnticipateInterpolator;
18+
import android.view.animation.BounceInterpolator;
19+
import android.widget.ImageView;
20+
import info.papdt.express.helper.R;
21+
import info.papdt.express.helper.support.ScreenUtils;
22+
import info.papdt.express.helper.ui.AddActivity;
23+
24+
public class ClipboardDetectService extends Service implements ClipboardManager.OnPrimaryClipChangedListener {
25+
26+
private ClipboardManager mClipboardManager;
27+
private WindowManager mWindowManager;
28+
private WindowManager.LayoutParams mLayoutParams;
29+
30+
private View mLayout;
31+
private ImageView mIconView;
32+
33+
private Handler mHandler;
34+
35+
private String mLastNumber;
36+
37+
private float mPositionY;
38+
39+
@Override
40+
public void onCreate() {
41+
super.onCreate();
42+
mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
43+
mClipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
44+
mClipboardManager.addPrimaryClipChangedListener(this);
45+
mHandler = new UiHandler();
46+
mPositionY = ScreenUtils.dpToPx(this, 128);
47+
initPopupView();
48+
}
49+
50+
@Override
51+
public void onDestroy() {
52+
super.onDestroy();
53+
mClipboardManager.removePrimaryClipChangedListener(this);
54+
}
55+
56+
@Override
57+
public IBinder onBind(Intent intent) {
58+
return null;
59+
}
60+
61+
@Override
62+
public void onPrimaryClipChanged() {
63+
mLastNumber = DetectNumberService.getPackageNumber(mClipboardManager.getPrimaryClip().toString());
64+
if (TextUtils.isEmpty(mLastNumber)) return;
65+
try {
66+
mWindowManager.addView(mLayout, mLayoutParams);
67+
mIconView.setScaleX(0.5f);
68+
mIconView.setScaleY(0.5f);
69+
mIconView.animate()
70+
.scaleX(1f)
71+
.scaleY(1f)
72+
.setListener(null)
73+
.setDuration(500).setInterpolator(new BounceInterpolator()).start();
74+
mHandler.sendEmptyMessageDelayed(0, 4500);
75+
} catch (Exception e) {
76+
e.printStackTrace();
77+
}
78+
}
79+
80+
private void initPopupView() {
81+
mLayout = View.inflate(this, R.layout.popupwindow_app_entry, null);
82+
mIconView = mLayout.findViewById(R.id.icon_view);
83+
mLayout.setOnClickListener(new View.OnClickListener() {
84+
@Override
85+
public void onClick(View view) {
86+
AddActivity.launch(view.getContext(), null, mLastNumber, null);
87+
mHandler.sendEmptyMessage(0);
88+
}
89+
});
90+
mLayout.setOnTouchListener(new View.OnTouchListener() {
91+
private float lastY;
92+
private float nowY;
93+
private float tranY;
94+
private float distance;
95+
96+
@Override
97+
public boolean onTouch(View view, MotionEvent event) {
98+
boolean ret = false;
99+
switch (event.getAction()){
100+
case MotionEvent.ACTION_DOWN:
101+
distance = 0;
102+
lastY = event.getRawY();
103+
ret = true;
104+
mHandler.removeMessages(0);
105+
break;
106+
case MotionEvent.ACTION_MOVE:
107+
// 获取移动时的X,Y坐标
108+
nowY = event.getRawY();
109+
// 计算XY坐标偏移量
110+
tranY = nowY - lastY;
111+
distance += Math.abs(tranY);
112+
// 移动悬浮窗
113+
mPositionY = mLayoutParams.y += tranY;
114+
//更新悬浮窗位置
115+
mWindowManager.updateViewLayout(mLayout, mLayoutParams);
116+
//记录当前坐标作为下一次计算的上一次移动的位置坐标
117+
lastY = nowY;
118+
break;
119+
case MotionEvent.ACTION_UP:
120+
if (distance < 5) {
121+
view.performClick();
122+
} else {
123+
mHandler.sendEmptyMessageDelayed(0, 3000);
124+
}
125+
break;
126+
}
127+
return ret;
128+
}
129+
});
130+
131+
mLayoutParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
132+
mLayoutParams.x = 0;
133+
mLayoutParams.y = (int) mPositionY;
134+
mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
135+
mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
136+
mLayoutParams.gravity = Gravity.RIGHT | Gravity.TOP;
137+
mLayoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
138+
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
139+
mLayoutParams.format = PixelFormat.TRANSLUCENT;
140+
}
141+
142+
class UiHandler extends Handler {
143+
144+
@Override
145+
public void handleMessage(Message msg) {
146+
switch (msg.what) {
147+
case 0:
148+
mIconView.animate()
149+
.scaleX(0f)
150+
.scaleY(0f)
151+
.setListener(new Animator.AnimatorListener() {
152+
@Override public void onAnimationStart(Animator animator) {}
153+
@Override
154+
public void onAnimationEnd(Animator animator) {
155+
try {mWindowManager.removeViewImmediate(mLayout);} catch (Exception e) {}
156+
}
157+
@Override public void onAnimationCancel(Animator animator) {}
158+
@Override public void onAnimationRepeat(Animator animator) {}
159+
})
160+
.setDuration(500).setInterpolator(new AnticipateInterpolator()).start();
161+
break;
162+
}
163+
}
164+
165+
}
166+
167+
}

mobile/src/main/java/info/papdt/express/helper/services/DetectNumberService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ private String getPackageCompany(String source) {
287287
return source.substring(source.indexOf(" ") + 1);
288288
}
289289

290-
private String getPackageNumber(String source) {
290+
public static String getPackageNumber(String source) {
291291
ArrayList<String> results = new ArrayList<>();
292292
StringBuffer sb = new StringBuffer();
293293
for (int i = 0; i < source.length(); i++) {

mobile/src/main/java/info/papdt/express/helper/support/Settings.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ public class Settings {
1010
KEY_NOTIFICATION_VIBRATE = "noti_vibrate",
1111
KEY_NOTIFICATION_INTERVAL = "noti_interval",
1212
KEY_NOTIFICATION_DO_NOT_DISTURB = "noti_do_not_disturb",
13-
KEY_NIGHT_MODE = "night_mode";
13+
KEY_NIGHT_MODE = "night_mode",
14+
KEY_DETECT_FROM_CLIPBOARD = "from_clipboard";
1415

1516
public static final String KEY_NAVIGATION_TINT = "navi_tint";
1617

mobile/src/main/java/info/papdt/express/helper/ui/SettingsActivity.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,16 @@
1212
import info.papdt.express.helper.R;
1313
import info.papdt.express.helper.support.Settings;
1414
import info.papdt.express.helper.ui.common.AbsActivity;
15-
import info.papdt.express.helper.ui.fragment.settings.SettingsContributors;
16-
import info.papdt.express.helper.ui.fragment.settings.SettingsLicense;
17-
import info.papdt.express.helper.ui.fragment.settings.SettingsMain;
18-
import info.papdt.express.helper.ui.fragment.settings.SettingsNetwork;
19-
import info.papdt.express.helper.ui.fragment.settings.SettingsUi;
15+
import info.papdt.express.helper.ui.fragment.settings.*;
2016

2117
public class SettingsActivity extends AbsActivity {
2218

2319
private int flag;
2420

2521
private static final String EXTRA_SETTINGS_FLAG = "extra_flag";
2622

27-
public static final int FLAG_MAIN = 0, FLAG_UI = 1, FLAG_LICENSE = 2, FLAG_NETWORK = 3, FLAG_CONTRIBUTORS = 4;
23+
public static final int FLAG_MAIN = 0, FLAG_UI = 1, FLAG_LICENSE = 2, FLAG_NETWORK = 3,
24+
FLAG_CONTRIBUTORS = 4, FLAG_AUTO_DETECT = 5;
2825

2926
@Override
3027
protected void onCreate(Bundle savedInstanceState) {
@@ -68,6 +65,10 @@ protected void setUpViews() {
6865
f = new SettingsContributors();
6966
mActionBar.setTitle(R.string.category_contributors);
7067
break;
68+
case FLAG_AUTO_DETECT:
69+
f = new SettingsAutoDetect();
70+
mActionBar.setTitle(R.string.category_auto_detect_services);
71+
break;
7172
default:
7273
throw new RuntimeException("Please set flag when launching activity.");
7374
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package info.papdt.express.helper.ui.fragment.settings;
2+
3+
import android.content.Intent;
4+
import android.os.Bundle;
5+
import info.papdt.express.helper.R;
6+
import info.papdt.express.helper.services.ClipboardDetectService;
7+
import info.papdt.express.helper.support.Settings;
8+
import rikka.materialpreference.Preference;
9+
import rikka.materialpreference.SwitchPreference;
10+
11+
public class SettingsAutoDetect extends AbsPrefFragment
12+
implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener {
13+
14+
private SwitchPreference mPrefFromClipboard;
15+
private Preference mPrefFromScreen;
16+
17+
@Override
18+
public void onCreatePreferences(Bundle bundle, String s) {
19+
addPreferencesFromResource(R.xml.settings_auto_detect);
20+
21+
/** findPreference */
22+
mPrefFromClipboard = (SwitchPreference) findPreference("from_clipboard");
23+
mPrefFromScreen = findPreference("from_screen");
24+
25+
/** Default value */
26+
mPrefFromClipboard.setChecked(getSettings().getBoolean(Settings.KEY_DETECT_FROM_CLIPBOARD, false));
27+
28+
/** Set callback */
29+
mPrefFromClipboard.setOnPreferenceChangeListener(this);
30+
mPrefFromScreen.setOnPreferenceClickListener(this);
31+
}
32+
33+
@Override
34+
public boolean onPreferenceChange(Preference pref, Object o) {
35+
if (pref == mPrefFromClipboard) {
36+
Boolean b = (Boolean) o;
37+
getSettings().putBoolean(Settings.KEY_DETECT_FROM_CLIPBOARD, b);
38+
Intent intent = new Intent(getActivity().getApplicationContext(), ClipboardDetectService.class);
39+
if (!b) {
40+
getActivity().stopService(intent);
41+
} else {
42+
getActivity().startService(intent);
43+
}
44+
return true;
45+
}
46+
return false;
47+
}
48+
49+
@Override
50+
public boolean onPreferenceClick(Preference pref) {
51+
if (pref == mPrefFromScreen) {
52+
Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
53+
startActivity(intent);
54+
return true;
55+
}
56+
return false;
57+
}
58+
}

mobile/src/main/java/info/papdt/express/helper/ui/fragment/settings/SettingsMain.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package info.papdt.express.helper.ui.fragment.settings;
22

3-
import android.content.Intent;
43
import android.content.pm.PackageManager;
54
import android.os.Bundle;
6-
import android.provider.Settings;
75
import android.support.design.widget.Snackbar;
86

97
import info.papdt.express.helper.R;
@@ -18,8 +16,6 @@ public class SettingsMain extends AbsPrefFragment implements Preference.OnPrefer
1816
mPrefGithub, mPrefAlipay, mPrefLicense, mPrefGooglePlus;
1917
private Preference mPrefIconDesigner, mPrefContributors, mPrefAutoDetect;
2018

21-
private static final int REQUEST_AUTO_DETECT_ENABLE = 1001;
22-
2319
@Override
2420
public void onCreatePreferences(Bundle bundle, String s) {
2521
addPreferencesFromResource(R.xml.settings_main);
@@ -104,8 +100,7 @@ public boolean onPreferenceClick(Preference pref) {
104100
return true;
105101
}
106102
if (pref == mPrefAutoDetect) {
107-
Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
108-
startActivityForResult(intent, REQUEST_AUTO_DETECT_ENABLE);
103+
SettingsActivity.launch(getParentActivity(), SettingsActivity.FLAG_AUTO_DETECT);
109104
return true;
110105
}
111106
return false;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:orientation="vertical"
4+
android:layout_width="100dp"
5+
android:layout_height="100dp"
6+
android:clickable="true">
7+
8+
<ImageView
9+
android:id="@+id/icon_view"
10+
android:layout_width="56dp"
11+
android:layout_height="56dp"
12+
android:layout_marginEnd="-8dp"
13+
android:layout_gravity="center_vertical"
14+
android:src="@mipmap/ic_launcher"/>
15+
16+
</FrameLayout>

mobile/src/main/res/values-zh-rCN/strings.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,11 @@
132132
<string name="item_notification_do_not_disturb">勿扰模式</string>
133133
<string name="item_notification_do_not_disturb_desc">在 23:00 到次日 06:00 期间不发出通知。</string>
134134

135-
<string name="item_auto_detect_services">自动检测新包裹</string>
135+
<string name="category_auto_detect_services">自动检测新包裹</string>
136+
<string name="item_detect_screen_text">从屏幕检测</string>
137+
<string name="item_detect_screen_text_desc">@string/description_detect_service</string>
138+
<string name="item_detect_clipboard">从剪贴板检测</string>
139+
<string name="item_detect_clipboard_desc">当你复制了一串带有数字的文本时,水表助手会显示一个气泡快速入口。</string>
136140

137141
<!-- Details -->
138142
<string name="activity_details">详情</string>
@@ -209,4 +213,6 @@
209213
<string name="auto_detect_noti_result">来自%1$s的【%2$s】%3$s</string>
210214
<string name="auto_detect_noti_action_add">添加</string>
211215

216+
<string name="label_clipboard_service">剪贴板自动检测</string>
217+
212218
</resources>

0 commit comments

Comments
 (0)