Commit 15e43c96 by cuiliang.shi

A16代码备份

1 parent c3a599c4
Showing with 1637 additions and 0 deletions
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
</code_scheme>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="7">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="6">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
\ No newline at end of file
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.agenew.location_server.application"
minSdkVersion 26
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.amap.api:location:latest.integration'
}
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# 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 *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
No preview for this file type
No preview for this file type
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
\ No newline at end of file
package com.agenew.location_server.application;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.example.john.myapplication", appContext.getPackageName());
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.agenew.location_server.application">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<application
android:persistent="true"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data android:name="com.amap.api.v2.apikey" android:value="2e40c8d145f8a0d4f9bb1cc7590594e7">
</meta-data>
<activity android:name="com.agenew.location_server.application.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<!--<category android:name="android.intent.category.LAUNCHER" />-->
</intent-filter>
<!--<intent-filter>-->
<!--<action android:name="com.android.settings.action.EXTRA_SETTINGS" />-->
<!--</intent-filter>-->
<!--<meta-data android:name="com.android.settings.category"-->
<!--android:value="com.android.settings.category.ia.homepage" />-->
<!--<meta-data android:name="com.android.settings.icon"-->
<!--android:resource="@drawable/ic_sos" />-->
<!--<meta-data android:name="com.android.settings.title"-->
<!--android:resource="@string/app_name" />-->
</activity>
<service android:name="com.amap.api.location.APSService" />
<receiver android:name="com.agenew.location_server.application.LocationReceiver"
android:permission="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS">
<intent-filter>
<action android:name="com.bird.send_sos" />
<action android:name="com.bird.close_sos" />
</intent-filter>
</receiver>
<service android:name="com.agenew.location_server.application.BirdService">
</service>
<receiver android:name="com.agenew.location_server.application.AlarmReceiver"></receiver>
</application>
</manifest>
\ No newline at end of file
package com.agenew.location_server.application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("BirdService","receiver--"+System.currentTimeMillis());
Intent i=new Intent(context,BirdService.class);
context.startForegroundService(i);
}
}
package com.agenew.location_server.application;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.support.v4.content.SharedPreferencesCompat;
import java.util.Set;
public class DevicePreferences {
private static DevicePreferences sDevicePreferences;
private final SharedPreferences mShareferences;
private final SharedPreferences.Editor mEditor;
private DevicePreferences(Context context) {
mShareferences = context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
mEditor = mShareferences.edit();
}
public static synchronized DevicePreferences getInstance(Context context) {
if (null == sDevicePreferences) {
sDevicePreferences = new DevicePreferences(context.getApplicationContext());
}
return sDevicePreferences;
}
public void putInt(final String key, final int value) {
mEditor.putInt(key, value);
SharedPreferencesCompat.EditorCompat.getInstance().apply(mEditor);
}
public void putLong(final String key, final long value) {
mEditor.putLong(key, value);
SharedPreferencesCompat.EditorCompat.getInstance().apply(mEditor);
}
public void putString(final String key, final String value) {
mEditor.putString(key, value);
SharedPreferencesCompat.EditorCompat.getInstance().apply(mEditor);
}
public void putFloat(final String key, final float value) {
mEditor.putFloat(key, value);
SharedPreferencesCompat.EditorCompat.getInstance().apply(mEditor);
}
public void putBoolean(final String key, final boolean value) {
mEditor.putBoolean(key, value);
SharedPreferencesCompat.EditorCompat.getInstance().apply(mEditor);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void putStringSet(final String key, final Set<String> values) {
mEditor.putStringSet(key, values);
SharedPreferencesCompat.EditorCompat.getInstance().apply(mEditor);
}
public int getInt(final String key, final int defaultValue) {
return mShareferences.getInt(key, defaultValue);
}
public long getLong(final String key, final long defaultValue) {
return mShareferences.getLong(key, defaultValue);
}
public String getString(final String key, final String defaultValue) {
return mShareferences.getString(key, defaultValue);
}
public float getFloat(final String key, final float defaultValue) {
return mShareferences.getFloat(key, defaultValue);
}
public boolean getBoolean(final String key, final boolean defaultValue) {
return mShareferences.getBoolean(key, defaultValue);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public Set<String> getStringSet(final String key) {
return mShareferences.getStringSet(key, null);
}
}
package com.agenew.location_server.application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;
public class LocationReceiver extends BroadcastReceiver{
private String TAG = "qqh";
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "action:" + action);
if (action.equals("com.bird.send_sos")){
if (BirdService.status != 1){
Log.d("qqh","bird_sos_open");
Intent intentThree = new Intent(context, BirdService.class);
context.startForegroundService(intentThree);
BirdService.status = 1;
}
}else if (action.equals("com.bird.close_sos")){
Intent intentThree = new Intent(context, BirdService.class);
context.stopService(intentThree);
BirdService.status = -1;
}
}
}
package com.agenew.location_server.application;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.agenew.location_server.application.permission.MPermission;
import com.agenew.location_server.application.permission.annotation.OnMPermissionDenied;
import com.agenew.location_server.application.permission.annotation.OnMPermissionGranted;
import com.agenew.location_server.application.permission.annotation.OnMPermissionNeverAskAgain;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class MainActivity extends Activity implements View.OnClickListener {
private String TAG="BirdService";
private SharedPreferences sp;
private LocationReceiver locationRecevier;
private Context mContext;
private final static String DEFAULTPATH = "http://202.100.179.139:8088/api";
private final static long DEFAULTINTERVAL = 30;
private EditText url_et;
private EditText interval_et;
private Button btnCannel;
private Button btnSave;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.location_msg);
mContext = this;
String url = DevicePreferences.getInstance(mContext).getString("bird_location_upload_url", DEFAULTPATH);
Long interval = DevicePreferences.getInstance(mContext).getLong("bird_location_upload_interval",DEFAULTINTERVAL);
Log.d("qqh","interval"+interval);
url_et = findViewById(R.id.url_value);
interval_et =findViewById(R.id.interval_value);
url_et.setText(url);
interval_et.setText(String.valueOf(interval));
btnCannel = findViewById(R.id.bt_cancel);
btnSave = findViewById(R.id.bt_save);
btnCannel.setOnClickListener(this);
btnSave.setOnClickListener(this);
sp = getSharedPreferences("config", MODE_PRIVATE);
requestBasicPermission();
// locationRecevier = new LocationReceiver();
// IntentFilter filter = new IntentFilter();
// filter.addAction("com.bird.send_sos");
// filter.addAction("com.bird.close_sos");
// registerReceiver(locationRecevier, filter);
Log.d("qqh","main___start");
//sendBroadcast(new Intent("com.bird.send_sos"));
// Intent intentThree = new Intent(this, BirdService.class);
// startForegroundService(intentThree);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
}
return true;
}
@Override
public void onClick(View v) {
Log.d("qqh","click"+v.getId());
switch (v.getId()) {
case R.id.bt_cancel:
finish();
break;
case R.id.bt_save:
String url_temp =url_et.getText().toString().trim();
String interval_temp =interval_et.getText().toString();
if(url_temp == null || "".equals(url_temp)|| url_temp.isEmpty()){
Toast.makeText(this, getString(R.string.server_prompt), Toast.LENGTH_SHORT).show();
break;
}
if(interval_temp == null || "".equals(interval_temp)|| interval_temp.isEmpty()){
Toast.makeText(this, getString(R.string.interval_prompt), Toast.LENGTH_SHORT).show();
break;
}
Long t=Long.valueOf(interval_temp);
Log.d(TAG,"time---"+t);
DevicePreferences.getInstance(MainActivity.this).putString("bird_location_upload_url",url_temp );
DevicePreferences.getInstance(MainActivity.this).putLong("bird_location_upload_interval",t);
finish();
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// unregisterReceiver(locationRecevier);
}
private static final int BASIC_PERMISSION_REQUEST_CODE = 100;
private static final String[] BASIC_PERMISSIONS = new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.CAMERA,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.SEND_SMS
};
private void requestBasicPermission() {
MPermission.printMPermissionResult(true, this, BASIC_PERMISSIONS);
MPermission.with(MainActivity.this)
.setRequestCode(BASIC_PERMISSION_REQUEST_CODE)
.permissions(BASIC_PERMISSIONS)
.request();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
MPermission.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
}
@OnMPermissionGranted(BASIC_PERMISSION_REQUEST_CODE)
public void onBasicPermissionSuccess() {
// Toast.makeText(this, "success to get permission", Toast.LENGTH_SHORT).show();
}
@OnMPermissionDenied(BASIC_PERMISSION_REQUEST_CODE)
@OnMPermissionNeverAskAgain(BASIC_PERMISSION_REQUEST_CODE)
public void onBasicPermissionFailed() {
// Toast.makeText(this, "fail to get permission", Toast.LENGTH_SHORT).show();
}
}
package com.agenew.location_server.application.permission;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.app.Fragment;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
public class BaseMPermission {
private static final String TAG = "MPermission";
public enum MPermissionResultEnum {
GRANTED, DENIED, DENIED_NEVER_ASK_AGAIN
}
static boolean isOverMarshmallow() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
static Activity getActivity(Object object) {
if (object instanceof Fragment) {
return ((Fragment) object).getActivity();
} else if (object instanceof Activity) {
return (Activity) object;
}
return null;
}
/**
* 获取权限请求结果
*/
public static List<MPermissionResultEnum> getPermissionResult(Activity activity, String[] permissions) {
return findPermissionResult(activity, permissions);
}
public static List<MPermissionResultEnum> getPermissionResult(Fragment fragment, String[] permissions) {
return findPermissionResult(fragment.getActivity(), permissions);
}
@TargetApi(value = Build.VERSION_CODES.M)
private static List<MPermissionResultEnum> findPermissionResult(Activity activity, String... permissions) {
boolean overM = isOverMarshmallow();
List<MPermissionResultEnum> result = new ArrayList<>();
for (String p : permissions) {
if (overM) {
if (activity.checkSelfPermission(p) == PackageManager.PERMISSION_GRANTED) {
result.add(MPermissionResultEnum.GRANTED);
} else {
if (!activity.shouldShowRequestPermissionRationale(p)) {
result.add(MPermissionResultEnum.DENIED_NEVER_ASK_AGAIN);
} else {
result.add(MPermissionResultEnum.DENIED);
}
}
} else {
result.add(MPermissionResultEnum.GRANTED);
}
}
return result;
}
/**
* 获取所有被未被授权的权限
*/
public static List<String> getDeniedPermissions(Activity activity, String[] permissions) {
return findDeniedPermissions(activity, permissions);
}
public static List<String> getDeniedPermissions(Fragment fragment, String[] permissions) {
return findDeniedPermissions(fragment.getActivity(), permissions);
}
@TargetApi(value = Build.VERSION_CODES.M)
static List<String> findDeniedPermissions(Activity activity, String... permissions) {
if (!isOverMarshmallow()) {
return null;
}
List<String> denyPermissions = new ArrayList<>();
for (String value : permissions) {
if (activity.checkSelfPermission(value) != PackageManager.PERMISSION_GRANTED) {
denyPermissions.add(value);
}
}
return denyPermissions;
}
/**
* 获取被拒绝且勾选不再询问的权限
* 请在请求权限结果回调中使用,因为从未请求过的权限也会被认为是该结果集
*/
public static List<String> getNeverAskAgainPermissions(Activity activity, String[] permissions) {
return findNeverAskAgainPermissions(activity, permissions);
}
public static List<String> getNeverAskAgainPermissions(Fragment fragment, String[] permissions) {
return findNeverAskAgainPermissions(fragment.getActivity(), permissions);
}
@TargetApi(value = Build.VERSION_CODES.M)
private static List<String> findNeverAskAgainPermissions(Activity activity, String... permissions) {
if (!isOverMarshmallow()) {
return null;
}
List<String> neverAskAgainPermission = new ArrayList<>();
for (String value : permissions) {
if (activity.checkSelfPermission(value) != PackageManager.PERMISSION_GRANTED &&
!activity.shouldShowRequestPermissionRationale(value)) {
// 拒绝&不要需要解释了(用户勾选了不再询问)
// 坑爹:第一次不做任何设置,返回值也是false。建议在权限授权结果里判断!!!
neverAskAgainPermission.add(value);
}
}
return neverAskAgainPermission;
}
@TargetApi(value = Build.VERSION_CODES.M)
static boolean hasNeverAskAgainPermission(Activity activity, List<String> permission) {
if (!isOverMarshmallow()) {
return false;
}
for (String value : permission) {
if (activity.checkSelfPermission(value) != PackageManager.PERMISSION_GRANTED &&
!activity.shouldShowRequestPermissionRationale(value)) {
return true;
}
}
return false;
}
/**
* 获取被拒绝但没有勾选不再询问的权限(可以继续申请,会继续弹框)
*/
public static List<String> getDeniedPermissionsWithoutNeverAskAgain(Activity activity, String[] permissions) {
return findDeniedPermissionWithoutNeverAskAgain(activity, permissions);
}
public static List<String> getDeniedPermissionsWithoutNeverAskAgain(Fragment fragment, String[] permissions) {
return findDeniedPermissionWithoutNeverAskAgain(fragment.getActivity(), permissions);
}
@TargetApi(value = Build.VERSION_CODES.M)
private static List<String> findDeniedPermissionWithoutNeverAskAgain(Activity activity, String... permission) {
if (!isOverMarshmallow()) {
return null;
}
List<String> denyPermissions = new ArrayList<>();
for (String value : permission) {
if (activity.checkSelfPermission(value) != PackageManager.PERMISSION_GRANTED &&
activity.shouldShowRequestPermissionRationale(value)) {
denyPermissions.add(value); // 上次申请被用户拒绝了
}
}
return denyPermissions;
}
/**
* Log专用
*/
public static void printMPermissionResult(boolean preRequest, Activity activity, String[] permissions) {
Log.i(TAG, "----- MPermission result " + (preRequest ? "before" : "after") + " request:");
List<MPermissionResultEnum> result = getPermissionResult(activity, permissions);
int i = 0;
for (BaseMPermission.MPermissionResultEnum p : result) {
Log.i(TAG, "* MPermission=" + permissions[i++] + ", result=" + p);
}
}
static String toString(List<String> permission) {
if (permission == null || permission.isEmpty()) {
return "";
}
return toString(permission.toArray(new String[permission.size()]));
}
private static String toString(String[] permission) {
if (permission == null || permission.length <= 0) {
return "";
}
StringBuilder sb = new StringBuilder();
for (String p : permission) {
sb.append(p.replaceFirst("android.permission.", ""));
sb.append(",");
}
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
}
}
package com.agenew.location_server.application.permission;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import com.agenew.location_server.application.permission.annotation.OnMPermissionDenied;
import com.agenew.location_server.application.permission.annotation.OnMPermissionGranted;
import com.agenew.location_server.application.permission.annotation.OnMPermissionNeverAskAgain;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class MPermission extends BaseMPermission {
private int requestCode;
private String[] permissions;
private Object object; // activity or fragment
private MPermission(Object object) {
this.object = object;
}
public static MPermission with(Activity activity) {
return new MPermission(activity);
}
public static MPermission with(Fragment fragment) {
return new MPermission(fragment);
}
public MPermission setRequestCode(int requestCode) {
this.requestCode = requestCode;
return this;
}
public MPermission permissions(String... permissions) {
this.permissions = permissions;
return this;
}
/**
* ********************* request *********************
*/
@TargetApi(value = Build.VERSION_CODES.M)
public void request() {
doRequestPermissions(object, requestCode, permissions);
}
@TargetApi(value = Build.VERSION_CODES.M)
private static void doRequestPermissions(Object object, int requestCode, String[] permissions) {
if (!isOverMarshmallow()) {
doExecuteSuccess(object, requestCode);
return;
}
List<String> deniedPermissions = findDeniedPermissions(getActivity(object), permissions);
if (deniedPermissions != null && deniedPermissions.size() > 0) {
if (object instanceof Activity) {
((Activity) object).requestPermissions(deniedPermissions.toArray(new String[deniedPermissions.size()]), requestCode);
} else if (object instanceof Fragment) {
((Fragment) object).requestPermissions(deniedPermissions.toArray(new String[deniedPermissions.size()]), requestCode);
} else {
throw new IllegalArgumentException(object.getClass().getName() + " is not supported");
}
} else {
doExecuteSuccess(object, requestCode);
}
}
/**
* ********************* on result *********************
*/
public static void onRequestPermissionsResult(Activity activity, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
dispatchResult(activity, requestCode, permissions, grantResults);
}
public static void onRequestPermissionsResult(Fragment fragment, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
dispatchResult(fragment, requestCode, permissions, grantResults);
}
private static void dispatchResult(Object obj, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
List<String> deniedPermissions = new ArrayList<>();
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
deniedPermissions.add(permissions[i]);
}
}
if (deniedPermissions.size() > 0) {
if (hasNeverAskAgainPermission(getActivity(obj), deniedPermissions)) {
doExecuteFailAsNeverAskAgain(obj, requestCode);
} else {
doExecuteFail(obj, requestCode);
}
} else {
doExecuteSuccess(obj, requestCode);
}
}
/**
* ********************* reflect execute result *********************
*/
private static void doExecuteSuccess(Object activity, int requestCode) {
executeMethod(activity, findMethodWithRequestCode(activity.getClass(), OnMPermissionGranted.class, requestCode));
}
private static void doExecuteFail(Object activity, int requestCode) {
executeMethod(activity, findMethodWithRequestCode(activity.getClass(), OnMPermissionDenied.class, requestCode));
}
private static void doExecuteFailAsNeverAskAgain(Object activity, int requestCode) {
executeMethod(activity, findMethodWithRequestCode(activity.getClass(), OnMPermissionNeverAskAgain.class, requestCode));
}
private static <A extends Annotation> Method findMethodWithRequestCode(Class clazz, Class<A> annotation, int
requestCode) {
for (Method method : clazz.getDeclaredMethods()) {
if (method.getAnnotation(annotation) != null &&
isEqualRequestCodeFromAnnotation(method, annotation, requestCode)) {
return method;
}
}
return null;
}
private static boolean isEqualRequestCodeFromAnnotation(Method m, Class clazz, int requestCode) {
if (clazz.equals(OnMPermissionDenied.class)) {
return requestCode == m.getAnnotation(OnMPermissionDenied.class).value();
} else if (clazz.equals(OnMPermissionGranted.class)) {
return requestCode == m.getAnnotation(OnMPermissionGranted.class).value();
} else if (clazz.equals(OnMPermissionNeverAskAgain.class)) {
return requestCode == m.getAnnotation(OnMPermissionNeverAskAgain.class).value();
} else {
return false;
}
}
/**
* ********************* reflect execute method *********************
*/
private static void executeMethod(Object activity, Method executeMethod) {
executeMethodWithParam(activity, executeMethod, new Object[]{});
}
private static void executeMethodWithParam(Object activity, Method executeMethod, Object... args) {
if (executeMethod != null) {
try {
if (!executeMethod.isAccessible()) {
executeMethod.setAccessible(true);
}
executeMethod.invoke(activity, args);
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
package com.agenew.location_server.application.permission.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* register a method invoked when permission requests are denied without check never ask again.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OnMPermissionDenied {
int value();
}
\ No newline at end of file
package com.agenew.location_server.application.permission.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* register a method invoked when permission requests are succeeded.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OnMPermissionGranted {
int value();
}
package com.agenew.location_server.application.permission.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* register some methods handling the user's choice to permanently deny permissions checking never ask again.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OnMPermissionNeverAskAgain {
int value();
}
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeWidth="1"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#EFEFEF"/>
<stroke
android:width="0.5px"
android:color="#FF6347"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
</selector>
\ No newline at end of file
<?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="#008577"
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>
<vector android:height="24dp" android:viewportHeight="1024"
android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#63BA4D" android:pathData="M635.9,692.22c-18.43,-25.6 -50.18,-41.47 -75.78,-41.47L448.51,650.75c-25.09,0 -57.34,15.87 -75.78,41.47l-45.57,63.49c-49.66,68.61 -56.32,160.26 16.38,160.26h321.02c72.7,0 66.05,-91.65 16.38,-160.26l-45.06,-63.49zM505.34,106.5c-219.14,0 -396.8,177.66 -396.8,396.8 0,118.27 52.74,230.4 143.87,305.66 5.12,-12.8 11.26,-25.6 18.43,-38.4 -15.87,-13.82 -30.21,-29.18 -43.52,-45.57 13.82,-5.63 28.16,-10.24 41.98,-14.85 4.1,14.34 8.19,27.65 13.31,41.98 0.51,-1.02 1.02,-2.05 2.05,-2.56l12.29,-16.9c-3.07,-9.22 -5.63,-18.43 -8.19,-27.65 11.78,-3.07 23.04,-6.14 34.82,-9.22l17.92,-24.58c-19.46,4.1 -38.4,9.22 -57.34,14.85 -10.75,-42.5 -17.41,-86.02 -20.99,-130.05 26.11,-4.61 46.08,-25.6 50.18,-51.71L394.24,504.32v4.1c0,61.44 49.66,111.1 111.1,111.1s111.1,-49.66 111.1,-111.1v-4.1h83.46c4.1,26.11 24.06,47.1 50.18,51.71 -3.58,44.03 -10.75,88.06 -21.5,130.56 -18.94,-5.63 -37.89,-10.75 -57.34,-14.85l17.92,25.09c11.78,3.07 23.04,6.14 34.3,9.22 -2.56,9.22 -5.12,18.43 -8.19,27.14l11.78,16.38 2.05,3.07c4.61,-13.82 9.22,-27.14 13.31,-40.96 13.82,4.61 27.14,9.22 40.45,14.34 -12.8,15.87 -27.14,30.72 -42.5,44.54 7.68,12.29 13.82,25.6 18.94,38.4 87.55,-72.7 142.85,-182.27 142.85,-305.15 0,-219.65 -177.66,-397.31 -396.8,-397.31zM860.67,483.84h-38.91c-4.61,-25.6 -25.6,-45.57 -51.2,-49.66 -4.1,-50.69 -12.8,-101.38 -27.14,-150.53 10.75,-3.58 21.5,-7.17 32.26,-11.26 50.69,59.39 80.38,133.63 84.99,211.46zM761.86,257.02c-7.68,3.07 -15.87,5.12 -24.06,7.68 -4.61,-14.34 -9.22,-28.67 -14.85,-42.5 13.82,10.75 26.62,22.53 38.91,34.82zM694.78,202.75c9.22,22.53 17.41,45.06 24.06,68.1 -49.66,14.34 -100.35,23.04 -152.06,27.14 -1.54,-28.16 -22.02,-51.71 -49.15,-56.83L517.63,148.48c62.98,1.54 123.9,20.48 177.15,54.27zM505.34,343.04c-23.04,0 -41.47,-18.43 -41.47,-41.47 1.02,-23.04 19.97,-40.45 43.01,-39.42 21.5,1.02 38.91,17.92 39.42,39.42 0,23.04 -18.43,41.47 -40.96,41.47zM318.46,200.7c53.76,-33.28 115.2,-51.71 178.69,-52.74v92.16c-29.18,4.1 -51.71,28.16 -53.25,57.86 -50.69,-4.1 -100.86,-13.31 -149.5,-27.14 7.17,-23.55 15.87,-47.1 25.09,-70.14h-1.02zM291.33,219.65c-5.63,15.36 -11.26,30.21 -15.87,46.08 -8.7,-2.56 -17.41,-5.63 -26.11,-8.7 12.8,-13.82 26.62,-26.11 41.98,-37.38zM235.01,272.38c11.26,4.1 23.04,8.19 34.3,11.78 -13.82,49.15 -23.04,99.33 -27.14,150.02 -26.11,4.1 -46.59,24.06 -51.71,49.66h-40.96c4.61,-77.82 34.3,-152.58 85.5,-211.46zM215.04,709.63c-42.5,-59.39 -65.54,-131.07 -65.54,-204.8h40.96c4.1,26.62 25.09,47.62 51.71,51.71 3.58,45.57 10.75,91.14 22.53,135.68 -16.9,5.12 -33.28,11.26 -49.66,17.41zM251.39,536.58c-22.53,0 -41.47,-18.43 -41.47,-41.47s18.43,-41.47 41.47,-41.47 41.47,18.43 41.47,41.47 -18.43,41.47 -41.47,41.47zM312.32,483.84c-4.61,-25.09 -24.58,-45.06 -49.66,-49.66 4.1,-48.64 12.29,-97.28 25.6,-144.9 51.2,14.85 103.94,24.58 157.18,28.67 6.66,23.55 27.14,40.96 51.2,44.03v34.82c-48.64,3.58 -89.6,38.91 -100.35,86.53L312.32,483.33v0.51zM699.9,483.84h-86.53c-10.75,-46.08 -49.15,-80.38 -96.26,-86.02v-35.84c22.53,-4.61 40.45,-21.5 47.1,-43.52 54.27,-4.1 107.52,-13.82 159.74,-29.18 12.8,47.1 21.5,95.74 25.09,144.9 -24.58,5.12 -44.03,24.58 -49.15,49.66zM719.87,495.62c0,-23.04 18.43,-41.47 41.47,-41.47 22.53,0 41.47,18.43 41.47,41.47 0,22.53 -18.43,41.47 -41.47,41.47 -23.04,-0.51 -41.47,-18.94 -41.47,-41.47zM747.52,693.25c11.78,-44.54 19.46,-90.11 23.04,-136.19 26.62,-4.1 47.62,-25.09 51.71,-51.71h38.91c0,73.73 -23.04,145.92 -66.05,205.82 -15.87,-7.17 -31.74,-12.8 -47.62,-17.92z"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/interval"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/interval"
android:textSize="18dp"
tools:layout_editor_absoluteX="4dp"
tools:layout_editor_absoluteY="0dp" />
<EditText
android:id="@+id/interval_value"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="50sp"
android:inputType="number"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/url"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/url"
android:textSize="18dp" />
<EditText
android:id="@+id/url_value"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="50sp"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<Button
android:id="@+id/bt_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dialog_cancel"
android:textAllCaps="false"
android:textSize="25sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<Button
android:id="@+id/bt_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dialog_save"
android:textAllCaps="false"
android:textSize="25sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">定位</string>
<string name="dialog_cancel">取消</string>
<string name="url">"上传地址:"</string>>
<string name="interval">"时间间隔(分钟):"</string>
<string name="dialog_save">"保存"</string>
<string name="interval_prompt">"请设置间隔时长"</string>
<string name="server_prompt">"请设置服务器地址"</string>
<string name="error_msg_1">"经纬度信息无效"</string>
<string name="error_msg_2">"MEID无效"</string>
<string name="error_msg_3">"内部处理错误"</string>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
</resources>
<resources>
<string name="app_name">Location</string>
<string name="dialog_cancel">Cancel</string>
<string name="url">"Upload address:"</string>>
<string name="interval">"Time interval(minutes):"</string>
<string name="dialog_save">save</string>
<string name="interval_prompt">"Please set the interval time"</string>
<string name="server_prompt">"Please set the server url"</string>
<string name="error_msg_1">"Latitude and longitude information is invalid"</string>
<string name="error_msg_2">"Invalid MEID"</string>
<string name="error_msg_3">"Internal processing error"</string>
</resources>
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
package com.agenew.location_server.application;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}
\ No newline at end of file
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
No preview for this file type
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
include ':app'
No preview for this file type
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!