| @@ -45,4 +45,9 @@ | |||||
| * 路径: `/app-keystore.jks` | * 路径: `/app-keystore.jks` | ||||
| * 密码: `ns61GK32x%` | * 密码: `ns61GK32x%` | ||||
| * Key Alias: `nsgk_rural_web` | * Key Alias: `nsgk_rural_web` | ||||
| * Key Password: `ns61GK32x%` | |||||
| * Key Password: `ns61GK32x%` | |||||
| > 示例 | |||||
| ```shell | |||||
| .\打包-正式.bat http://mxixiaxian.nongshen.net/sunVillage_info/login_code_new 阳光三资 ygcw | |||||
| ``` | |||||
| @@ -1,34 +0,0 @@ | |||||
| package com.nsgk.ruralWeb; | |||||
| public class Constants | |||||
| { | |||||
| /** | |||||
| * App首页链接地址 | |||||
| * 可以在 /gradle.properties 里配置 appHomeUrl=链接地址, 不要携带双引号 | |||||
| * 也可以在命令行添加 -PappHomeUrl="链接地址", 双引号可携带也可不携带 | |||||
| */ | |||||
| public static String AppHomeUrl() | |||||
| { | |||||
| return BuildConfig.APP_HOME_URL; | |||||
| } | |||||
| /** | |||||
| * App启动页版权文本 | |||||
| * 可以在 /gradle.properties 里配置 appCopyright=文本, 不要携带双引号 | |||||
| * 也可以在命令行添加 -PappCopyright="文本", 双引号可携带也可不携带 | |||||
| */ | |||||
| public static String AppCopyright() | |||||
| { | |||||
| return BuildConfig.APP_COMPYRIGHT; | |||||
| } | |||||
| /** | |||||
| * App启动页厂商文本 | |||||
| * 可以在 /gradle.properties 里配置 appVendor=文本, 不要携带双引号 | |||||
| * 也可以在命令行添加 -PappVendor="文本", 双引号可携带也可不携带 | |||||
| */ | |||||
| public static String AppVendor() | |||||
| { | |||||
| return BuildConfig.APP_VENDOR; | |||||
| } | |||||
| } | |||||
| @@ -1,263 +0,0 @@ | |||||
| package com.nsgk.ruralWeb; | |||||
| import android.annotation.SuppressLint; | |||||
| import android.app.Activity; | |||||
| import android.location.Criteria; | |||||
| import android.location.LocationManager; | |||||
| import android.Manifest; | |||||
| import android.content.Context; | |||||
| import android.content.pm.PackageManager; | |||||
| import android.location.Location; | |||||
| import android.location.LocationManager; | |||||
| import android.location.LocationProvider; | |||||
| import android.os.Build; | |||||
| import android.os.Handler; | |||||
| import android.util.Log; | |||||
| import android.webkit.JavascriptInterface; | |||||
| import android.webkit.ValueCallback; | |||||
| import android.webkit.WebView; | |||||
| import android.widget.Toast; | |||||
| import androidx.core.app.ActivityCompat; | |||||
| import com.nsgk.ruralWeb.utils.ContextUtils; | |||||
| import java.util.HashMap; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import java.util.concurrent.CompletableFuture; | |||||
| public class EnvWindowObject | |||||
| { | |||||
| private static final String ID_TAG = EnvWindowObject.class.getName(); | |||||
| private static final String FUSED_PROVIDER = "fused"; | |||||
| private final Handler m_handler; | |||||
| private final Context m_context; | |||||
| private final WebView m_webView; | |||||
| // 最近一次获取到的定位坐标, 如果获取定位失败则返回此值. 可能不需要, 因为PASSIVE_PROVIDER就为最近的定位 | |||||
| private String lastLocation = null; | |||||
| public EnvWindowObject(Context context, Handler handler, WebView webView) | |||||
| { | |||||
| m_context = context; | |||||
| m_handler = handler; | |||||
| m_webView = webView; | |||||
| } | |||||
| @JavascriptInterface | |||||
| public void Toast(final String message) | |||||
| { | |||||
| ShowToast(message, Toast.LENGTH_LONG); | |||||
| } | |||||
| private void ShowToast(final String message, int duration) | |||||
| { | |||||
| RunOnUIThread(new Runnable() { | |||||
| @Override | |||||
| public void run() | |||||
| { | |||||
| Toast.makeText(m_context, message, duration).show(); | |||||
| } | |||||
| }); | |||||
| } | |||||
| @JavascriptInterface | |||||
| public void Log(final String message) | |||||
| { | |||||
| Log.i(ID_TAG, message); | |||||
| } | |||||
| @JavascriptInterface | |||||
| public String GetLocation(final String type) | |||||
| { | |||||
| try | |||||
| { | |||||
| if(ActivityCompat.checkSelfPermission(m_context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(m_context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) | |||||
| { | |||||
| Activity activity = (Activity) m_context; | |||||
| if (activity.shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION) && activity.shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_COARSE_LOCATION)) // do not ask | |||||
| { | |||||
| Toast.makeText(m_context, "请先允许定位服务", Toast.LENGTH_LONG).show(); | |||||
| ContextUtils.RequestLocationPermission(activity, FullscreenActivity.PERMISSION_LOCATION_REQUEST_CODE); | |||||
| } | |||||
| else | |||||
| { | |||||
| activity.requestPermissions(new String[] { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }, FullscreenActivity.PERMISSION_LOCATION_REQUEST_CODE); | |||||
| } | |||||
| return lastLocation; | |||||
| } | |||||
| LocationInfo loc; | |||||
| loc = GetHighLocation(null); | |||||
| if(null == loc) | |||||
| loc = GetLastLocation(type); | |||||
| if(null != loc) | |||||
| lastLocation = loc.longitude + "," + loc.latitude; | |||||
| else | |||||
| ShowToast("定位失败, 请先开启位置服务", Toast.LENGTH_LONG); | |||||
| } | |||||
| catch(Throwable e) | |||||
| { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return lastLocation; | |||||
| } | |||||
| @SuppressLint("MissingPermission") | |||||
| private LocationInfo GetLastLocation(final String type) | |||||
| { | |||||
| LocationInfo loc = null; | |||||
| try | |||||
| { | |||||
| LocationManager lm = (LocationManager) m_context.getSystemService(Context.LOCATION_SERVICE); | |||||
| List<String> allProviders = lm.getAllProviders(); | |||||
| Log.i("NSGK", "使用最近所有定位提供器: " + allProviders); | |||||
| Map<String, LocationInfo> map = new HashMap<>(); | |||||
| for(String provider : allProviders) | |||||
| { | |||||
| Location lastKnownLocation = lm.getLastKnownLocation(provider); | |||||
| if(null == lastKnownLocation) | |||||
| continue; | |||||
| LocationInfo l = new LocationInfo(provider, lastKnownLocation.getLongitude(), lastKnownLocation.getLatitude()); | |||||
| map.put(provider, l); | |||||
| } | |||||
| Log.i("NSGK", "最近定位提供器结果: " + map); | |||||
| if(null != type && !type.isEmpty() && map.containsKey(type)) | |||||
| loc = map.get(type); | |||||
| else if(map.containsKey(FUSED_PROVIDER)) | |||||
| loc = map.get(FUSED_PROVIDER); | |||||
| else if(map.containsKey(LocationManager.GPS_PROVIDER)) | |||||
| loc = map.get(LocationManager.GPS_PROVIDER); | |||||
| else if(map.containsKey(LocationManager.NETWORK_PROVIDER)) | |||||
| loc = map.get(LocationManager.NETWORK_PROVIDER); | |||||
| else if(map.containsKey(LocationManager.PASSIVE_PROVIDER)) | |||||
| loc = map.get(LocationManager.PASSIVE_PROVIDER); | |||||
| if(null == loc) | |||||
| Log.i("NSGK", "所有提供器无最近定位"); | |||||
| else | |||||
| Log.i("NSGK", "使用提供器最近定位: " + loc.provider); | |||||
| } | |||||
| catch(Throwable e) | |||||
| { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return loc; | |||||
| } | |||||
| @SuppressLint("MissingPermission") | |||||
| private LocationInfo GetHighLocation(String provider) | |||||
| { | |||||
| if(Build.VERSION.SDK_INT < Build.VERSION_CODES.R) | |||||
| { | |||||
| return null; | |||||
| } | |||||
| LocationInfo loc = null; | |||||
| try | |||||
| { | |||||
| LocationManager lm = (LocationManager) m_context.getSystemService(Context.LOCATION_SERVICE); | |||||
| if(null == provider) | |||||
| { | |||||
| Criteria criteria = new Criteria(); | |||||
| criteria.setAccuracy(Criteria.ACCURACY_FINE); // 高精度 | |||||
| // criteria.setPowerRequirement(Criteria.POWER_HIGH); | |||||
| // criteria.setAltitudeRequired(false); | |||||
| provider = lm.getBestProvider(criteria, true); | |||||
| } | |||||
| Log.i("NSGK", "使用高精度定位提供器: " + provider); | |||||
| if(null == provider) | |||||
| { | |||||
| Log.i("NSGK", "无法获取高精度定位提供器"); | |||||
| return null; | |||||
| } | |||||
| CompletableFuture<Location> future = new CompletableFuture<>(); | |||||
| if(null == lastLocation) | |||||
| ShowToast("定位中......", Toast.LENGTH_SHORT); | |||||
| lm.getCurrentLocation(provider, null, m_context.getMainExecutor(), future::complete); | |||||
| Location location = future.get(); | |||||
| if(null == location) | |||||
| { | |||||
| Log.i("NSGK", "无法使用高精度提供器定位"); | |||||
| return null; | |||||
| } | |||||
| loc = new LocationInfo(provider, location.getLongitude(), location.getLatitude()); | |||||
| Log.i("NSGK", "使用高精度提供器获取定位: " + loc); | |||||
| } | |||||
| catch(Throwable e) | |||||
| { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return loc; | |||||
| } | |||||
| protected void RunOnUIThread(Runnable runnable) | |||||
| { | |||||
| if(null != m_handler) | |||||
| m_handler.post(runnable); | |||||
| else if(m_context instanceof Activity) | |||||
| ((Activity)m_context).runOnUiThread(runnable); | |||||
| else | |||||
| { | |||||
| Log.e(ID_TAG, "无法在UI线程中执行"); | |||||
| } | |||||
| } | |||||
| protected void CallJSFunc(final String func, Object...args) | |||||
| { | |||||
| StringBuilder sb = new StringBuilder(); | |||||
| for(int i = 0; i < args.length; i++) | |||||
| { | |||||
| sb.append("'").append(args[i].toString()).append("'"); | |||||
| if(i < args.length - 1) | |||||
| sb.append(", "); | |||||
| } | |||||
| final String arg = sb.toString(); | |||||
| RunOnUIThread(new Runnable() { | |||||
| @Override | |||||
| public void run() | |||||
| { | |||||
| String script = "javascript:typeof(" + func + ") == 'function' && " + func + "(" + arg + ");"; | |||||
| Log.e(ID_TAG, String.format("调用js函数: 函数(%s), 参数(%s)", func, arg)); | |||||
| m_webView.evaluateJavascript(script, new ValueCallback<String>() { | |||||
| @Override | |||||
| public void onReceiveValue(String value) { | |||||
| Log.e(ID_TAG, String.format("js函数 %s 返回: %s", func, value)); | |||||
| } | |||||
| }); | |||||
| } | |||||
| }); | |||||
| } | |||||
| protected void CallJSFunc_beforeAndroid4_4(final String func, Object...args) | |||||
| { | |||||
| StringBuilder sb = new StringBuilder(); | |||||
| for(int i = 0; i < args.length; i++) | |||||
| { | |||||
| sb.append("'").append(args[i].toString()).append("'"); | |||||
| if(i < args.length - 1) | |||||
| sb.append(", "); | |||||
| } | |||||
| final String arg = sb.toString(); | |||||
| RunOnUIThread(new Runnable() { | |||||
| @Override | |||||
| public void run() { | |||||
| Log.e(ID_TAG, String.format("调用js函数: 函数(%s), 参数(%s)", func, arg)); | |||||
| String script = "javascript:typeof(" + func + ") == 'function' && " + func + "(" + arg + ");"; | |||||
| Log.e(ID_TAG, script); | |||||
| m_webView.loadUrl(script, null); | |||||
| } | |||||
| }); | |||||
| } | |||||
| } | |||||
| @@ -1,25 +0,0 @@ | |||||
| package com.nsgk.ruralWeb; | |||||
| public final class LocationInfo | |||||
| { | |||||
| public final String provider; | |||||
| public final double longitude; | |||||
| public final double latitude; | |||||
| public LocationInfo(String provider, double longitude, double latitude) | |||||
| { | |||||
| this.provider = provider; | |||||
| this.longitude = longitude; | |||||
| this.latitude = latitude; | |||||
| } | |||||
| @Override | |||||
| public String toString() | |||||
| { | |||||
| return "LocationInfo{" + | |||||
| "provider='" + provider + '\'' + | |||||
| ", latitude=" + latitude + | |||||
| ", longitude=" + longitude + | |||||
| '}'; | |||||
| } | |||||
| } | |||||
| @@ -1,37 +0,0 @@ | |||||
| package com.nsgk.ruralWeb; | |||||
| import android.content.Context; | |||||
| import android.content.SharedPreferences; | |||||
| import android.preference.PreferenceManager; | |||||
| public final class Preference | |||||
| { | |||||
| public static final String LAST_ACCESS_URL = "last_access_url"; | |||||
| private final Context context; | |||||
| public Preference(Context context) | |||||
| { | |||||
| this.context = context; | |||||
| } | |||||
| private SharedPreferences Read() | |||||
| { | |||||
| return PreferenceManager.getDefaultSharedPreferences(context); | |||||
| } | |||||
| private SharedPreferences.Editor Write() | |||||
| { | |||||
| return PreferenceManager.getDefaultSharedPreferences(context).edit(); | |||||
| } | |||||
| public String GetString(String name, String...def) | |||||
| { | |||||
| return Read().getString(name, null != def && def.length > 0 ? def[0] : null); | |||||
| } | |||||
| public void SetString(String name, String val) | |||||
| { | |||||
| Write().putString(name, val).commit(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,27 @@ | |||||
| package com.nsgk.ruralWeb; | |||||
| import android.os.Bundle; | |||||
| import androidx.appcompat.app.AppCompatActivity; | |||||
| import com.nsgk.ruralWeb.ui.SettingsFragment; | |||||
| public class SettingsActivity extends AppCompatActivity | |||||
| { | |||||
| private static final String ID_TAG = SettingsActivity.class.getName(); | |||||
| @Override | |||||
| protected void onCreate(Bundle savedInstanceState) | |||||
| { | |||||
| super.onCreate(savedInstanceState); | |||||
| setTitle(R.string.settings_name); | |||||
| getSupportFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit(); | |||||
| } | |||||
| @Override | |||||
| protected void onDestroy() { | |||||
| super.onDestroy(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,22 @@ | |||||
| package com.nsgk.ruralWeb.enums; | |||||
| public final class NSEnums | |||||
| { | |||||
| public final class LocationScheme | |||||
| { | |||||
| public static final String SYSTEM = "system"; | |||||
| public static final String GAODE = "gaode"; | |||||
| public static final String REALTIME = "realtime"; | |||||
| private LocationScheme() {} | |||||
| } | |||||
| public final class LocationProvider | |||||
| { | |||||
| public static final String AUTO = "auto"; | |||||
| private LocationProvider() {} | |||||
| } | |||||
| private NSEnums() {} | |||||
| } | |||||
| @@ -0,0 +1,57 @@ | |||||
| package com.nsgk.ruralWeb.sys; | |||||
| import android.location.LocationManager; | |||||
| import com.nsgk.ruralWeb.BuildConfig; | |||||
| import com.nsgk.ruralWeb.enums.NSEnums; | |||||
| public final class NSConstants | |||||
| { | |||||
| /** | |||||
| * App首页链接地址 | |||||
| * 可以在 /gradle.properties 里配置 appHomeUrl=链接地址, 不要携带双引号 | |||||
| * 也可以在命令行添加 -PappHomeUrl="链接地址", 双引号可携带也可不携带 | |||||
| */ | |||||
| public static String AppHomeUrl() | |||||
| { | |||||
| return BuildConfig.APP_HOME_URL; | |||||
| } | |||||
| /** | |||||
| * App启动页版权文本 | |||||
| * 可以在 /gradle.properties 里配置 appCopyright=文本, 不要携带双引号 | |||||
| * 也可以在命令行添加 -PappCopyright="文本", 双引号可携带也可不携带 | |||||
| */ | |||||
| public static String AppCopyright() | |||||
| { | |||||
| return BuildConfig.APP_COMPYRIGHT; | |||||
| } | |||||
| /** | |||||
| * App启动页厂商文本 | |||||
| * 可以在 /gradle.properties 里配置 appVendor=文本, 不要携带双引号 | |||||
| * 也可以在命令行添加 -PappVendor="文本", 双引号可携带也可不携带 | |||||
| */ | |||||
| public static String AppVendor() | |||||
| { | |||||
| return BuildConfig.APP_VENDOR; | |||||
| } | |||||
| public static String AppIcon() | |||||
| { | |||||
| return BuildConfig.APP_ICON; | |||||
| } | |||||
| // 偏好默认值 | |||||
| public static final String DEFAULT_LOCATION_SCHEME = NSEnums.LocationScheme.REALTIME; | |||||
| public static final int DEFAULT_LOCATION_GAODE_INTERVAL = 1000; | |||||
| public static final int DEFAULT_LOCATION_GAODE_READ_COUNT = 1; | |||||
| public static final String DEFAULT_LOCATION_PROVIDER = LocationManager.GPS_PROVIDER; | |||||
| public static final int DEFAULT_LOCATION_REALTIME_INTERVAL = 1000; | |||||
| public static final int DEFAULT_LOCATION_REALTIME_DISTANCE = 1; | |||||
| public static final int DEFAULT_LOCATION_REALTIME_READ_COUNT = 1; | |||||
| public static final boolean DEFAULT_OPEN_LAST_URL = false; | |||||
| public static final int DEFAULT_FONT_SCALE = 100; | |||||
| private NSConstants() {} | |||||
| } | |||||
| @@ -0,0 +1,78 @@ | |||||
| package com.nsgk.ruralWeb.sys; | |||||
| import android.content.Context; | |||||
| import android.content.SharedPreferences; | |||||
| import android.preference.PreferenceManager; | |||||
| import com.nsgk.ruralWeb.utils.NSStr; | |||||
| public final class NSPreference | |||||
| { | |||||
| public static final String LOCATION_SCHEME = "location_scheme"; | |||||
| public static final String LOCATION_GAODE_INTERVAL = "location_gaode_interval"; | |||||
| public static final String LOCATION_GAODE_READ_COUNT = "location_gaode_read_count"; | |||||
| public static final String LOCATION_PROVIDER = "location_provider"; | |||||
| public static final String LOCATION_REALTIME_INTERVAL = "location_realtime_interval"; | |||||
| public static final String LOCATION_REALTIME_DISTANCE = "location_realtime_distance"; | |||||
| public static final String LOCATION_REALTIME_READ_COUNT = "location_realtime_read_count"; | |||||
| public static final String OPEN_LAST_URL = "open_last_url"; | |||||
| public static final String LAST_ACCESS_URL = "last_access_url"; | |||||
| public static final String COOKIES = "cookies"; | |||||
| public static final String FONT_SCALE = "font_scale"; | |||||
| public static final String RESET_SETTINGS = "RESET_SETTINGS"; | |||||
| public static final String VERSION = "VERSION"; | |||||
| private final Context context; | |||||
| public NSPreference(Context context) | |||||
| { | |||||
| this.context = context; | |||||
| } | |||||
| public SharedPreferences Read() | |||||
| { | |||||
| return PreferenceManager.getDefaultSharedPreferences(context); | |||||
| } | |||||
| public SharedPreferences.Editor Write() | |||||
| { | |||||
| return PreferenceManager.getDefaultSharedPreferences(context).edit(); | |||||
| } | |||||
| public String GetString(String name, String... def) | |||||
| { | |||||
| return Read().getString(name, null != def && def.length > 0 ? def[0] : null); | |||||
| } | |||||
| public boolean GetBool(String name, boolean... def) | |||||
| { | |||||
| return Read().getBoolean(name, null != def && def.length > 0 ? def[0] : false); | |||||
| } | |||||
| public void Remove(String name) | |||||
| { | |||||
| Write().remove(name).commit(); | |||||
| } | |||||
| public void SetString(String name, String val) | |||||
| { | |||||
| Write().putString(name, val).commit(); | |||||
| } | |||||
| public void SetInt(String name, int val) | |||||
| { | |||||
| Write().putInt(name, val).commit(); | |||||
| } | |||||
| public int GetInt(String name, int... def) | |||||
| { | |||||
| return Read().getInt(name, null != def && def.length > 0 ? def[0] : 0); | |||||
| } | |||||
| public int GetIntFromString(String name, int defVal) | |||||
| { | |||||
| String str = Read().getString(name, ""); | |||||
| return NSStr.parseInt_s(str, defVal); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,309 @@ | |||||
| package com.nsgk.ruralWeb.ui; | |||||
| import android.content.Context; | |||||
| import android.content.DialogInterface; | |||||
| import android.content.SharedPreferences; | |||||
| import android.os.Bundle; | |||||
| import android.text.Html; | |||||
| import android.widget.Toast; | |||||
| import androidx.appcompat.app.AlertDialog; | |||||
| import androidx.preference.Preference; | |||||
| import androidx.preference.PreferenceFragmentCompat; | |||||
| import androidx.preference.PreferenceManager; | |||||
| import androidx.preference.SeekBarPreference; | |||||
| import com.nsgk.ruralWeb.BuildConfig; | |||||
| import com.nsgk.ruralWeb.R; | |||||
| import com.nsgk.ruralWeb.sys.NSConstants; | |||||
| import com.nsgk.ruralWeb.sys.NSPreference; | |||||
| import com.nsgk.ruralWeb.utils.NSContextUtils; | |||||
| import com.nsgk.ruralWeb.utils.NSMisc; | |||||
| import cn.hutool.core.util.NumberUtil; | |||||
| import cn.hutool.core.util.StrUtil; | |||||
| public class SettingsFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener | |||||
| { | |||||
| private static final String ID_TAG = SettingsFragment.class.getName(); | |||||
| @Override | |||||
| public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { | |||||
| addPreferencesFromResource(R.xml.settings_preference); | |||||
| Preference preference; | |||||
| final Context context = getContext(); | |||||
| preference = findPreference(NSPreference.LOCATION_SCHEME); | |||||
| preference.setDefaultValue(NSConstants.DEFAULT_LOCATION_SCHEME); | |||||
| preference.setOnPreferenceChangeListener(this); | |||||
| preference = findPreference(NSPreference.LOCATION_GAODE_INTERVAL); | |||||
| preference.setDefaultValue("" + NSConstants.DEFAULT_LOCATION_GAODE_INTERVAL); | |||||
| preference.setOnPreferenceChangeListener(this); | |||||
| preference = findPreference(NSPreference.LOCATION_GAODE_READ_COUNT); | |||||
| preference.setDefaultValue("" + NSConstants.DEFAULT_LOCATION_GAODE_READ_COUNT); | |||||
| preference.setOnPreferenceChangeListener(this); | |||||
| preference = findPreference(NSPreference.OPEN_LAST_URL); | |||||
| preference.setDefaultValue(NSConstants.DEFAULT_OPEN_LAST_URL); | |||||
| preference.setOnPreferenceChangeListener(this); | |||||
| preference = findPreference(NSPreference.LOCATION_PROVIDER); | |||||
| preference.setDefaultValue(NSConstants.DEFAULT_LOCATION_PROVIDER); | |||||
| preference.setOnPreferenceChangeListener(this); | |||||
| preference = findPreference(NSPreference.LOCATION_REALTIME_INTERVAL); | |||||
| preference.setDefaultValue("" + NSConstants.DEFAULT_LOCATION_REALTIME_INTERVAL); | |||||
| preference.setOnPreferenceChangeListener(this); | |||||
| preference = findPreference(NSPreference.LOCATION_REALTIME_DISTANCE); | |||||
| preference.setDefaultValue("" + NSConstants.DEFAULT_LOCATION_REALTIME_DISTANCE); | |||||
| preference.setOnPreferenceChangeListener(this); | |||||
| preference = findPreference(NSPreference.LOCATION_REALTIME_READ_COUNT); | |||||
| preference.setDefaultValue("" + NSConstants.DEFAULT_LOCATION_REALTIME_READ_COUNT); | |||||
| preference.setOnPreferenceChangeListener(this); | |||||
| preference = findPreference(NSPreference.FONT_SCALE); | |||||
| preference.setDefaultValue(NSConstants.DEFAULT_FONT_SCALE); | |||||
| preference.setOnPreferenceChangeListener(this); | |||||
| preference = findPreference(NSPreference.RESET_SETTINGS); | |||||
| preference.setOnPreferenceClickListener(this); | |||||
| preference = findPreference(NSPreference.VERSION); | |||||
| preference.setOnPreferenceClickListener(this); | |||||
| } | |||||
| private boolean CheckValueIsNumber(Object newValue, Integer min) | |||||
| { | |||||
| if(null != newValue) | |||||
| { | |||||
| String str = newValue.toString(); | |||||
| if(StrUtil.isNotBlank(str)) | |||||
| { | |||||
| if(!NumberUtil.isInteger(str)) | |||||
| { | |||||
| Toast.makeText(getContext(), "请输入数字", Toast.LENGTH_SHORT).show(); | |||||
| return false; | |||||
| } | |||||
| int i = Integer.parseInt(str); | |||||
| if(null != min) | |||||
| { | |||||
| if(i < min) | |||||
| { | |||||
| Toast.makeText(getContext(), "必须大于等于" + min, Toast.LENGTH_SHORT).show(); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| return true; | |||||
| } | |||||
| @Override | |||||
| public boolean onPreferenceChange(Preference preference, Object newValue) { | |||||
| String key = preference.getKey(); | |||||
| switch(key) | |||||
| { | |||||
| case NSPreference.LOCATION_GAODE_INTERVAL: | |||||
| if(!CheckValueIsNumber(newValue, 1000)) | |||||
| return false; | |||||
| break; | |||||
| case NSPreference.LOCATION_GAODE_READ_COUNT: | |||||
| if(!CheckValueIsNumber(newValue, 1)) | |||||
| return false; | |||||
| break; | |||||
| case NSPreference.LOCATION_REALTIME_INTERVAL: | |||||
| if(!CheckValueIsNumber(newValue, 1000)) | |||||
| return false; | |||||
| break; | |||||
| case NSPreference.LOCATION_REALTIME_DISTANCE: | |||||
| if(!CheckValueIsNumber(newValue, 0)) | |||||
| return false; | |||||
| break; | |||||
| case NSPreference.LOCATION_REALTIME_READ_COUNT: | |||||
| if(!CheckValueIsNumber(newValue, 1)) | |||||
| return false; | |||||
| break; | |||||
| case NSPreference.FONT_SCALE: { | |||||
| int i = (int)newValue; | |||||
| int newi = Math.round((float)i / 10.0f) * 10; | |||||
| if(i < 50) | |||||
| i = 50; | |||||
| if(i != newi) | |||||
| { | |||||
| getView().post(() -> { | |||||
| ((SeekBarPreference)preference).setValue(newi); | |||||
| preference.callChangeListener(newi); | |||||
| }); | |||||
| return false; | |||||
| } | |||||
| break; | |||||
| } | |||||
| } | |||||
| SetSummary(key, newValue); | |||||
| return true; | |||||
| } | |||||
| @Override | |||||
| public boolean onPreferenceClick(final Preference preference) { | |||||
| String key = preference.getKey(); | |||||
| final Context context = getContext(); | |||||
| switch(key) | |||||
| { | |||||
| case NSPreference.RESET_SETTINGS: | |||||
| OpenQueryDialog("警告", "确定要重置到默认设置?", (dialog, which) -> { | |||||
| ResetSettings(); | |||||
| SetSummary(null, null); | |||||
| Toast.makeText(context, "设置已重置", Toast.LENGTH_LONG).show(); | |||||
| }); | |||||
| break; | |||||
| case NSPreference.VERSION: | |||||
| OpenAbout(); | |||||
| break; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| private void ResetSettings() | |||||
| { | |||||
| NSPreference preference = new NSPreference(getContext()); | |||||
| preference.Write() | |||||
| .putString(NSPreference.LOCATION_SCHEME, NSConstants.DEFAULT_LOCATION_SCHEME) | |||||
| .putString(NSPreference.LOCATION_GAODE_INTERVAL, "" + NSConstants.DEFAULT_LOCATION_GAODE_INTERVAL) | |||||
| .putString(NSPreference.LOCATION_GAODE_READ_COUNT, "" + NSConstants.DEFAULT_LOCATION_GAODE_READ_COUNT) | |||||
| .putBoolean(NSPreference.OPEN_LAST_URL, NSConstants.DEFAULT_OPEN_LAST_URL) | |||||
| .putString(NSPreference.LOCATION_PROVIDER, NSConstants.DEFAULT_LOCATION_PROVIDER) | |||||
| .putString(NSPreference.LOCATION_REALTIME_INTERVAL, "" + NSConstants.DEFAULT_LOCATION_REALTIME_INTERVAL) | |||||
| .putString(NSPreference.LOCATION_REALTIME_DISTANCE, "" + NSConstants.DEFAULT_LOCATION_REALTIME_DISTANCE) | |||||
| .putString(NSPreference.LOCATION_REALTIME_READ_COUNT, "" + NSConstants.DEFAULT_LOCATION_REALTIME_READ_COUNT) | |||||
| .putInt(NSPreference.FONT_SCALE, NSConstants.DEFAULT_FONT_SCALE) | |||||
| .commit() | |||||
| ; | |||||
| } | |||||
| private void OpenQueryDialog(String title, String message, DialogInterface.OnClickListener listener) | |||||
| { | |||||
| AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); | |||||
| builder.setTitle(title); | |||||
| builder.setMessage(message); | |||||
| builder.setIcon(R.drawable.no_words); | |||||
| builder.setPositiveButton("确定", listener); | |||||
| builder.setNegativeButton("取消", null); | |||||
| AlertDialog dialog = builder.create(); | |||||
| dialog.show(); | |||||
| } | |||||
| private void OpenAbout() | |||||
| { | |||||
| Context context = getContext(); | |||||
| AlertDialog.Builder builder = new AlertDialog.Builder(context); | |||||
| String msg = "<br/>" + NSContextUtils.tr(context, R.string.company) + "<br/><br/>" + NSContextUtils.tr(context, R.string.copyright); | |||||
| msg = "<div style='text-align:center;'>" + msg + "</div>"; | |||||
| builder.setTitle(R.string.app_name2); | |||||
| builder.setMessage(Html.fromHtml(msg, Html.FROM_HTML_MODE_LEGACY, null, null)); | |||||
| int icon = context.getResources().getIdentifier("ic_launcher_" + NSConstants.AppIcon()/* + "_round"*/, "mipmap", context.getApplicationContext().getPackageName()); | |||||
| builder.setIcon(icon); | |||||
| AlertDialog dialog = builder.create(); | |||||
| dialog.show(); | |||||
| } | |||||
| @Override | |||||
| public void onResume() { | |||||
| super.onResume(); | |||||
| SetSummary(null, null); | |||||
| } | |||||
| public void SetSummary(String key, Object newValue) | |||||
| { | |||||
| Context context = getContext(); | |||||
| Preference preference; | |||||
| String summary; | |||||
| String value; | |||||
| boolean b; | |||||
| int i; | |||||
| SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); | |||||
| if(key == null || NSPreference.LOCATION_SCHEME.equals(key)) | |||||
| { | |||||
| preference = findPreference(NSPreference.LOCATION_SCHEME); | |||||
| value = newValue != null ? newValue.toString() : sharedPreferences.getString(NSPreference.LOCATION_SCHEME, NSConstants.DEFAULT_LOCATION_SCHEME); | |||||
| summary = NSContextUtils.GetListName(context, value, R.array.location_scheme_values, R.array.location_scheme_labels); | |||||
| preference.setSummary(summary); | |||||
| } | |||||
| if(key == null || NSPreference.LOCATION_GAODE_INTERVAL.equals(key)) | |||||
| { | |||||
| preference = findPreference(NSPreference.LOCATION_GAODE_INTERVAL); | |||||
| value = newValue != null && StrUtil.isNotBlank(newValue.toString()) ? newValue.toString() : sharedPreferences.getString(NSPreference.LOCATION_GAODE_INTERVAL, "" + NSConstants.DEFAULT_LOCATION_GAODE_INTERVAL); | |||||
| summary = value + "毫秒"; | |||||
| preference.setSummary(summary); | |||||
| } | |||||
| if(key == null || NSPreference.LOCATION_GAODE_READ_COUNT.equals(key)) | |||||
| { | |||||
| preference = findPreference(NSPreference.LOCATION_GAODE_READ_COUNT); | |||||
| value = newValue != null && StrUtil.isNotBlank(newValue.toString()) ? newValue.toString() : sharedPreferences.getString(NSPreference.LOCATION_GAODE_READ_COUNT, "" + NSConstants.DEFAULT_LOCATION_GAODE_READ_COUNT); | |||||
| summary = value + "次"; | |||||
| preference.setSummary(summary); | |||||
| } | |||||
| if(key == null || NSPreference.OPEN_LAST_URL.equals(key)) | |||||
| { | |||||
| preference = findPreference(NSPreference.OPEN_LAST_URL); | |||||
| b = newValue != null ? (Boolean)newValue : sharedPreferences.getBoolean(NSPreference.OPEN_LAST_URL, NSConstants.DEFAULT_OPEN_LAST_URL); | |||||
| summary = b ? "打开最近页面" : "打开默认页面"; | |||||
| preference.setSummary(summary); | |||||
| } | |||||
| if(key == null || NSPreference.LOCATION_PROVIDER.equals(key)) | |||||
| { | |||||
| preference = findPreference(NSPreference.LOCATION_PROVIDER); | |||||
| value = newValue != null ? newValue.toString() : sharedPreferences.getString(NSPreference.LOCATION_PROVIDER, NSConstants.DEFAULT_LOCATION_PROVIDER); | |||||
| summary = NSContextUtils.GetListName(context, value, R.array.location_provider_values, R.array.location_provider_labels); | |||||
| preference.setSummary(summary); | |||||
| } | |||||
| if(key == null || NSPreference.LOCATION_REALTIME_INTERVAL.equals(key)) | |||||
| { | |||||
| preference = findPreference(NSPreference.LOCATION_REALTIME_INTERVAL); | |||||
| value = newValue != null && StrUtil.isNotBlank(newValue.toString()) ? newValue.toString() : sharedPreferences.getString(NSPreference.LOCATION_REALTIME_INTERVAL, "" + NSConstants.DEFAULT_LOCATION_REALTIME_INTERVAL); | |||||
| summary = value + "毫秒"; | |||||
| preference.setSummary(summary); | |||||
| } | |||||
| if(key == null || NSPreference.LOCATION_REALTIME_DISTANCE.equals(key)) | |||||
| { | |||||
| preference = findPreference(NSPreference.LOCATION_REALTIME_DISTANCE); | |||||
| value = newValue != null && StrUtil.isNotBlank(newValue.toString()) ? newValue.toString() : sharedPreferences.getString(NSPreference.LOCATION_REALTIME_DISTANCE, "" + NSConstants.DEFAULT_LOCATION_REALTIME_DISTANCE); | |||||
| summary = value + "米"; | |||||
| preference.setSummary(summary); | |||||
| } | |||||
| if(key == null || NSPreference.LOCATION_REALTIME_READ_COUNT.equals(key)) | |||||
| { | |||||
| preference = findPreference(NSPreference.LOCATION_REALTIME_READ_COUNT); | |||||
| value = newValue != null && StrUtil.isNotBlank(newValue.toString()) ? newValue.toString() : sharedPreferences.getString(NSPreference.LOCATION_REALTIME_READ_COUNT, "" + NSConstants.DEFAULT_LOCATION_REALTIME_READ_COUNT); | |||||
| summary = value + "次"; | |||||
| preference.setSummary(summary); | |||||
| } | |||||
| if(key == null || NSPreference.FONT_SCALE.equals(key)) | |||||
| { | |||||
| preference = findPreference(NSPreference.FONT_SCALE); | |||||
| i = newValue != null ? (int)newValue : sharedPreferences.getInt(NSPreference.FONT_SCALE, NSConstants.DEFAULT_FONT_SCALE); | |||||
| if(i == 0) | |||||
| i = 100; | |||||
| summary = i + "%"; | |||||
| preference.setSummary(summary); | |||||
| } | |||||
| findPreference(NSPreference.VERSION).setSummary(NSContextUtils.GetAppVersion(getContext())); | |||||
| } | |||||
| } | |||||
| @@ -1,16 +0,0 @@ | |||||
| package com.nsgk.ruralWeb.utils; | |||||
| import android.app.Activity; | |||||
| import android.content.Intent; | |||||
| import android.provider.Settings; | |||||
| public final class ContextUtils | |||||
| { | |||||
| public static void RequestLocationPermission(Activity context, int requestCode) | |||||
| { | |||||
| Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); | |||||
| context.startActivityForResult(intent, requestCode); | |||||
| } | |||||
| private ContextUtils() {} | |||||
| } | |||||
| @@ -0,0 +1,79 @@ | |||||
| package com.nsgk.ruralWeb.utils; | |||||
| import android.app.Activity; | |||||
| import android.content.Context; | |||||
| import android.content.Intent; | |||||
| import android.content.pm.ApplicationInfo; | |||||
| import android.content.pm.PackageInfo; | |||||
| import android.content.pm.PackageManager; | |||||
| import android.content.res.Resources; | |||||
| import android.net.Uri; | |||||
| import android.provider.Settings; | |||||
| public final class NSContextUtils | |||||
| { | |||||
| public static void RequestLocationPermission(Activity context, int requestCode) | |||||
| { | |||||
| Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); | |||||
| context.startActivityForResult(intent, requestCode); | |||||
| } | |||||
| public static void OpenAppSetting(Context context) | |||||
| { | |||||
| Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); | |||||
| Uri uri = Uri.fromParts("package", context.getApplicationContext().getPackageName(), null); | |||||
| intent.setData(uri); | |||||
| context.startActivity(intent); | |||||
| } | |||||
| public static String GetAppVersion(Context context) | |||||
| { | |||||
| String version = "UNKNOWN"; | |||||
| try | |||||
| { | |||||
| PackageManager manager = context.getPackageManager(); | |||||
| PackageInfo info = manager.getPackageInfo(context.getApplicationContext().getPackageName(), 0); | |||||
| version = info.versionName; | |||||
| } | |||||
| catch (Exception e) | |||||
| { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return version; | |||||
| } | |||||
| public static boolean BuildIsDebug(Context context) | |||||
| { | |||||
| try | |||||
| { | |||||
| ApplicationInfo info = context.getApplicationInfo(); | |||||
| return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; | |||||
| } | |||||
| catch (Exception e) | |||||
| { | |||||
| e.printStackTrace(); | |||||
| return false; // default is release | |||||
| } | |||||
| } | |||||
| public static String GetListName(Context context, String value, int keyResource, int nameResource, String... def) | |||||
| { | |||||
| Resources resources = context.getResources(); | |||||
| String[] keys = resources.getStringArray(keyResource); | |||||
| String[] names = resources.getStringArray(nameResource); | |||||
| for(int i = 0; i < keys.length; i++) | |||||
| { | |||||
| if(keys[i].equals(value)) | |||||
| return names[i]; | |||||
| } | |||||
| return null != def && def.length > 0 ? def[0] : null; | |||||
| } | |||||
| public static String tr(Context context, int id, Object...args) | |||||
| { | |||||
| return context.getResources().getString(id, args); | |||||
| } | |||||
| private NSContextUtils() {} | |||||
| } | |||||
| @@ -0,0 +1,19 @@ | |||||
| package com.nsgk.ruralWeb.utils; | |||||
| public final class NSMisc | |||||
| { | |||||
| public static void noexcept(Runnable runnable) | |||||
| { | |||||
| if(null != runnable) | |||||
| { | |||||
| try | |||||
| { | |||||
| runnable.run(); | |||||
| } | |||||
| catch(Throwable e) | |||||
| { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,38 @@ | |||||
| package com.nsgk.ruralWeb.utils; | |||||
| import java.net.URL; | |||||
| import cn.hutool.core.util.StrUtil; | |||||
| import cn.hutool.core.util.URLUtil; | |||||
| public final class NSStr | |||||
| { | |||||
| public static String GetUrlPart(String str) | |||||
| { | |||||
| URL url = URLUtil.url(str); | |||||
| String protocol = url.getProtocol(); | |||||
| String host = url.getHost(); | |||||
| int port = url.getPort(); | |||||
| StringBuilder buf = new StringBuilder(); | |||||
| buf.append(protocol).append("://").append(host); | |||||
| if(port >= 0) | |||||
| buf.append(':').append(port); | |||||
| return buf.toString(); | |||||
| } | |||||
| public static int parseInt_s(String str, int...def) | |||||
| { | |||||
| int res = null != def && def.length > 0 ? def[0] : 0; | |||||
| if(StrUtil.isBlank(str)) | |||||
| return res; | |||||
| try | |||||
| { | |||||
| return Integer.parseInt(str); | |||||
| } | |||||
| catch(Exception e) | |||||
| { | |||||
| e.printStackTrace(); | |||||
| return res; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,26 @@ | |||||
| <?xml version="1.0" encoding="utf-8"?> | |||||
| <resources> | |||||
| <string-array name="location_scheme_values"> | |||||
| <item>system</item> | |||||
| <item>gaode</item> | |||||
| <item>realtime</item> | |||||
| </string-array> | |||||
| <string-array name="location_scheme_labels"> | |||||
| <item>系统</item> | |||||
| <item>高德</item> | |||||
| <item>系统实时</item> | |||||
| </string-array> | |||||
| <string-array name="location_provider_values"> | |||||
| <item>gps</item> | |||||
| <item>network</item> | |||||
| </string-array> | |||||
| <string-array name="location_provider_labels"> | |||||
| <item>GPS</item> | |||||
| <item>网络</item> | |||||
| </string-array> | |||||
| </resources> | |||||
| @@ -5,4 +5,7 @@ | |||||
| <string name="dummy_content">DUMMY\nCONTENT</string> | <string name="dummy_content">DUMMY\nCONTENT</string> | ||||
| <string name="copyright">Copyright © 2024 ZNRX All Rights Reserved.</string> | <string name="copyright">Copyright © 2024 ZNRX All Rights Reserved.</string> | ||||
| <string name="company">中农融信(北京)科技股份有限公司</string> | <string name="company">中农融信(北京)科技股份有限公司</string> | ||||
| <string name="settings_name">设置</string> | |||||
| </resources> | </resources> | ||||
| @@ -0,0 +1,125 @@ | |||||
| <?xml version="1.0" encoding="utf-8"?> | |||||
| <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" | |||||
| xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
| android:title="设置"> | |||||
| <PreferenceCategory | |||||
| android:key="base" | |||||
| android:title="基础" | |||||
| > | |||||
| <SwitchPreference | |||||
| android:title="进入App打开最近的页面" | |||||
| android:key="open_last_url" | |||||
| android:persistent="true" | |||||
| android:defaultValue="false" | |||||
| android:summary="打开最近的页面" | |||||
| /> | |||||
| <SeekBarPreference | |||||
| android:title="字体缩放倍数(%)" | |||||
| android:key="font_scale" | |||||
| android:persistent="true" | |||||
| android:defaultValue="100" | |||||
| app:min="50" | |||||
| android:max="300" | |||||
| app:showSeekBarValue="true" | |||||
| android:summary="字体缩放倍数" | |||||
| /> | |||||
| <ListPreference | |||||
| android:dialogTitle="定位方式" | |||||
| android:key="location_scheme" | |||||
| android:entries="@array/location_scheme_labels" | |||||
| android:entryValues="@array/location_scheme_values" | |||||
| android:summary="定位方式" | |||||
| android:persistent="true" | |||||
| android:title="选择定位方式" | |||||
| android:defaultValue="realtime" | |||||
| /> | |||||
| </PreferenceCategory> | |||||
| <PreferenceCategory | |||||
| android:key="location_gaode" | |||||
| android:title="高德定位" | |||||
| > | |||||
| <EditTextPreference | |||||
| android:dialogTitle="定位间隔(毫秒)" | |||||
| android:key="location_gaode_interval" | |||||
| android:summary="定位间隔" | |||||
| android:persistent="true" | |||||
| android:title="设置定位间隔" | |||||
| android:inputType="number" | |||||
| android:defaultValue="1000" | |||||
| /> | |||||
| <EditTextPreference | |||||
| android:dialogTitle="每次定位次数" | |||||
| android:key="location_gaode_read_count" | |||||
| android:summary="定位次数" | |||||
| android:persistent="true" | |||||
| android:title="设置定位次数" | |||||
| android:inputType="number" | |||||
| android:defaultValue="1" | |||||
| /> | |||||
| </PreferenceCategory> | |||||
| <PreferenceCategory | |||||
| android:key="location_system" | |||||
| android:title="系统定位" | |||||
| > | |||||
| <ListPreference | |||||
| android:dialogTitle="定位提供器" | |||||
| android:key="location_provider" | |||||
| android:entries="@array/location_provider_labels" | |||||
| android:entryValues="@array/location_provider_values" | |||||
| android:summary="定位提供器" | |||||
| android:persistent="true" | |||||
| android:title="选择定位提供器" | |||||
| android:defaultValue="gps" | |||||
| /> | |||||
| <EditTextPreference | |||||
| android:dialogTitle="定位间隔(毫秒)" | |||||
| android:key="location_realtime_interval" | |||||
| android:summary="定位间隔" | |||||
| android:persistent="true" | |||||
| android:title="设置定位间隔" | |||||
| android:inputType="number" | |||||
| android:defaultValue="1000" | |||||
| /> | |||||
| <EditTextPreference | |||||
| android:dialogTitle="定位距离(米)" | |||||
| android:key="location_realtime_distance" | |||||
| android:summary="定位距离" | |||||
| android:persistent="true" | |||||
| android:title="设置定位距离" | |||||
| android:inputType="number" | |||||
| android:defaultValue="1" | |||||
| /> | |||||
| <EditTextPreference | |||||
| android:dialogTitle="每次定位次数" | |||||
| android:key="location_realtime_read_count" | |||||
| android:summary="定位次数" | |||||
| android:persistent="true" | |||||
| android:title="设置定位次数" | |||||
| android:inputType="number" | |||||
| android:defaultValue="1" | |||||
| /> | |||||
| </PreferenceCategory> | |||||
| <PreferenceCategory | |||||
| android:key="other" | |||||
| android:title="其他" | |||||
| > | |||||
| <Preference | |||||
| android:key="RESET_SETTINGS" | |||||
| android:summary="重置所有设置为默认值" | |||||
| android:title="重置设置" | |||||
| android:persistent="false"> | |||||
| </Preference> | |||||
| <Preference | |||||
| android:key="VERSION" | |||||
| android:title="版本" | |||||
| android:summary="" | |||||
| android:persistent="false"> | |||||
| </Preference> | |||||
| </PreferenceCategory> | |||||
| </PreferenceScreen> | |||||
| @@ -0,0 +1,17 @@ | |||||
| <shortcuts xmlns:tools="http://schemas.android.com/tools" | |||||
| xmlns:android="http://schemas.android.com/apk/res/android"> | |||||
| <shortcut | |||||
| android:shortcutId="shortcut_settings" | |||||
| android:enabled="true" | |||||
| android:icon="@drawable/no_words" | |||||
| android:shortcutShortLabel="@string/settings_name" | |||||
| tools:targetApi="n_mr1"> | |||||
| <intent | |||||
| android:action="android.intent.action.VIEW" | |||||
| android:targetPackage="com.nsgk.ruralWeb" | |||||
| android:targetClass="com.nsgk.ruralWeb.SettingsActivity" | |||||
| android:name="android.shortcut.conversation"/> | |||||
| </shortcut> | |||||
| </shortcuts> | |||||