更新重构
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="11" />
|
||||
<bytecodeTargetLevel target="17" />
|
||||
</component>
|
||||
</project>
|
@ -7,6 +7,7 @@
|
||||
<option name="testRunner" value="GRADLE" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="jbr-17" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
|
@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
@ -8,14 +8,17 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "run.evan.gost"
|
||||
minSdk 23
|
||||
minSdk 26
|
||||
targetSdk 32
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
aidl true
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
@ -49,12 +52,7 @@ tasks.withType(JavaCompile)
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')
|
||||
implementation 'androidx.appcompat:appcompat:1.5.1'
|
||||
implementation 'com.google.android.material:material:1.7.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.4'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
|
||||
implementation 'androidx.annotation:annotation:1.3.0'
|
||||
}
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 845 B |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 8.7 KiB |
@ -22,7 +22,6 @@
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Gost"
|
||||
tools:targetApi="31">
|
||||
|
@ -38,12 +38,15 @@ public class GostService extends Service {
|
||||
Channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
|
||||
manager.createNotificationChannel(Channel);
|
||||
}
|
||||
|
||||
Notification.Builder builder = new Notification.Builder(this);
|
||||
builder = builder.setContentTitle("GOST")
|
||||
.setContentText(getResources().getString(R.string.service_text))
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setSmallIcon(R.mipmap.ic_launcher)
|
||||
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
|
||||
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
|
||||
.setAutoCancel(false)
|
||||
.setPriority(Notification.PRIORITY_HIGH);
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
builder = builder.setChannelId(CHANNEL_ID);
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package run.evan.gost;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
@ -14,40 +14,26 @@ import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.PowerManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.method.ScrollingMovementMethod;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.security.Permissions;
|
||||
import java.util.Map;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
import run.evan.gost.databinding.ActivityMainBinding;
|
||||
|
||||
Button btnSave;
|
||||
public class MainActivity extends Activity {
|
||||
|
||||
Button btnDelete;
|
||||
|
||||
Button btnStart;
|
||||
|
||||
EditText textView1;
|
||||
|
||||
EditText configEditText;
|
||||
private ActivityMainBinding binding;
|
||||
|
||||
Process process;
|
||||
|
||||
@ -57,8 +43,6 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
ArrayAdapter<String> starAdapter;
|
||||
|
||||
Spinner sp;
|
||||
|
||||
MyHandler handler = new MyHandler(this);
|
||||
|
||||
Intent gostServiceIntent;
|
||||
@ -84,21 +68,26 @@ public class MainActivity extends AppCompatActivity {
|
||||
if (null != activity) {
|
||||
switch (msg.what) {
|
||||
case 1:
|
||||
activity.textView1.append(msg.obj.toString());
|
||||
activity.textView1.setSelection(activity.textView1.getText().length());
|
||||
int length = activity.binding.textView.getText().length();
|
||||
String s = activity.binding.textView.getText().toString();
|
||||
if (length > 5000) {
|
||||
activity.binding.textView.setText(s.substring(2500));
|
||||
}
|
||||
activity.binding.textView.append(msg.obj.toString());
|
||||
activity.binding.textView.setSelection(activity.binding.textView.getText().length());
|
||||
break;
|
||||
case 2:
|
||||
activity.btnStart.setText(R.string.btn_stop);
|
||||
activity.btnStart.setBackgroundTintList(ColorStateList.valueOf(-1499549));
|
||||
activity.binding.btnStart.setText(R.string.btn_stop);
|
||||
activity.binding.btnStart.setBackgroundTintList(ColorStateList.valueOf(-1499549));
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
activity.getApplicationContext().startForegroundService(activity.gostServiceIntent);
|
||||
}else {
|
||||
} else {
|
||||
activity.getApplicationContext().startService(activity.gostServiceIntent);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
activity.btnStart.setText(R.string.btn_start);
|
||||
activity.btnStart.setBackgroundTintList(ColorStateList.valueOf(-11751600));
|
||||
activity.binding.btnStart.setText(R.string.btn_start);
|
||||
activity.binding.btnStart.setBackgroundTintList(ColorStateList.valueOf(-11751600));
|
||||
activity.getApplicationContext().stopService(activity.gostServiceIntent);
|
||||
default:
|
||||
}
|
||||
@ -110,15 +99,18 @@ public class MainActivity extends AppCompatActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
gostServiceIntent = new Intent(MainActivity.this, GostService.class);
|
||||
appPreferences = getSharedPreferences("app", MODE_PRIVATE);
|
||||
|
||||
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|
||||
|| ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|
||||
|| ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS) != PackageManager.PERMISSION_GRANTED
|
||||
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|
||||
|| checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|
||||
|| checkSelfPermission(Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS) != PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS}, 10);
|
||||
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS}, 10);
|
||||
}
|
||||
// android 11 且 不是已经被拒绝
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !appPreferences.getBoolean("refuse", false)) {
|
||||
@ -130,40 +122,42 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
textView1 = findViewById(R.id.textView);
|
||||
textView1.setMovementMethod(ScrollingMovementMethod.getInstance());
|
||||
configEditText = findViewById(R.id.configEditText);
|
||||
binding.textView.setMovementMethod(ScrollingMovementMethod.getInstance());
|
||||
configPreferences = getSharedPreferences("config", MODE_PRIVATE);
|
||||
|
||||
|
||||
sp = findViewById(R.id.spinner);
|
||||
starAdapter = new ArrayAdapter<String>(this, R.layout.item_select);
|
||||
starAdapter.setDropDownViewResource(R.layout.item_dropdown);
|
||||
sp.setAdapter(starAdapter);
|
||||
binding.spinner.setAdapter(starAdapter);
|
||||
binding.configEditText.setVisibility(View.GONE);
|
||||
reloadConfig();
|
||||
//给下拉框设置选择监听器,一旦用户选中某一项,就触发监听器的onItemSelected方法
|
||||
sp.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
binding.spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
configEditText.setText(configPreferences.getString(adapterView.getSelectedItem().toString(), ""));
|
||||
binding.configEditText.setText(configPreferences.getString(adapterView.getSelectedItem().toString(), ""));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> adapterView) {
|
||||
configEditText.setText("");
|
||||
binding.configEditText.setText("");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
btnSave = findViewById(R.id.button1);
|
||||
btnDelete = findViewById(R.id.button2);
|
||||
btnStart = findViewById(R.id.button3);
|
||||
MainActivity mainActivity = this;
|
||||
btnSave.setOnClickListener(new View.OnClickListener() {
|
||||
binding.btnSave.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
||||
String config = configEditText.getText().toString();
|
||||
int visibility = binding.configEditText.getVisibility();
|
||||
if (visibility == View.GONE) {
|
||||
binding.configEditText.setVisibility(View.VISIBLE);
|
||||
binding.btnSave.setText(R.string.btn_save);
|
||||
return;
|
||||
}
|
||||
|
||||
String config = binding.configEditText.getText().toString();
|
||||
if ("".contains(config)) {
|
||||
Toast.makeText(getApplicationContext(), R.string.toast_tip_config_empty, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
@ -173,7 +167,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
builder.setTitle(R.string.title_config_box);
|
||||
final EditText input = new EditText(mainActivity);
|
||||
input.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
Object selectedItem = sp.getSelectedItem();
|
||||
Object selectedItem = binding.spinner.getSelectedItem();
|
||||
input.setText(selectedItem == null ? "" : selectedItem.toString());
|
||||
builder.setView(input);
|
||||
|
||||
@ -189,12 +183,15 @@ public class MainActivity extends AppCompatActivity {
|
||||
edit.putString(configName, config);
|
||||
edit.apply();
|
||||
reloadConfig();
|
||||
binding.btnSave.setText(R.string.btn_edit);
|
||||
binding.configEditText.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(R.string.title_btn_cancel, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.cancel();
|
||||
binding.configEditText.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
|
||||
@ -204,11 +201,11 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
});
|
||||
|
||||
btnDelete.setOnClickListener(new View.OnClickListener() {
|
||||
binding.btnDelete.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
||||
if (null == sp.getSelectedItem()) {
|
||||
if (null == binding.spinner.getSelectedItem()) {
|
||||
Toast.makeText(getApplicationContext(), R.string.tip_config_not_selected, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
@ -218,7 +215,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
builder.setPositiveButton(R.string.title_yes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
String key = sp.getSelectedItem().toString();
|
||||
String key = binding.spinner.getSelectedItem().toString();
|
||||
SharedPreferences.Editor edit = configPreferences.edit();
|
||||
edit.remove(key);
|
||||
edit.apply();
|
||||
@ -236,14 +233,14 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
});
|
||||
|
||||
btnStart.setOnClickListener(new View.OnClickListener() {
|
||||
binding.btnStart.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
String basedir = getApplication().getApplicationInfo().nativeLibraryDir;
|
||||
String config = configEditText.getText().toString();
|
||||
String config = binding.configEditText.getText().toString();
|
||||
|
||||
if (null != sp.getSelectedItem()) {
|
||||
String key = sp.getSelectedItem().toString();
|
||||
if (null != binding.spinner.getSelectedItem()) {
|
||||
String key = binding.spinner.getSelectedItem().toString();
|
||||
appPreferences.edit().putString("lastConfig", key).apply();
|
||||
}
|
||||
|
||||
@ -350,7 +347,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
for (String s : all.keySet()) {
|
||||
starAdapter.add(s);
|
||||
if (s.equals(lastConfig)) {
|
||||
sp.setSelection(count);
|
||||
binding.spinner.setSelection(count);
|
||||
lastValid = true;
|
||||
}
|
||||
count++;
|
||||
|
@ -1,65 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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"
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
tools:layout_editor_absoluteX="1dp"
|
||||
tools:layout_editor_absoluteY="1dp">
|
||||
android:layout_marginRight="10dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textTipConfig"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="18sp"
|
||||
android:text="@string/text_tip_config" />
|
||||
android:text="@string/text_tip_config"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="horizontal">
|
||||
<Spinner
|
||||
android:id="@+id/spinner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:spinnerMode="dropdown" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnSave"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/btn_edit"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnDelete"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/btn_del"
|
||||
android:textAllCaps="false" />
|
||||
</LinearLayout>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/configEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="120dp"
|
||||
android:ems="10"
|
||||
android:gravity="start|top"
|
||||
android:scrollbars="vertical"
|
||||
android:inputType="textMultiLine" />
|
||||
android:inputType="textMultiLine"
|
||||
android:scrollbars="vertical" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAllCaps="false"
|
||||
android:text="@string/btn_save" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/btn_del"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button3"
|
||||
android:id="@+id/btnStart"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:backgroundTint="#4CAF50"
|
||||
android:textColor="#FFFFFF"
|
||||
android:text="@string/btn_start"
|
||||
android:textAllCaps="false" />
|
||||
android:textAllCaps="false"
|
||||
android:textColor="#FFFFFF" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/textView"
|
||||
@ -69,7 +72,8 @@
|
||||
android:gravity="start|top"
|
||||
android:inputType="textMultiLine"
|
||||
android:scrollbars="vertical"
|
||||
android:textSize="10sp" />
|
||||
android:textSize="10dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</ScrollView>
|
@ -16,4 +16,5 @@
|
||||
<string name="title_no">否</string>
|
||||
<string name="tip_config_not_selected">未选择配置</string>
|
||||
<string name="service_text">GOST运行中</string>
|
||||
<string name="btn_edit">编辑</string>
|
||||
</resources>
|
@ -15,4 +15,5 @@
|
||||
<string name="title_no">No</string>
|
||||
<string name="tip_config_not_selected">No config selected</string>
|
||||
<string name="service_text">GOST is running</string>
|
||||
<string name="btn_edit">Edit</string>
|
||||
</resources>
|
@ -1,8 +1,6 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.Gost" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimary</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<style name="Theme.Gost" parent="@android:style/Theme.DeviceDefault.Light">
|
||||
<item name="android:colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
</resources>
|