添加Positions项目
This commit is contained in:
parent
e849e54960
commit
3bcfc5a5da
38
positions/README.md
Normal file
38
positions/README.md
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# Positions
|
||||||
|
|
||||||
|
#### 介绍
|
||||||
|
位置应用,与卫星定位有关的应用。可以根据设定的位置与时间条件判断,来发送通知的应用。
|
||||||
|
|
||||||
|
#### 软件架构
|
||||||
|
适配安卓应用 [AIDE Pro] 的 Gradle 编译结构。
|
||||||
|
也适配安卓应用 [AndroidIDE] 的 Gradle 编译结构。
|
||||||
|
|
||||||
|
|
||||||
|
#### Gradle 编译说明
|
||||||
|
调试版编译命令 :gradle assembleBetaDebug
|
||||||
|
阶段版编译命令 :gradle assembleStageRelease
|
||||||
|
|
||||||
|
#### 使用说明
|
||||||
|
|
||||||
|
在安卓系统中需要设置两个权限允许。
|
||||||
|
1.自启动权限允许。
|
||||||
|
2.省电策略-无限制权限允许。
|
||||||
|
|
||||||
|
#### 参与贡献
|
||||||
|
|
||||||
|
1. Fork 本仓库
|
||||||
|
2. 新建 Feat_xxx 分支
|
||||||
|
3. 提交代码 : ZhanGSKen(ZhanGSKen@AliYun.Com)
|
||||||
|
4. 新建 Pull Request
|
||||||
|
|
||||||
|
|
||||||
|
#### 特技
|
||||||
|
|
||||||
|
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
|
||||||
|
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
|
||||||
|
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
|
||||||
|
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
|
||||||
|
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
|
||||||
|
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||||
|
|
||||||
|
#### 参考文档
|
1
positions/app_update_description.txt
Normal file
1
positions/app_update_description.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
71
positions/build.gradle
Normal file
71
positions/build.gradle
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
apply plugin: 'com.android.application'
|
||||||
|
apply from: '../.winboll/winboll_app_build.gradle'
|
||||||
|
apply from: '../.winboll/winboll_lint_build.gradle'
|
||||||
|
|
||||||
|
def genVersionName(def versionName){
|
||||||
|
// 检查编译标志位配置
|
||||||
|
assert (winbollBuildProps['stageCount'] != null)
|
||||||
|
assert (winbollBuildProps['baseVersion'] != null)
|
||||||
|
// 保存基础版本号
|
||||||
|
winbollBuildProps.setProperty("baseVersion", "${versionName}");
|
||||||
|
//保存编译标志配置
|
||||||
|
FileOutputStream fos = new FileOutputStream(winbollBuildPropsFile)
|
||||||
|
winbollBuildProps.store(fos, "${winbollBuildPropsDesc}");
|
||||||
|
fos.close();
|
||||||
|
|
||||||
|
// 返回编译版本号
|
||||||
|
return "${versionName}." + winbollBuildProps['stageCount']
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 32
|
||||||
|
buildToolsVersion "33.0.3"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "cc.winboll.studio.positions"
|
||||||
|
minSdkVersion 21
|
||||||
|
targetSdkVersion 30
|
||||||
|
versionCode 1
|
||||||
|
// versionName 更新后需要手动设置
|
||||||
|
// 项目模块目录的 build.gradle 文件的 stageCount=0
|
||||||
|
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
|
||||||
|
versionName "1.0"
|
||||||
|
if(true) {
|
||||||
|
versionName = genVersionName("${versionName}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_17
|
||||||
|
targetCompatibility JavaVersion.VERSION_17
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// 二维码使用的类库
|
||||||
|
api 'com.google.zxing:core:3.4.1'
|
||||||
|
api 'com.journeyapps:zxing-android-embedded:3.6.0'
|
||||||
|
|
||||||
|
api 'io.github.medyo:android-about-page:2.0.0'
|
||||||
|
api 'com.github.getActivity:ToastUtils:10.5'
|
||||||
|
api 'com.jcraft:jsch:0.1.55'
|
||||||
|
api 'org.jsoup:jsoup:1.13.1'
|
||||||
|
api 'com.squareup.okhttp3:okhttp:4.4.1'
|
||||||
|
|
||||||
|
api 'androidx.appcompat:appcompat:1.1.0'
|
||||||
|
api 'androidx.viewpager:viewpager:1.0.0'
|
||||||
|
api 'androidx.fragment:fragment:1.1.0'
|
||||||
|
api 'com.google.android.material:material:1.4.0'
|
||||||
|
|
||||||
|
api 'cc.winboll.studio:libapputils:9.3.2'
|
||||||
|
api 'cc.winboll.studio:libappbase:1.5.6'
|
||||||
|
|
||||||
|
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
}
|
8
positions/build.properties
Normal file
8
positions/build.properties
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
|
#Fri Feb 21 17:45:58 GMT 2025
|
||||||
|
stageCount=0
|
||||||
|
libraryProject=
|
||||||
|
baseVersion=1.0
|
||||||
|
publishVersion=1.0.0
|
||||||
|
buildCount=1
|
||||||
|
baseBetaVersion=1.0.1
|
17
positions/proguard-rules.pro
vendored
Normal file
17
positions/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in C:\tools\adt-bundle-windows-x86_64-20131030\sdk/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
13
positions/src/beta/AndroidManifest.xml
Normal file
13
positions/src/beta/AndroidManifest.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools" >
|
||||||
|
|
||||||
|
<application
|
||||||
|
tools:replace="android:icon"
|
||||||
|
android:icon="@drawable/ic_winbollbeta">
|
||||||
|
|
||||||
|
<!-- Put flavor specific code here -->
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
|
|
6
positions/src/beta/res/values/strings.xml
Normal file
6
positions/src/beta/res/values/strings.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<string name="app_name">Positions+</string>
|
||||||
|
|
||||||
|
</resources>
|
62
positions/src/main/AndroidManifest.xml
Normal file
62
positions/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<manifest
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="cc.winboll.studio.positions">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:name=".App"
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@drawable/ic_winboll"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/MyAppTheme"
|
||||||
|
android:supportsRtl="true">
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:exported="true">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
|
||||||
|
<activity android:name="cc.winboll.studio.positions.activities.SettingsActivity"/>
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name="cc.winboll.studio.positions.services.MainService"
|
||||||
|
android:exported="true"/>
|
||||||
|
|
||||||
|
<service android:name="cc.winboll.studio.positions.services.AssistantService"/>
|
||||||
|
|
||||||
|
<receiver android:name=".receivers.MainReceiver">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
|
||||||
|
<action android:name="cc.winboll.studio.positions.receivers.MainReceiver"/>
|
||||||
|
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
android:authorities="${applicationId}.fileprovider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true">
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/studio_provider"/>
|
||||||
|
|
||||||
|
</provider>
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
28
positions/src/main/java/cc/winboll/studio/positions/App.java
Normal file
28
positions/src/main/java/cc/winboll/studio/positions/App.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package cc.winboll.studio.positions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@QQ.COM
|
||||||
|
* @Date 2024/12/08 15:10:51
|
||||||
|
* @Describe 全局应用类
|
||||||
|
*/
|
||||||
|
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||||
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
|
||||||
|
|
||||||
|
public class App extends GlobalApplication {
|
||||||
|
|
||||||
|
public static final String TAG = "App";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
// 必须在调用基类前设置应用调试标志,
|
||||||
|
// 这样可以预先设置日志与数据的存储根目录。
|
||||||
|
setIsDebuging(this, BuildConfig.DEBUG);
|
||||||
|
super.onCreate();
|
||||||
|
// 设置 WinBoll 应用 UI 类型
|
||||||
|
WinBollActivityManager.getInstance(this).setWinBollUI_TYPE(WinBollActivityManager.WinBollUI_TYPE.Aplication);
|
||||||
|
|
||||||
|
LogUtils.d(TAG, "onCreate");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,387 @@
|
|||||||
|
package cc.winboll.studio.positions;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.ActivityManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.telecom.TelecomManager;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import androidx.viewpager.widget.ViewPager;
|
||||||
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import cc.winboll.studio.libappbase.LogView;
|
||||||
|
import cc.winboll.studio.libapputils.app.IWinBollActivity;
|
||||||
|
import cc.winboll.studio.libapputils.app.WinBollActivityManager;
|
||||||
|
import cc.winboll.studio.libapputils.bean.APPInfo;
|
||||||
|
import cc.winboll.studio.libapputils.view.YesNoAlertDialog;
|
||||||
|
import cc.winboll.studio.positions.R;
|
||||||
|
import cc.winboll.studio.positions.activities.SettingsActivity;
|
||||||
|
import cc.winboll.studio.positions.adapters.MyPagerAdapter;
|
||||||
|
import cc.winboll.studio.positions.beans.MainServiceBean;
|
||||||
|
import cc.winboll.studio.positions.services.MainService;
|
||||||
|
import com.google.android.material.tabs.TabLayout;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
final public class MainActivity extends AppCompatActivity implements IWinBollActivity, ViewPager.OnPageChangeListener, View.OnClickListener {
|
||||||
|
|
||||||
|
public static final String TAG = "MainActivity";
|
||||||
|
|
||||||
|
public static final int REQUEST_HOME_ACTIVITY = 0;
|
||||||
|
public static final int REQUEST_ABOUT_ACTIVITY = 1;
|
||||||
|
|
||||||
|
public static final String ACTION_SOS = "cc.winboll.studio.libappbase.WinBoll.ACTION_SOS";
|
||||||
|
|
||||||
|
LogView mLogView;
|
||||||
|
Toolbar mToolbar;
|
||||||
|
CheckBox cbMainService;
|
||||||
|
MainServiceBean mMainServiceBean;
|
||||||
|
ViewPager viewPager;
|
||||||
|
private List<View> views; //用来存放放进ViewPager里面的布局
|
||||||
|
//实例化存储imageView(导航原点)的集合
|
||||||
|
ImageView[] imageViews;
|
||||||
|
//MyPagerAdapter adapter;//适配器
|
||||||
|
MyPagerAdapter pagerAdapter;
|
||||||
|
LinearLayout linearLayout;//下标所在在LinearLayout布局里
|
||||||
|
int currentPoint = 0;//当前被选中中页面的下标
|
||||||
|
|
||||||
|
private static final int DIALER_REQUEST_CODE = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AppCompatActivity getActivity() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public APPInfo getAppInfo() {
|
||||||
|
// String szBranchName = "contacts";
|
||||||
|
//
|
||||||
|
// APPInfo appInfo = AboutActivityFactory.buildDefaultAPPInfo();
|
||||||
|
// appInfo.setAppName("Contacts");
|
||||||
|
// appInfo.setAppIcon(cc.winboll.studio.libapputils.R.drawable.ic_winboll);
|
||||||
|
// appInfo.setAppDescription("Contacts Description");
|
||||||
|
// appInfo.setAppGitName("APP");
|
||||||
|
// appInfo.setAppGitOwner("Studio");
|
||||||
|
// appInfo.setAppGitAPPBranch(szBranchName);
|
||||||
|
// appInfo.setAppGitAPPSubProjectFolder(szBranchName);
|
||||||
|
// appInfo.setAppHomePage("https://www.winboll.cc/studio/details.php?app=Contacts");
|
||||||
|
// appInfo.setAppAPKName("Contacts");
|
||||||
|
// appInfo.setAppAPKFolderName("Contacts");
|
||||||
|
// return appInfo;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
// 接收并处理 Intent 数据,函数 Intent 处理接收就直接返回
|
||||||
|
//if (prosessIntents(getIntent())) return;
|
||||||
|
// 以下正常创建主窗口
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
// 初始化工具栏
|
||||||
|
mToolbar = findViewById(R.id.activitymainToolbar1);
|
||||||
|
setSupportActionBar(mToolbar);
|
||||||
|
if (isEnableDisplayHomeAsUp()) {
|
||||||
|
// 显示后退按钮
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
}
|
||||||
|
getSupportActionBar().setSubtitle(getTag());
|
||||||
|
|
||||||
|
initData();
|
||||||
|
initView();
|
||||||
|
//initPoint();//调用初始化导航原点的方法
|
||||||
|
viewPager.addOnPageChangeListener(this);//滑动事件
|
||||||
|
|
||||||
|
ViewPager viewPager = findViewById(R.id.activitymainViewPager1);
|
||||||
|
MyPagerAdapter pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
|
||||||
|
viewPager.setAdapter(pagerAdapter);
|
||||||
|
TabLayout tabLayout = findViewById(R.id.activitymainTabLayout1);
|
||||||
|
tabLayout.setupWithViewPager(viewPager);
|
||||||
|
|
||||||
|
// mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
|
||||||
|
// if (mMainServiceBean == null) {
|
||||||
|
// mMainServiceBean = new MainServiceBean();
|
||||||
|
// }
|
||||||
|
// cbMainService = findViewById(R.id.activitymainCheckBox1);
|
||||||
|
// cbMainService.setChecked(mMainServiceBean.isEnable());
|
||||||
|
// cbMainService.setOnClickListener(new View.OnClickListener(){
|
||||||
|
// @Override
|
||||||
|
// public void onClick(View view) {
|
||||||
|
// if (cbMainService.isChecked()) {
|
||||||
|
// MainService.startMainService(MainActivity.this);
|
||||||
|
// } else {
|
||||||
|
// MainService.stopMainService(MainActivity.this);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
MainService.startMainService(MainActivity.this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//初始化view,即显示的图片
|
||||||
|
void initView() {
|
||||||
|
viewPager = findViewById(R.id.activitymainViewPager1);
|
||||||
|
pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
|
||||||
|
viewPager.setAdapter(pagerAdapter);
|
||||||
|
//adapter = new MyPagerAdapter(views);
|
||||||
|
//viewPager = findViewById(R.id.activitymainViewPager1);
|
||||||
|
//viewPager.setAdapter(adapter);
|
||||||
|
//linearLayout = findViewById(R.id.activitymainLinearLayout1);
|
||||||
|
//initPoint();//初始化页面下方的点
|
||||||
|
viewPager.setOnPageChangeListener(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//初始化所要显示的布局
|
||||||
|
void initData() {
|
||||||
|
ViewPager viewPager = findViewById(R.id.activitymainViewPager1);
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(getActivity());
|
||||||
|
View view1 = inflater.inflate(R.layout.fragment_call, viewPager, false);
|
||||||
|
View view2 = inflater.inflate(R.layout.fragment_contacts, viewPager, false);
|
||||||
|
View view3 = inflater.inflate(R.layout.fragment_log, viewPager, false);
|
||||||
|
|
||||||
|
views = new ArrayList<>();
|
||||||
|
views.add(view1);
|
||||||
|
views.add(view2);
|
||||||
|
views.add(view3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// void initPoint() {
|
||||||
|
// imageViews = new ImageView[5];//实例化5个图片
|
||||||
|
// for (int i = 0; i < linearLayout.getChildCount(); i++) {
|
||||||
|
// imageViews[i] = (ImageView) linearLayout.getChildAt(i);
|
||||||
|
// imageViews[i].setImageResource(R.drawable.ic_launcher);
|
||||||
|
// imageViews[i].setOnClickListener(this);//点击导航点,即可跳转
|
||||||
|
// imageViews[i].setTag(i);//重复利用实例化的对象
|
||||||
|
// }
|
||||||
|
// currentPoint = 0;//默认第一个坐标
|
||||||
|
// imageViews[currentPoint].setImageResource(R.drawable.ic_launcher);
|
||||||
|
// }
|
||||||
|
|
||||||
|
//OnPageChangeListener接口要实现的三个方法
|
||||||
|
/* onPageScrollStateChanged(int state)
|
||||||
|
此方法是在状态改变的时候调用,其中state这个参数有三种状态:
|
||||||
|
SCROLL_STATE_DRAGGING(1)表示用户手指“按在屏幕上并且开始拖动”的状态
|
||||||
|
(手指按下但是还没有拖动的时候还不是这个状态,只有按下并且手指开始拖动后log才打出。)
|
||||||
|
SCROLL_STATE_IDLE(0)滑动动画做完的状态。
|
||||||
|
SCROLL_STATE_SETTLING(2)在“手指离开屏幕”的状态。*/
|
||||||
|
@Override
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
|
||||||
|
}
|
||||||
|
/* onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
|
||||||
|
当页面在滑动的时候会调用此方法,在滑动被停止之前,此方法回一直得到调用。其中三个参数的含义分别为:
|
||||||
|
|
||||||
|
position :当前页面,即你点击滑动的页面(从A滑B,则是A页面的position。
|
||||||
|
positionOffset:当前页面偏移的百分比
|
||||||
|
positionOffsetPixels:当前页面偏移的像素位置*/
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
|
||||||
|
}
|
||||||
|
/* onPageSelected(int position)
|
||||||
|
此方法是页面滑动完后得到调用,position是你当前选中的页面的Position(位置编号)
|
||||||
|
(从A滑动到B,就是B的position)*/
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
|
||||||
|
// ImageView preView = imageViews[currentPoint];
|
||||||
|
// preView.setImageResource(R.drawable.ic_launcher);
|
||||||
|
// ImageView currView = imageViews[position];
|
||||||
|
// currView.setImageResource(R.drawable.ic_launcher);
|
||||||
|
// currentPoint = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
//小圆点点击事件
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
//通过getTag(),可以判断是哪个控件
|
||||||
|
// int i = (Integer) v.getTag();
|
||||||
|
// viewPager.setCurrentItem(i);//直接跳转到某一个页面的情况
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostCreate(Bundle savedInstanceState) {
|
||||||
|
super.onPostCreate(savedInstanceState);
|
||||||
|
//setSubTitle("");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
LogUtils.d(TAG, "onDestroy() SOS");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 处理传入的 Intent 数据
|
||||||
|
//
|
||||||
|
// boolean prosessIntents(Intent intent) {
|
||||||
|
// if (intent == null
|
||||||
|
// || intent.getAction() == null
|
||||||
|
// || intent.getAction().equals(""))
|
||||||
|
// return false;
|
||||||
|
//
|
||||||
|
// if (intent.getAction().equals(StringToQrCodeView.ACTION_UNITTEST_QRCODE)) {
|
||||||
|
// try {
|
||||||
|
// WinBollActivity clazzActivity = UnitTestActivity.class.newInstance();
|
||||||
|
// String tag = clazzActivity.getTag();
|
||||||
|
// LogUtils.d(TAG, "String tag = clazzActivity.getTag(); tag " + tag);
|
||||||
|
// Intent subIntent = new Intent(this, UnitTestActivity.class);
|
||||||
|
// subIntent.setAction(intent.getAction());
|
||||||
|
// File file = new File(getCacheDir(), UUID.randomUUID().toString());
|
||||||
|
// //取出文件uri
|
||||||
|
// Uri uri = intent.getData();
|
||||||
|
// if (uri == null) {
|
||||||
|
// uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
|
||||||
|
// }
|
||||||
|
// //获取文件真实地址
|
||||||
|
// String szSrcPath = UriUtils.getFileFromUri(getApplication(), uri);
|
||||||
|
// if (TextUtils.isEmpty(szSrcPath)) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Files.copy(Paths.get(szSrcPath), Paths.get(file.getPath()));
|
||||||
|
// //startWinBollActivity(subIntent, tag);
|
||||||
|
// WinBollActivityManager.getInstance(this).startWinBollActivity(this, subIntent, UnitTestActivity.class);
|
||||||
|
// } catch (IllegalAccessException | InstantiationException | IOException e) {
|
||||||
|
// LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
// // 函数处理异常返回失败
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// LogUtils.d(TAG, "prosessIntents|" + intent.getAction() + "|yet");
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Toolbar initToolBar() {
|
||||||
|
return findViewById(R.id.activitymainToolbar1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAddWinBollToolBar() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnableDisplayHomeAsUp() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void exit() {
|
||||||
|
YesNoAlertDialog.OnDialogResultListener listener = new YesNoAlertDialog.OnDialogResultListener(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onYes() {
|
||||||
|
WinBollActivityManager.getInstance(getApplicationContext()).finishAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNo() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
YesNoAlertDialog.show(this, "[ " + getString(R.string.app_name) + " ]", "Exit(Yes/No).\nIs close all activity?", listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.toolbar_main, menu);
|
||||||
|
return super.onCreateOptionsMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
if (item.getItemId() == R.id.item_settings) {
|
||||||
|
Intent intent = new Intent(this, SettingsActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
//WinBollActivityManager.getInstance(this).startWinBollActivity(this, CallActivity.class);
|
||||||
|
}
|
||||||
|
// } else
|
||||||
|
// if (item.getItemId() == R.id.item_exit) {
|
||||||
|
// exit();
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Android M 及以上检查是否是系统默认电话应用
|
||||||
|
*/
|
||||||
|
public boolean isDefaultPhoneCallApp() {
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
TelecomManager manger = (TelecomManager) getSystemService(TELECOM_SERVICE);
|
||||||
|
if (manger != null && manger.getDefaultDialerPackage() != null) {
|
||||||
|
return manger.getDefaultDialerPackage().equals(getPackageName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isServiceRunning(Class<?> serviceClass) {
|
||||||
|
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||||
|
if (manager == null) return false;
|
||||||
|
|
||||||
|
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(
|
||||||
|
Integer.MAX_VALUE)) {
|
||||||
|
if (serviceClass.getName().equals(service.service.getClassName())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
// switch (resultCode) {
|
||||||
|
// case REQUEST_HOME_ACTIVITY : {
|
||||||
|
// LogUtils.d(TAG, "REQUEST_HOME_ACTIVITY");
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// case REQUEST_ABOUT_ACTIVITY : {
|
||||||
|
// LogUtils.d(TAG, "REQUEST_ABOUT_ACTIVITY");
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// default : {
|
||||||
|
// super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
if (requestCode == DIALER_REQUEST_CODE) {
|
||||||
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
|
Toast.makeText(MainActivity.this, getString(R.string.app_name) + " 已成为默认电话应用",
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
package cc.winboll.studio.positions.activities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/21 05:37:42
|
||||||
|
*/
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import cc.winboll.studio.positions.R;
|
||||||
|
import com.hjq.toast.ToastUtils;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import cc.winboll.studio.libappbase.IWinBollActivity;
|
||||||
|
import cc.winboll.studio.libappbase.bean.APPInfo;
|
||||||
|
|
||||||
|
public class SettingsActivity extends AppCompatActivity implements IWinBollActivity {
|
||||||
|
|
||||||
|
public static final String TAG = "SettingsActivity";
|
||||||
|
|
||||||
|
Toolbar mToolbar;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public APPInfo getAppInfo() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AppCompatActivity getActivity() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Toolbar initToolBar() {
|
||||||
|
return findViewById(R.id.activitymainToolbar1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAddWinBollToolBar() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnableDisplayHomeAsUp() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_settings);
|
||||||
|
|
||||||
|
// 初始化工具栏
|
||||||
|
mToolbar = findViewById(R.id.activitymainToolbar1);
|
||||||
|
setSupportActionBar(mToolbar);
|
||||||
|
if (isEnableDisplayHomeAsUp()) {
|
||||||
|
// 显示后退按钮
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
}
|
||||||
|
getSupportActionBar().setSubtitle(getTag());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDefaultPhone(View view) {
|
||||||
|
Intent intent = new Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
public void onCanDrawOverlays(View view) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||||
|
&& !Settings.canDrawOverlays(this)) {
|
||||||
|
// 请求 悬浮框 权限
|
||||||
|
askForDrawOverlay();
|
||||||
|
} else {
|
||||||
|
ToastUtils.show("悬浮窗已开启");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void askForDrawOverlay() {
|
||||||
|
AlertDialog alertDialog = new AlertDialog.Builder(this)
|
||||||
|
.setTitle("允许显示悬浮框")
|
||||||
|
.setMessage("为了使电话监听服务正常工作,请允许这项权限")
|
||||||
|
.setPositiveButton("去设置", new DialogInterface.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
openDrawOverlaySettings();
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton("稍后再说", new DialogInterface.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
alertDialog.getWindow().setFlags(
|
||||||
|
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
|
||||||
|
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
|
||||||
|
alertDialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跳转悬浮窗管理设置界面
|
||||||
|
*/
|
||||||
|
private void openDrawOverlaySettings() {
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
// Android M 以上引导用户去系统设置中打开允许悬浮窗
|
||||||
|
// 使用反射是为了用尽可能少的代码保证在大部分机型上都可用
|
||||||
|
try {
|
||||||
|
Context context = this;
|
||||||
|
Class clazz = Settings.class;
|
||||||
|
Field field = clazz.getDeclaredField("ACTION_MANAGE_OVERLAY_PERMISSION");
|
||||||
|
Intent intent = new Intent(field.get(null).toString());
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
intent.setData(Uri.parse("package:" + context.getPackageName()));
|
||||||
|
context.startActivity(intent);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Toast.makeText(this, "请在悬浮窗管理中打开权限", Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package cc.winboll.studio.positions.adapters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/20 13:33:04
|
||||||
|
* @Describe MyPagerAdapter
|
||||||
|
*/
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.fragment.app.FragmentPagerAdapter;
|
||||||
|
import cc.winboll.studio.positions.fragments.CallFragment;
|
||||||
|
import cc.winboll.studio.positions.fragments.ContactsFragment;
|
||||||
|
import cc.winboll.studio.positions.fragments.LogFragment;
|
||||||
|
|
||||||
|
public class MyPagerAdapter extends FragmentPagerAdapter {
|
||||||
|
public static final String TAG = "MyPagerAdapter";
|
||||||
|
|
||||||
|
private static final int PAGE_COUNT = 3;
|
||||||
|
|
||||||
|
public MyPagerAdapter(@NonNull FragmentManager fm) {
|
||||||
|
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Fragment getItem(int position) {
|
||||||
|
if(position == 1) {
|
||||||
|
return ContactsFragment.newInstance(position);
|
||||||
|
} else if(position == 2) {
|
||||||
|
return LogFragment.newInstance(position);
|
||||||
|
} else {
|
||||||
|
return CallFragment.newInstance(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return PAGE_COUNT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
|||||||
|
package cc.winboll.studio.positions.beans;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/13 07:06:13
|
||||||
|
*/
|
||||||
|
import android.util.JsonReader;
|
||||||
|
import android.util.JsonWriter;
|
||||||
|
import cc.winboll.studio.libappbase.BaseBean;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class MainServiceBean extends BaseBean {
|
||||||
|
|
||||||
|
public static final String TAG = "MainServiceBean";
|
||||||
|
|
||||||
|
boolean isEnable;
|
||||||
|
|
||||||
|
public MainServiceBean() {
|
||||||
|
this.isEnable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsEnable(boolean isEnable) {
|
||||||
|
this.isEnable = isEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnable() {
|
||||||
|
return isEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return MainServiceBean.class.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
|
||||||
|
super.writeThisToJsonWriter(jsonWriter);
|
||||||
|
MainServiceBean bean = this;
|
||||||
|
jsonWriter.name("isEnable").value(bean.isEnable());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
|
||||||
|
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
|
||||||
|
if (name.equals("isEnable")) {
|
||||||
|
setIsEnable(jsonReader.nextBoolean());
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException {
|
||||||
|
jsonReader.beginObject();
|
||||||
|
while (jsonReader.hasNext()) {
|
||||||
|
String name = jsonReader.nextName();
|
||||||
|
if (!initObjectsFromJsonReader(jsonReader, name)) {
|
||||||
|
jsonReader.skipValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 结束 JSON 对象
|
||||||
|
jsonReader.endObject();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package cc.winboll.studio.positions.fragments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/20 12:57:00
|
||||||
|
* @Describe 拨号
|
||||||
|
*/
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import cc.winboll.studio.positions.R;
|
||||||
|
import cc.winboll.studio.libappbase.LogView;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
public class CallFragment extends Fragment {
|
||||||
|
|
||||||
|
public static final String TAG = "CallFragment";
|
||||||
|
|
||||||
|
private static final String ARG_PAGE = "ARG_PAGE";
|
||||||
|
private int mPage;
|
||||||
|
|
||||||
|
public static CallFragment newInstance(int page) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putInt(ARG_PAGE, page);
|
||||||
|
CallFragment fragment = new CallFragment();
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
if (getArguments()!= null) {
|
||||||
|
mPage = getArguments().getInt(ARG_PAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
View view = inflater.inflate(R.layout.fragment_call, container, false);
|
||||||
|
TextView textView = view.findViewById(R.id.page_text);
|
||||||
|
textView.setText("这是第 " + mPage + " 页");
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package cc.winboll.studio.positions.fragments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/20 12:57:50
|
||||||
|
* @Describe 联系人
|
||||||
|
*/
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import cc.winboll.studio.positions.R;
|
||||||
|
|
||||||
|
public class ContactsFragment extends Fragment {
|
||||||
|
|
||||||
|
public static final String TAG = "ContactsFragment";
|
||||||
|
|
||||||
|
private static final String ARG_PAGE = "ARG_PAGE";
|
||||||
|
private int mPage;
|
||||||
|
|
||||||
|
public static ContactsFragment newInstance(int page) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putInt(ARG_PAGE, page);
|
||||||
|
ContactsFragment fragment = new ContactsFragment();
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
if (getArguments()!= null) {
|
||||||
|
mPage = getArguments().getInt(ARG_PAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
View view = inflater.inflate(R.layout.fragment_contacts, container, false);
|
||||||
|
TextView textView = view.findViewById(R.id.page_text);
|
||||||
|
textView.setText("这是第 " + mPage + " 页");
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package cc.winboll.studio.positions.fragments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/20 12:58:15
|
||||||
|
* @Describe 应用日志
|
||||||
|
*/
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import cc.winboll.studio.positions.R;
|
||||||
|
import cc.winboll.studio.libappbase.LogView;
|
||||||
|
|
||||||
|
public class LogFragment extends Fragment {
|
||||||
|
|
||||||
|
public static final String TAG = "LogFragment";
|
||||||
|
|
||||||
|
private static final String ARG_PAGE = "ARG_PAGE";
|
||||||
|
private int mPage;
|
||||||
|
|
||||||
|
public static LogFragment newInstance(int page) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putInt(ARG_PAGE, page);
|
||||||
|
LogFragment fragment = new LogFragment();
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
if (getArguments() != null) {
|
||||||
|
mPage = getArguments().getInt(ARG_PAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
View view = inflater.inflate(R.layout.fragment_log, container, false);
|
||||||
|
LogView logView = view.findViewById(R.id.logview);
|
||||||
|
logView.start();
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package cc.winboll.studio.positions.handlers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/14 03:51:40
|
||||||
|
*/
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import cc.winboll.studio.positions.services.MainService;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
public class MainServiceHandler extends Handler {
|
||||||
|
public static final String TAG = "MainServiceHandler";
|
||||||
|
|
||||||
|
public static final int MSG_REMINDTHREAD = 0;
|
||||||
|
|
||||||
|
WeakReference<MainService> serviceWeakReference;
|
||||||
|
public MainServiceHandler(MainService service) {
|
||||||
|
serviceWeakReference = new WeakReference<MainService>(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case MSG_REMINDTHREAD: // 处理下载完成消息,更新UI
|
||||||
|
{
|
||||||
|
// 显示提醒消息
|
||||||
|
//
|
||||||
|
//LogUtils.d(TAG, "显示提醒消息");
|
||||||
|
MainService mainService = serviceWeakReference.get();
|
||||||
|
if (mainService != null) {
|
||||||
|
mainService.appenMessage((String)msg.obj);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package cc.winboll.studio.positions.receivers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/13 06:58:04
|
||||||
|
* @Describe 主要广播接收器
|
||||||
|
*/
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import cc.winboll.studio.positions.services.MainService;
|
||||||
|
import com.hjq.toast.ToastUtils;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
public class MainReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
|
public static final String TAG = "MainReceiver";
|
||||||
|
public static final String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
|
||||||
|
WeakReference<MainService> mwrService;
|
||||||
|
// 存储电量指示值,
|
||||||
|
// 用于校验电量消息时的电量变化
|
||||||
|
static volatile int _mnTheQuantityOfElectricityOld = -1;
|
||||||
|
static volatile boolean _mIsCharging = false;
|
||||||
|
|
||||||
|
public MainReceiver(MainService service) {
|
||||||
|
mwrService = new WeakReference<MainService>(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
String szAction = intent.getAction();
|
||||||
|
if (szAction.equals(ACTION_BOOT_COMPLETED)) {
|
||||||
|
ToastUtils.show("ACTION_BOOT_COMPLETED");
|
||||||
|
MainService.startMainService(context);
|
||||||
|
} else {
|
||||||
|
ToastUtils.show(szAction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册 Receiver
|
||||||
|
//
|
||||||
|
public void registerAction(Context context) {
|
||||||
|
IntentFilter filter=new IntentFilter();
|
||||||
|
filter.addAction(ACTION_BOOT_COMPLETED);
|
||||||
|
//filter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
||||||
|
context.registerReceiver(this, filter);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,139 @@
|
|||||||
|
package cc.winboll.studio.positions.services;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/14 03:38:31
|
||||||
|
* @Describe 守护进程服务
|
||||||
|
*/
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.ServiceConnection;
|
||||||
|
import android.os.Binder;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import cc.winboll.studio.positions.beans.MainServiceBean;
|
||||||
|
import cc.winboll.studio.positions.services.MainService;
|
||||||
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import cc.winboll.studio.libappbase.SOS;
|
||||||
|
import cc.winboll.studio.libappbase.bean.APPSOSBean;
|
||||||
|
|
||||||
|
public class AssistantService extends Service {
|
||||||
|
|
||||||
|
public static final String TAG = "AssistantService";
|
||||||
|
|
||||||
|
MainServiceBean mMainServiceBean;
|
||||||
|
MyServiceConnection mMyServiceConnection;
|
||||||
|
MainService mMainService;
|
||||||
|
boolean isBound = false;
|
||||||
|
volatile boolean isThreadAlive = false;
|
||||||
|
|
||||||
|
public synchronized void setIsThreadAlive(boolean isThreadAlive) {
|
||||||
|
LogUtils.d(TAG, "setIsThreadAlive(...)");
|
||||||
|
LogUtils.d(TAG, String.format("isThreadAlive %s", isThreadAlive));
|
||||||
|
this.isThreadAlive = isThreadAlive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isThreadAlive() {
|
||||||
|
return isThreadAlive;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return new MyBinder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
LogUtils.d(TAG, "onCreate");
|
||||||
|
super.onCreate();
|
||||||
|
|
||||||
|
//mMyBinder = new MyBinder();
|
||||||
|
if (mMyServiceConnection == null) {
|
||||||
|
mMyServiceConnection = new MyServiceConnection();
|
||||||
|
}
|
||||||
|
// 设置运行参数
|
||||||
|
setIsThreadAlive(false);
|
||||||
|
assistantService();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
LogUtils.d(TAG, "call onStartCommand(...)");
|
||||||
|
assistantService();
|
||||||
|
return START_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
//LogUtils.d(TAG, "onDestroy");
|
||||||
|
setIsThreadAlive(false);
|
||||||
|
// 解除绑定
|
||||||
|
if (isBound) {
|
||||||
|
unbindService(mMyServiceConnection);
|
||||||
|
isBound = false;
|
||||||
|
}
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 运行服务内容
|
||||||
|
//
|
||||||
|
void assistantService() {
|
||||||
|
LogUtils.d(TAG, "assistantService()");
|
||||||
|
mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
|
||||||
|
LogUtils.d(TAG, String.format("mMainServiceBean.isEnable() %s", mMainServiceBean.isEnable()));
|
||||||
|
if (mMainServiceBean.isEnable()) {
|
||||||
|
LogUtils.d(TAG, String.format("mIsThreadAlive %s", isThreadAlive()));
|
||||||
|
if (isThreadAlive() == false) {
|
||||||
|
// 设置运行状态
|
||||||
|
setIsThreadAlive(true);
|
||||||
|
// 唤醒和绑定主进程
|
||||||
|
wakeupAndBindMain();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 唤醒和绑定主进程
|
||||||
|
//
|
||||||
|
void wakeupAndBindMain() {
|
||||||
|
LogUtils.d(TAG, "wakeupAndBindMain()");
|
||||||
|
// 绑定服务的Intent
|
||||||
|
Intent intent = new Intent(this, MainService.class);
|
||||||
|
startService(new Intent(this, MainService.class));
|
||||||
|
bindService(intent, mMyServiceConnection, Context.BIND_IMPORTANT);
|
||||||
|
|
||||||
|
// startService(new Intent(this, MainService.class));
|
||||||
|
// bindService(new Intent(AssistantService.this, MainService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 主进程与守护进程连接时需要用到此类
|
||||||
|
//
|
||||||
|
class MyServiceConnection implements ServiceConnection {
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
|
LogUtils.d(TAG, "onServiceConnected(...)");
|
||||||
|
MainService.MyBinder binder = (MainService.MyBinder) service;
|
||||||
|
mMainService = binder.getService();
|
||||||
|
isBound = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
|
LogUtils.d(TAG, "onServiceDisconnected(...)");
|
||||||
|
mMainServiceBean = MainServiceBean.loadBean(AssistantService.this, MainServiceBean.class);
|
||||||
|
if (mMainServiceBean.isEnable()) {
|
||||||
|
wakeupAndBindMain();
|
||||||
|
}
|
||||||
|
isBound = false;
|
||||||
|
mMainService = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用于返回服务实例的Binder
|
||||||
|
public class MyBinder extends Binder {
|
||||||
|
AssistantService getService() {
|
||||||
|
LogUtils.d(TAG, "AssistantService MyBinder getService()");
|
||||||
|
return AssistantService.this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,228 @@
|
|||||||
|
package cc.winboll.studio.positions.services;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/13 06:56:41
|
||||||
|
* @Describe 拨号主服务
|
||||||
|
* 参考:
|
||||||
|
* 进程保活-双进程守护的正确姿势
|
||||||
|
* https://blog.csdn.net/sinat_35159441/article/details/75267380
|
||||||
|
* Android Service之onStartCommand方法研究
|
||||||
|
* https://blog.csdn.net/cyp331203/article/details/38920491
|
||||||
|
*/
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.ServiceConnection;
|
||||||
|
import android.os.Binder;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import cc.winboll.studio.libappbase.SOS;
|
||||||
|
import cc.winboll.studio.libappbase.bean.APPSOSBean;
|
||||||
|
import cc.winboll.studio.positions.beans.MainServiceBean;
|
||||||
|
import cc.winboll.studio.positions.handlers.MainServiceHandler;
|
||||||
|
import cc.winboll.studio.positions.receivers.MainReceiver;
|
||||||
|
import cc.winboll.studio.positions.services.MainService;
|
||||||
|
import cc.winboll.studio.positions.threads.MainServiceThread;
|
||||||
|
|
||||||
|
public class MainService extends Service {
|
||||||
|
|
||||||
|
public static final String TAG = "MainService";
|
||||||
|
|
||||||
|
public static final int MSG_UPDATE_STATUS = 0;
|
||||||
|
|
||||||
|
static MainService _mControlCenterService;
|
||||||
|
|
||||||
|
volatile boolean isServiceRunning;
|
||||||
|
|
||||||
|
MainServiceBean mMainServiceBean;
|
||||||
|
MainServiceThread mMainServiceThread;
|
||||||
|
MainServiceHandler mMainServiceHandler;
|
||||||
|
MyServiceConnection mMyServiceConnection;
|
||||||
|
AssistantService mAssistantService;
|
||||||
|
boolean isBound = false;
|
||||||
|
MainReceiver mMainReceiver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return new MyBinder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MainServiceThread getRemindThread() {
|
||||||
|
return mMainServiceThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
LogUtils.d(TAG, "onCreate()");
|
||||||
|
_mControlCenterService = MainService.this;
|
||||||
|
isServiceRunning = false;
|
||||||
|
mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
|
||||||
|
|
||||||
|
if (mMyServiceConnection == null) {
|
||||||
|
mMyServiceConnection = new MyServiceConnection();
|
||||||
|
}
|
||||||
|
mMainServiceHandler = new MainServiceHandler(this);
|
||||||
|
|
||||||
|
// 运行服务内容
|
||||||
|
mainService();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
LogUtils.d(TAG, "onStartCommand(...)");
|
||||||
|
// 运行服务内容
|
||||||
|
mainService();
|
||||||
|
return (mMainServiceBean.isEnable()) ? START_STICKY : super.onStartCommand(intent, flags, startId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 运行服务内容
|
||||||
|
//
|
||||||
|
void mainService() {
|
||||||
|
LogUtils.d(TAG, "mainService()");
|
||||||
|
mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
|
||||||
|
if (mMainServiceBean.isEnable() && isServiceRunning == false) {
|
||||||
|
LogUtils.d(TAG, "mainService() start running");
|
||||||
|
isServiceRunning = true;
|
||||||
|
// 唤醒守护进程
|
||||||
|
wakeupAndBindAssistant();
|
||||||
|
// 召唤 WinBoll APP 绑定本服务
|
||||||
|
SOS.bindToAPPService(this, new APPSOSBean(getPackageName(), MainService.class.getName()));
|
||||||
|
|
||||||
|
if (mMainReceiver == null) {
|
||||||
|
// 注册广播接收器
|
||||||
|
mMainReceiver = new MainReceiver(this);
|
||||||
|
mMainReceiver.registerAction(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MainServiceThread.getInstance(this, mMainServiceHandler).start();
|
||||||
|
|
||||||
|
LogUtils.i(TAG, "Main Service Is Start.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 唤醒和绑定守护进程
|
||||||
|
//
|
||||||
|
void wakeupAndBindAssistant() {
|
||||||
|
LogUtils.d(TAG, "wakeupAndBindAssistant()");
|
||||||
|
// if (ServiceUtils.isServiceAlive(getApplicationContext(), AssistantService.class.getName()) == false) {
|
||||||
|
// startService(new Intent(MainService.this, AssistantService.class));
|
||||||
|
// //LogUtils.d(TAG, "call wakeupAndBindAssistant() : Binding... AssistantService");
|
||||||
|
// bindService(new Intent(MainService.this, AssistantService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
|
||||||
|
// }
|
||||||
|
Intent intent = new Intent(this, AssistantService.class);
|
||||||
|
startService(intent);
|
||||||
|
// 绑定服务的Intent
|
||||||
|
//Intent intent = new Intent(this, AssistantService.class);
|
||||||
|
bindService(intent, mMyServiceConnection, Context.BIND_IMPORTANT);
|
||||||
|
|
||||||
|
// Intent intent = new Intent(this, AssistantService.class);
|
||||||
|
// startService(intent);
|
||||||
|
// LogUtils.d(TAG, "startService(intent)");
|
||||||
|
// bindService(new Intent(this, AssistantService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
//LogUtils.d(TAG, "onDestroy");
|
||||||
|
mMainServiceBean = MainServiceBean.loadBean(this, MainServiceBean.class);
|
||||||
|
//LogUtils.d(TAG, "onDestroy done");
|
||||||
|
if (mMainServiceBean.isEnable() == false) {
|
||||||
|
// 设置运行状态
|
||||||
|
isServiceRunning = false;// 解除绑定
|
||||||
|
if (isBound) {
|
||||||
|
unbindService(mMyServiceConnection);
|
||||||
|
isBound = false;
|
||||||
|
}
|
||||||
|
// 停止守护进程
|
||||||
|
Intent intent = new Intent(this, AssistantService.class);
|
||||||
|
stopService(intent);
|
||||||
|
// 停止Receiver
|
||||||
|
if (mMainReceiver != null) {
|
||||||
|
unregisterReceiver(mMainReceiver);
|
||||||
|
mMainReceiver = null;
|
||||||
|
}
|
||||||
|
// 停止前台通知栏
|
||||||
|
stopForeground(true);
|
||||||
|
|
||||||
|
// 停止主要进程
|
||||||
|
MainServiceThread.getInstance(this, mMainServiceHandler).setIsExit(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 主进程与守护进程连接时需要用到此类
|
||||||
|
//
|
||||||
|
private class MyServiceConnection implements ServiceConnection {
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
|
LogUtils.d(TAG, "onServiceConnected(...)");
|
||||||
|
AssistantService.MyBinder binder = (AssistantService.MyBinder) service;
|
||||||
|
mAssistantService = binder.getService();
|
||||||
|
isBound = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
|
LogUtils.d(TAG, "onServiceDisconnected(...)");
|
||||||
|
if (mMainServiceBean.isEnable()) {
|
||||||
|
// 唤醒守护进程
|
||||||
|
wakeupAndBindAssistant();
|
||||||
|
SOS.sosWinBollService(getApplicationContext(), new APPSOSBean(getPackageName(), MainService.class.getName()));
|
||||||
|
}
|
||||||
|
isBound = false;
|
||||||
|
mAssistantService = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 用于返回服务实例的Binder
|
||||||
|
public class MyBinder extends Binder {
|
||||||
|
MainService getService() {
|
||||||
|
LogUtils.d(TAG, "MainService MyBinder getService()");
|
||||||
|
return MainService.this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // 启动服务
|
||||||
|
// //
|
||||||
|
// public static void startControlCenterService(Context context) {
|
||||||
|
// Intent intent = new Intent(context, MainService.class);
|
||||||
|
// context.startForegroundService(intent);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //
|
||||||
|
// // 停止服务
|
||||||
|
// //
|
||||||
|
// public static void stopControlCenterService(Context context) {
|
||||||
|
// Intent intent = new Intent(context, MainService.class);
|
||||||
|
// context.stopService(intent);
|
||||||
|
// }
|
||||||
|
|
||||||
|
public void appenMessage(String message) {
|
||||||
|
LogUtils.d(TAG, String.format("Message : %s", message));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stopMainService(Context context) {
|
||||||
|
LogUtils.d(TAG, "stopMainService");
|
||||||
|
MainServiceBean bean = new MainServiceBean();
|
||||||
|
bean.setIsEnable(false);
|
||||||
|
MainServiceBean.saveBean(context, bean);
|
||||||
|
context.stopService(new Intent(context, MainService.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startMainService(Context context) {
|
||||||
|
LogUtils.d(TAG, "startMainService");
|
||||||
|
MainServiceBean bean = new MainServiceBean();
|
||||||
|
bean.setIsEnable(true);
|
||||||
|
MainServiceBean.saveBean(context, bean);
|
||||||
|
context.startService(new Intent(context, MainService.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,77 @@
|
|||||||
|
package cc.winboll.studio.positions.threads;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen@AliYun.Com
|
||||||
|
* @Date 2025/02/14 03:46:44
|
||||||
|
*/
|
||||||
|
import android.content.Context;
|
||||||
|
import cc.winboll.studio.positions.handlers.MainServiceHandler;
|
||||||
|
import cc.winboll.studio.positions.services.MainService;
|
||||||
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import cc.winboll.studio.libappbase.SOS;
|
||||||
|
import cc.winboll.studio.libappbase.bean.APPSOSBean;
|
||||||
|
import com.hjq.toast.ToastUtils;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
public class MainServiceThread extends Thread {
|
||||||
|
|
||||||
|
public static final String TAG = "MainServiceThread";
|
||||||
|
|
||||||
|
volatile static MainServiceThread _MainServiceThread;
|
||||||
|
// 控制线程是否退出的标志
|
||||||
|
volatile boolean isExit = false;
|
||||||
|
volatile boolean isStarted = false;
|
||||||
|
Context mContext;
|
||||||
|
// 服务Handler, 用于线程发送消息使用
|
||||||
|
WeakReference<MainServiceHandler> mwrMainServiceHandler;
|
||||||
|
|
||||||
|
MainServiceThread(Context context, MainServiceHandler handler) {
|
||||||
|
mContext = context;
|
||||||
|
mwrMainServiceHandler = new WeakReference<MainServiceHandler>(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsExit(boolean isExit) {
|
||||||
|
this.isExit = isExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isExit() {
|
||||||
|
return isExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsStarted(boolean isStarted) {
|
||||||
|
this.isStarted = isStarted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStarted() {
|
||||||
|
return isStarted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MainServiceThread getInstance(Context context, MainServiceHandler handler) {
|
||||||
|
if (_MainServiceThread != null) {
|
||||||
|
_MainServiceThread.setIsExit(true);
|
||||||
|
}
|
||||||
|
_MainServiceThread = new MainServiceThread(context, handler);
|
||||||
|
return _MainServiceThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (isStarted == false) {
|
||||||
|
isStarted = true;
|
||||||
|
LogUtils.d(TAG, "run()");
|
||||||
|
|
||||||
|
while (!isExit()) {
|
||||||
|
//ToastUtils.show("run");
|
||||||
|
//LogUtils.d(TAG, "run()");
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_MainServiceThread = null;
|
||||||
|
LogUtils.d(TAG, "run() exit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
positions/src/main/res/drawable/ic_launcher.xml
Normal file
11
positions/src/main/res/drawable/ic_launcher.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:clickable="true">
|
||||||
|
<item android:drawable="@drawable/ic_launcher_background"/>
|
||||||
|
<item
|
||||||
|
android:left="15dp"
|
||||||
|
android:top="15dp"
|
||||||
|
android:right="15dp"
|
||||||
|
android:bottom="15dp"
|
||||||
|
android:drawable="@drawable/ic_launcher_foreground"/>
|
||||||
|
</layer-list>
|
170
positions/src/main/res/drawable/ic_launcher_background.xml
Normal file
170
positions/src/main/res/drawable/ic_launcher_background.xml
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/colorPrimary"
|
||||||
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M9,0L9,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,0L19,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,0L29,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,0L39,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,0L49,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,0L59,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,0L69,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,0L79,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M89,0L89,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M99,0L99,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,9L108,9"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,19L108,19"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,29L108,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,39L108,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,49L108,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,59L108,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,69L108,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,79L108,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,89L108,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,99L108,99"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,29L89,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,39L89,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,49L89,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,59L89,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,69L89,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,79L89,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,19L29,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,19L39,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,19L49,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,19L59,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,19L69,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,19L79,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
</vector>
|
11
positions/src/main/res/drawable/ic_launcher_disable.xml
Normal file
11
positions/src/main/res/drawable/ic_launcher_disable.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:clickable="true">
|
||||||
|
<item android:drawable="@drawable/ic_launcher_background"/>
|
||||||
|
<item
|
||||||
|
android:left="15dp"
|
||||||
|
android:top="15dp"
|
||||||
|
android:right="15dp"
|
||||||
|
android:bottom="15dp"
|
||||||
|
android:drawable="@drawable/ic_launcher_foreground_disable"/>
|
||||||
|
</layer-list>
|
10
positions/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
10
positions/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:viewportWidth="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M16.61,15.15C16.15,15.15 15.77,14.78 15.77,14.32S16.15,13.5 16.61,13.5H16.61C17.07,13.5 17.45,13.86 17.45,14.32C17.45,14.78 17.07,15.15 16.61,15.15M7.41,15.15C6.95,15.15 6.57,14.78 6.57,14.32C6.57,13.86 6.95,13.5 7.41,13.5H7.41C7.87,13.5 8.24,13.86 8.24,14.32C8.24,14.78 7.87,15.15 7.41,15.15M16.91,10.14L18.58,7.26C18.67,7.09 18.61,6.88 18.45,6.79C18.28,6.69 18.07,6.75 18,6.92L16.29,9.83C14.95,9.22 13.5,8.9 12,8.91C10.47,8.91 9,9.24 7.73,9.82L6.04,6.91C5.95,6.74 5.74,6.68 5.57,6.78C5.4,6.87 5.35,7.08 5.44,7.25L7.1,10.13C4.25,11.69 2.29,14.58 2,18H22C21.72,14.59 19.77,11.7 16.91,10.14H16.91Z"/>
|
||||||
|
</vector>
|
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:viewportWidth="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFAAAAAA"
|
||||||
|
android:pathData="M16.61,15.15C16.15,15.15 15.77,14.78 15.77,14.32S16.15,13.5 16.61,13.5H16.61C17.07,13.5 17.45,13.86 17.45,14.32C17.45,14.78 17.07,15.15 16.61,15.15M7.41,15.15C6.95,15.15 6.57,14.78 6.57,14.32C6.57,13.86 6.95,13.5 7.41,13.5H7.41C7.87,13.5 8.24,13.86 8.24,14.32C8.24,14.78 7.87,15.15 7.41,15.15M16.91,10.14L18.58,7.26C18.67,7.09 18.61,6.88 18.45,6.79C18.28,6.69 18.07,6.75 18,6.92L16.29,9.83C14.95,9.22 13.5,8.9 12,8.91C10.47,8.91 9,9.24 7.73,9.82L6.04,6.91C5.95,6.74 5.74,6.68 5.57,6.78C5.4,6.87 5.35,7.08 5.44,7.25L7.1,10.13C4.25,11.69 2.29,14.58 2,18H22C21.72,14.59 19.77,11.7 16.91,10.14H16.91Z"/>
|
||||||
|
</vector>
|
10
positions/src/main/res/drawable/shape_gradient.xml
Normal file
10
positions/src/main/res/drawable/shape_gradient.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<gradient
|
||||||
|
android:angle="180"
|
||||||
|
android:endColor="#FFFFFFFF"
|
||||||
|
android:startColor="#FFFFFFFF"
|
||||||
|
android:type="linear" />
|
||||||
|
|
||||||
|
<corners android:radius="10dp" />
|
||||||
|
</shape>
|
27
positions/src/main/res/layout/activity_main.xml
Normal file
27
positions/src/main/res/layout/activity_main.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/activitymainToolbar1"/>
|
||||||
|
|
||||||
|
<androidx.viewpager.widget.ViewPager
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1.0"
|
||||||
|
android:id="@+id/activitymainViewPager1"/>
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:id="@+id/activitymainTabLayout1"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
46
positions/src/main/res/layout/activity_settings.xml
Normal file
46
positions/src/main/res/layout/activity_settings.xml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/activitymainToolbar1"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1.0">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="right">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="悬浮窗设置"
|
||||||
|
android:id="@+id/activitysettingsButton2"
|
||||||
|
android:onClick="onCanDrawOverlays"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="默认拨号设置"
|
||||||
|
android:id="@+id/activitysettingsButton1"
|
||||||
|
android:onClick="onDefaultPhone"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
29
positions/src/main/res/layout/fragment_call.xml
Normal file
29
positions/src/main/res/layout/fragment_call.xml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:ems="10"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1.0"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Text"
|
||||||
|
android:id="@+id/page_text"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
15
positions/src/main/res/layout/fragment_contacts.xml
Normal file
15
positions/src/main/res/layout/fragment_contacts.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Text"
|
||||||
|
android:id="@+id/page_text"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
12
positions/src/main/res/layout/fragment_log.xml
Normal file
12
positions/src/main/res/layout/fragment_log.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<cc.winboll.studio.libappbase.LogView
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:id="@+id/logview"/>
|
||||||
|
</LinearLayout>
|
32
positions/src/main/res/layout/view_toast.xml
Normal file
32
positions/src/main/res/layout/view_toast.xml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/shape_gradient"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="10dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:src="@drawable/ic_launcher"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@android:id/message"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
android:textColor="#FF000000"
|
||||||
|
android:textSize="16sp"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
8
positions/src/main/res/menu/toolbar_main.xml
Normal file
8
positions/src/main/res/menu/toolbar_main.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/item_settings"
|
||||||
|
android:title="SettingsActivity"/>
|
||||||
|
</menu>
|
7
positions/src/main/res/values/colors.xml
Normal file
7
positions/src/main/res/values/colors.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!-- WinBoll 默认方案 -->
|
||||||
|
<color name="colorPrimary">#FF196ABC</color>
|
||||||
|
<color name="colorPrimaryDark">#FF002B57</color>
|
||||||
|
<color name="colorAccent">#FF80BFFF</color>
|
||||||
|
</resources>
|
6
positions/src/main/res/values/strings.xml
Normal file
6
positions/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<string name="app_name">Positions</string>
|
||||||
|
|
||||||
|
</resources>
|
17
positions/src/main/res/values/styles.xml
Normal file
17
positions/src/main/res/values/styles.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<style name="MyAppTheme" parent="APPBaseTheme">
|
||||||
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
|
<item name="android:windowFullscreen">true</item>
|
||||||
|
<item name="android:windowContentOverlay">@null</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="GlobalCrashActivityTheme" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar">
|
||||||
|
<item name="colorTittle">@color/colorAccent</item>
|
||||||
|
<item name="colorTittleBackgound">@color/colorPrimary</item>
|
||||||
|
<item name="colorText">@color/colorAccent</item>
|
||||||
|
<item name="colorTextBackgound">@color/colorPrimaryDark</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
25
positions/src/main/res/xml/studio_provider.xml
Normal file
25
positions/src/main/res/xml/studio_provider.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<paths>
|
||||||
|
<external-path
|
||||||
|
name="external_storage_root"
|
||||||
|
path="." />
|
||||||
|
<files-path
|
||||||
|
name="files_path"
|
||||||
|
path="." />
|
||||||
|
<cache-path
|
||||||
|
name="cache_path"
|
||||||
|
path="." />
|
||||||
|
<!--/storage/emulated/0/Android/data/...-->
|
||||||
|
<external-files-path
|
||||||
|
name="external_file_path"
|
||||||
|
path="." />
|
||||||
|
<!--代表app 外部存储区域根目录下的文件 Context.getExternalCacheDir目录下的目录-->
|
||||||
|
<external-cache-path
|
||||||
|
name="external_cache_path"
|
||||||
|
path="." />
|
||||||
|
<!--配置root-path。这样子可以读取到sd卡和一些应用分身的目录,否则微信分身保存的图片,就会导致 java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/999/tencent/MicroMsg/WeiXin/export1544062754693.jpg,在小米6的手机上微信分身有这个crash,华为没有
|
||||||
|
-->
|
||||||
|
<root-path
|
||||||
|
name="root_path"
|
||||||
|
path="" />
|
||||||
|
</paths>
|
12
positions/src/stage/AndroidManifest.xml
Normal file
12
positions/src/stage/AndroidManifest.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools" >
|
||||||
|
|
||||||
|
<application>
|
||||||
|
|
||||||
|
<!-- Put flavor specific code here -->
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
|
|
6
positions/src/stage/res/values/strings.xml
Normal file
6
positions/src/stage/res/values/strings.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Put flavor specific strings here -->
|
||||||
|
|
||||||
|
</resources>
|
@ -37,3 +37,8 @@
|
|||||||
//include ':aes'
|
//include ':aes'
|
||||||
//include ':libaes'
|
//include ':libaes'
|
||||||
//rootProject.name = "aes"
|
//rootProject.name = "aes"
|
||||||
|
|
||||||
|
// Positions 项目编译设置
|
||||||
|
//include ':positions'
|
||||||
|
//rootProject.name = "positions"
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Fri Nov 29 11:55:20 GMT 2024
|
#Fri Feb 21 17:45:37 GMT 2025
|
||||||
stageCount=0
|
stageCount=1
|
||||||
libraryProject=winboll-shared
|
libraryProject=winboll-shared
|
||||||
baseVersion=1.8
|
baseVersion=1.0
|
||||||
publishVersion=1.8.16
|
publishVersion=1.0.0
|
||||||
buildCount=0
|
buildCount=1
|
||||||
baseBetaVersion=1.8.17
|
baseBetaVersion=1.0.1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user