Этот коммит содержится в:
Anton Tananaev
2017-08-30 13:25:18 +12:00
родитель 90fffa9873
Коммит e0c5340d8b
21 изменённых файлов: 192 добавлений и 302 удалений
+1
Просмотреть файл
@@ -35,6 +35,7 @@ android {
} }
dependencies { dependencies {
compile 'com.android.support:design:26.0.1'
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:3.4.2' testCompile 'org.robolectric:robolectric:3.4.2'
} }
+2 -2
Просмотреть файл
@@ -17,11 +17,11 @@
android:theme="@style/TraccarTheme" android:theme="@style/TraccarTheme"
android:name=".MainApplication"> android:name=".MainApplication">
<activity android:name=".MainActivity" android:launchMode="singleTask" /> <activity android:name=".MainFragment" android:launchMode="singleTask" />
<activity-alias <activity-alias
android:name=".Launcher" android:name=".Launcher"
android:targetActivity=".MainActivity"> android:targetActivity=".MainFragment">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
-134
Просмотреть файл
@@ -1,134 +0,0 @@
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.support.v4.content;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.util.Log;
import android.util.SparseArray;
/**
* Helper for the common pattern of implementing a {@link BroadcastReceiver}
* that receives a device wakeup event and then passes the work off
* to a {@link android.app.Service}, while ensuring that the
* device does not go back to sleep during the transition.
*
* <p>This class takes care of creating and managing a partial wake lock
* for you; you must request the {@link android.Manifest.permission#WAKE_LOCK}
* permission to use it.</p>
*
* <h3>Example</h3>
*
* <p>A {@link WakefulBroadcastReceiver} uses the method
* {@link WakefulBroadcastReceiver#startWakefulService startWakefulService()}
* to start the service that does the work. This method is comparable to
* {@link android.content.Context#startService startService()}, except that
* the {@link WakefulBroadcastReceiver} is holding a wake lock when the service
* starts. The intent that is passed with
* {@link WakefulBroadcastReceiver#startWakefulService startWakefulService()}
* holds an extra identifying the wake lock.</p>
*
* {@sample development/samples/Support4Demos/src/com/example/android/supportv4/content/SimpleWakefulReceiver.java complete}
*
* <p>The service (in this example, an {@link android.app.IntentService}) does
* some work. When it is finished, it releases the wake lock by calling
* {@link WakefulBroadcastReceiver#completeWakefulIntent
* completeWakefulIntent(intent)}. The intent it passes as a parameter
* is the same intent that the {@link WakefulBroadcastReceiver} originally
* passed in.</p>
*
* {@sample development/samples/Support4Demos/src/com/example/android/supportv4/content/SimpleWakefulService.java complete}
*/
public abstract class WakefulBroadcastReceiver extends BroadcastReceiver {
private static final String EXTRA_WAKE_LOCK_ID = "android.support.content.wakelockid";
private static final SparseArray<PowerManager.WakeLock> mActiveWakeLocks
= new SparseArray<PowerManager.WakeLock>();
private static int mNextId = 1;
/**
* Do a {@link android.content.Context#startService(android.content.Intent)
* Context.startService}, but holding a wake lock while the service starts.
* This will modify the Intent to hold an extra identifying the wake lock;
* when the service receives it in {@link android.app.Service#onStartCommand
* Service.onStartCommand}, it should pass back the Intent it receives there to
* {@link #completeWakefulIntent(android.content.Intent)} in order to release
* the wake lock.
*
* @param context The Context in which it operate.
* @param intent The Intent with which to start the service, as per
* {@link android.content.Context#startService(android.content.Intent)
* Context.startService}.
*/
public static ComponentName startWakefulService(Context context, Intent intent) {
synchronized (mActiveWakeLocks) {
int id = mNextId;
mNextId++;
if (mNextId <= 0) {
mNextId = 1;
}
intent.putExtra(EXTRA_WAKE_LOCK_ID, id);
ComponentName comp = context.startService(intent);
if (comp == null) {
return null;
}
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"wake:" + comp.flattenToShortString());
wl.setReferenceCounted(false);
wl.acquire(60*1000);
mActiveWakeLocks.put(id, wl);
return comp;
}
}
/**
* Finish the execution from a previous {@link #startWakefulService}. Any wake lock
* that was being held will now be released.
*
* @param intent The Intent as originally generated by {@link #startWakefulService}.
* @return Returns true if the intent is associated with a wake lock that is
* now released; returns false if there was no wake lock specified for it.
*/
public static boolean completeWakefulIntent(Intent intent) {
final int id = intent.getIntExtra(EXTRA_WAKE_LOCK_ID, 0);
if (id == 0) {
return false;
}
synchronized (mActiveWakeLocks) {
PowerManager.WakeLock wl = mActiveWakeLocks.get(id);
if (wl != null) {
wl.release();
mActiveWakeLocks.remove(id);
return true;
}
// We return true whether or not we actually found the wake lock
// the return code is defined to indicate whether the Intent contained
// an identifier for a wake lock that it was supposed to match.
// We just log a warning here if there is no wake lock found, which could
// happen for example if this function is called twice on the same
// intent or the process is killed and restarted before processing the intent.
Log.w("WakefulBroadcastReceive", "No active wake lock id #" + id);
return true;
}
}
}
+6 -4
Просмотреть файл
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012 Anton Tananaev (anton.tananaev@gmail.com) * Copyright 2012 - 2017 Anton Tananaev (anton.tananaev@gmail.com)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -15,22 +15,24 @@
*/ */
package org.traccar.client; package org.traccar.client;
import android.app.Activity;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView; import android.widget.TextView;
public class AboutActivity extends Activity { public class AboutActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.about); setContentView(R.layout.about);
TextView title = (TextView) findViewById(R.id.title); TextView title = findViewById(R.id.title);
try { try {
title.setText(title.getText() + " " + getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName); title.setText(title.getText() + " " + getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName);
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
Log.w(AboutActivity.class.getSimpleName(), e);
} }
} }
+1 -1
Просмотреть файл
@@ -26,7 +26,7 @@ public class AutostartReceiver extends WakefulBroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedPreferences.getBoolean(MainActivity.KEY_STATUS, false)) { if (sharedPreferences.getBoolean(MainFragment.KEY_STATUS, false)) {
startWakefulService(context, new Intent(context, TrackingService.class)); startWakefulService(context, new Intent(context, TrackingService.class));
} }
} }
+1 -1
Просмотреть файл
@@ -28,7 +28,7 @@ public class DialLaunchReceiver extends BroadcastReceiver {
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
if (phoneNumber.equals(LAUNCHER_NUMBER)) { if (phoneNumber.equals(LAUNCHER_NUMBER)) {
setResultData(null); setResultData(null);
Intent appIntent = new Intent(context, MainActivity.class); Intent appIntent = new Intent(context, MainFragment.class);
appIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); appIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(appIntent); context.startActivity(appIntent);
} }
@@ -20,6 +20,7 @@ import android.app.AlarmManager;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
@@ -30,11 +31,14 @@ import android.os.Bundle;
import android.preference.CheckBoxPreference; import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference; import android.preference.EditTextPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceActivity; import android.preference.PreferenceFragment;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.preference.TwoStatePreference; import android.preference.TwoStatePreference;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.webkit.URLUtil; import android.webkit.URLUtil;
import android.widget.Toast; import android.widget.Toast;
@@ -43,10 +47,9 @@ import java.util.HashSet;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
@SuppressWarnings("deprecation") public class MainFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {
public class MainActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
private static final String TAG = MainActivity.class.getSimpleName(); private static final String TAG = MainFragment.class.getSimpleName();
public static final String KEY_DEVICE = "id"; public static final String KEY_DEVICE = "id";
public static final String KEY_URL = "url"; public static final String KEY_URL = "url";
@@ -70,7 +73,7 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen
removeLauncherIcon(); removeLauncherIcon();
} }
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
migrateLegacyPreferences(sharedPreferences); migrateLegacyPreferences(sharedPreferences);
addPreferencesFromResource(R.xml.preferences); addPreferencesFromResource(R.xml.preferences);
initPreferences(); initPreferences();
@@ -120,8 +123,8 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen
findPreference(KEY_DISTANCE).setOnPreferenceChangeListener(numberValidationListener); findPreference(KEY_DISTANCE).setOnPreferenceChangeListener(numberValidationListener);
findPreference(KEY_ANGLE).setOnPreferenceChangeListener(numberValidationListener); findPreference(KEY_ANGLE).setOnPreferenceChangeListener(numberValidationListener);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
alarmIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, AutostartReceiver.class), 0); alarmIntent = PendingIntent.getBroadcast(getActivity(), 0, new Intent(getActivity(), AutostartReceiver.class), 0);
if (sharedPreferences.getBoolean(KEY_STATUS, false)) { if (sharedPreferences.getBoolean(KEY_STATUS, false)) {
startTrackingService(true, false); startTrackingService(true, false);
@@ -129,14 +132,14 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen
} }
private void removeLauncherIcon() { private void removeLauncherIcon() {
String className = MainActivity.class.getCanonicalName().replace(".MainActivity", ".Launcher"); String className = MainFragment.class.getCanonicalName().replace(".MainActivity", ".Launcher");
ComponentName componentName = new ComponentName(getPackageName(), className); ComponentName componentName = new ComponentName(getActivity().getPackageName(), className);
PackageManager packageManager = getPackageManager(); PackageManager packageManager = getActivity().getPackageManager();
if (packageManager.getComponentEnabledSetting(componentName) != PackageManager.COMPONENT_ENABLED_STATE_DISABLED) { if (packageManager.getComponentEnabledSetting(componentName) != PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
packageManager.setComponentEnabledSetting( packageManager.setComponentEnabledSetting(
componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setIcon(android.R.drawable.ic_dialog_alert); builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.hidden_alert)); builder.setMessage(getString(R.string.hidden_alert));
builder.setPositiveButton(android.R.string.ok, null); builder.setPositiveButton(android.R.string.ok, null);
@@ -146,32 +149,32 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen
private void addShortcuts(String action, int name) { private void addShortcuts(String action, int name) {
Intent shortcutIntent = new Intent(Intent.ACTION_MAIN); Intent shortcutIntent = new Intent(Intent.ACTION_MAIN);
shortcutIntent.setComponent(new ComponentName(getPackageName(), ShortcutActivity.class.getCanonicalName())); shortcutIntent.setComponent(new ComponentName(getActivity().getPackageName(), ShortcutActivity.class.getCanonicalName()));
shortcutIntent.putExtra(ShortcutActivity.EXTRA_ACTION, action); shortcutIntent.putExtra(ShortcutActivity.EXTRA_ACTION, action);
Intent installShortCutIntent = new Intent("com.android.launcher.action.INSTALL_SHORTCUT"); Intent installShortCutIntent = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
installShortCutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); installShortCutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
installShortCutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(name)); installShortCutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(name));
installShortCutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, installShortCutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
Intent.ShortcutIconResource.fromContext(this, R.mipmap.ic_launcher)); Intent.ShortcutIconResource.fromContext(getActivity(), R.mipmap.ic_launcher));
sendBroadcast(installShortCutIntent); getActivity().sendBroadcast(installShortCutIntent);
} }
private boolean hasPermission(String permission) { private boolean hasPermission(String permission) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
return true; return true;
} }
return checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED; return ContextCompat.checkSelfPermission(getActivity(), permission) == PackageManager.PERMISSION_GRANTED;
} }
@Override @Override
protected void onResume() { public void onResume() {
super.onResume(); super.onResume();
sharedPreferences.registerOnSharedPreferenceChangeListener(this); sharedPreferences.registerOnSharedPreferenceChangeListener(this);
} }
@Override @Override
protected void onPause() { public void onPause() {
super.onPause(); super.onPause();
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this); sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
} }
@@ -199,15 +202,15 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen
} }
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
getMenuInflater().inflate(R.menu.main, menu); inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu); super.onCreateOptionsMenu(menu, inflater);
} }
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.status) { if (item.getItemId() == R.id.status) {
startActivity(new Intent(this, StatusActivity.class)); startActivity(new Intent(getActivity(), StatusActivity.class));
return true; return true;
} else if (item.getItemId() == R.id.shortcuts) { } else if (item.getItemId() == R.id.shortcuts) {
addShortcuts(ShortcutActivity.EXTRA_ACTION_START, R.string.shortcut_start); addShortcuts(ShortcutActivity.EXTRA_ACTION_START, R.string.shortcut_start);
@@ -215,18 +218,18 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen
addShortcuts(ShortcutActivity.EXTRA_ACTION_SOS, R.string.shortcut_sos); addShortcuts(ShortcutActivity.EXTRA_ACTION_SOS, R.string.shortcut_sos);
return true; return true;
} else if (item.getItemId() == R.id.about) { } else if (item.getItemId() == R.id.about) {
startActivity(new Intent(this, AboutActivity.class)); startActivity(new Intent(getActivity(), AboutActivity.class));
return true; return true;
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
private void initPreferences() { private void initPreferences() {
PreferenceManager.setDefaultValues(this, R.xml.preferences, false); PreferenceManager.setDefaultValues(getActivity(), R.xml.preferences, false);
if (!sharedPreferences.contains(KEY_DEVICE)) { if (!sharedPreferences.contains(KEY_DEVICE)) {
String id = String.valueOf(new Random().nextInt(900000) + 100000); String id = String.valueOf(new Random().nextInt(900000) + 100000);
sharedPreferences.edit().putString(KEY_DEVICE, id).commit(); sharedPreferences.edit().putString(KEY_DEVICE, id).apply();
((EditTextPreference) findPreference(KEY_DEVICE)).setText(id); ((EditTextPreference) findPreference(KEY_DEVICE)).setText(id);
} }
findPreference(KEY_DEVICE).setSummary(sharedPreferences.getString(KEY_DEVICE, null)); findPreference(KEY_DEVICE).setSummary(sharedPreferences.getString(KEY_DEVICE, null));
@@ -254,11 +257,11 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen
if (permission) { if (permission) {
setPreferencesEnabled(false); setPreferencesEnabled(false);
startService(new Intent(this, TrackingService.class)); getActivity().startService(new Intent(getActivity(), TrackingService.class));
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
15000, 15000, alarmIntent); 15000, 15000, alarmIntent);
} else { } else {
sharedPreferences.edit().putBoolean(KEY_STATUS, false).commit(); sharedPreferences.edit().putBoolean(KEY_STATUS, false).apply();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
TwoStatePreference preference = (TwoStatePreference) findPreference(KEY_STATUS); TwoStatePreference preference = (TwoStatePreference) findPreference(KEY_STATUS);
preference.setChecked(false); preference.setChecked(false);
@@ -271,12 +274,12 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen
private void stopTrackingService() { private void stopTrackingService() {
alarmManager.cancel(alarmIntent); alarmManager.cancel(alarmIntent);
stopService(new Intent(this, TrackingService.class)); getActivity().stopService(new Intent(getActivity(), TrackingService.class));
setPreferencesEnabled(true); setPreferencesEnabled(true);
} }
@Override @Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PERMISSIONS_REQUEST_LOCATION) { if (requestCode == PERMISSIONS_REQUEST_LOCATION) {
boolean granted = true; boolean granted = true;
for (int result : grantResults) { for (int result : grantResults) {
@@ -295,14 +298,14 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen
&& (URLUtil.isHttpUrl(userUrl) || URLUtil.isHttpsUrl(userUrl))) { && (URLUtil.isHttpUrl(userUrl) || URLUtil.isHttpsUrl(userUrl))) {
return true; return true;
} }
Toast.makeText(MainActivity.this, R.string.error_msg_invalid_url, Toast.LENGTH_LONG).show(); Toast.makeText(getActivity(), R.string.error_msg_invalid_url, Toast.LENGTH_LONG).show();
return false; return false;
} }
private void migrateLegacyPreferences(SharedPreferences preferences) { private void migrateLegacyPreferences(SharedPreferences preferences) {
String port = preferences.getString("port", null); String port = preferences.getString("port", null);
if (port != null) { if (port != null) {
Log.d(TAG, "migrateLegacyPreferences: migrating to URL preference"); Log.d(TAG, "Migrating to URL preference");
String host = preferences.getString("address", getString(R.string.settings_url_default_value)); String host = preferences.getString("address", getString(R.string.settings_url_default_value));
String scheme = preferences.getBoolean("secure", false) ? "https" : "http"; String scheme = preferences.getBoolean("secure", false) ? "https" : "http";
@@ -315,7 +318,8 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen
editor.remove("port"); editor.remove("port");
editor.remove("address"); editor.remove("address");
editor.remove("secure"); editor.remove("secure");
editor.commit(); editor.apply();
} }
} }
} }
+73 -19
Просмотреть файл
@@ -1,5 +1,5 @@
/* /*
* Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) * Copyright 2015 - 2017 Anton Tananaev (anton.tananaev@gmail.com)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -36,39 +36,93 @@ public class Position {
} }
private long id; private long id;
public long getId() { return id; }
public void setId(long id) { this.id = id; } public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
private String deviceId; private String deviceId;
public String getDeviceId() { return deviceId; }
public void setDeviceId(String deviceId) { this.deviceId = deviceId; } public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
private Date time; private Date time;
public Date getTime() { return time; }
public void setTime(Date time) { this.time = time; } public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
private double latitude; private double latitude;
public double getLatitude() { return latitude; }
public void setLatitude(double latitude) { this.latitude = latitude; } public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
private double longitude; private double longitude;
public double getLongitude() { return longitude; }
public void setLongitude(double longitude) { this.longitude = longitude; } public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
private double altitude; private double altitude;
public double getAltitude() { return altitude; }
public void setAltitude(double altitude) { this.altitude = altitude; } public double getAltitude() {
return altitude;
}
public void setAltitude(double altitude) {
this.altitude = altitude;
}
private double speed; private double speed;
public double getSpeed() { return speed; }
public void setSpeed(double speed) { this.speed = speed; } public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
private double course; private double course;
public double getCourse() { return course; }
public void setCourse(double course) { this.course = course; } public double getCourse() {
return course;
}
public void setCourse(double course) {
this.course = course;
}
private double battery; private double battery;
public double getBattery() { return battery; }
public void setBattery(double battery) { this.battery = battery; } public double getBattery() {
return battery;
}
public void setBattery(double battery) {
this.battery = battery;
}
} }
+9 -16
Просмотреть файл
@@ -15,7 +15,6 @@
*/ */
package org.traccar.client; package org.traccar.client;
import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
@@ -23,7 +22,6 @@ import android.content.SharedPreferences;
import android.location.Location; import android.location.Location;
import android.location.LocationManager; import android.location.LocationManager;
import android.os.BatteryManager; import android.os.BatteryManager;
import android.os.Build;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
@@ -58,10 +56,10 @@ public abstract class PositionProvider {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
deviceId = preferences.getString(MainActivity.KEY_DEVICE, null); deviceId = preferences.getString(MainFragment.KEY_DEVICE, null);
interval = Long.parseLong(preferences.getString(MainActivity.KEY_INTERVAL, null)) * 1000; interval = Long.parseLong(preferences.getString(MainFragment.KEY_INTERVAL, null)) * 1000;
distance = Integer.parseInt(preferences.getString(MainActivity.KEY_DISTANCE, null)); distance = Integer.parseInt(preferences.getString(MainFragment.KEY_DISTANCE, null));
angle = Integer.parseInt(preferences.getString(MainActivity.KEY_ANGLE, null)); angle = Integer.parseInt(preferences.getString(MainFragment.KEY_ANGLE, null));
if (distance > 0 || angle > 0) { if (distance > 0 || angle > 0) {
requestInterval = MINIMUM_INTERVAL; requestInterval = MINIMUM_INTERVAL;
@@ -69,7 +67,7 @@ public abstract class PositionProvider {
requestInterval = interval; requestInterval = interval;
} }
type = preferences.getString(MainActivity.KEY_PROVIDER, "gps"); type = preferences.getString(MainFragment.KEY_PROVIDER, "gps");
} }
public abstract void startUpdates(); public abstract void startUpdates();
@@ -89,16 +87,11 @@ public abstract class PositionProvider {
} }
} }
@TargetApi(Build.VERSION_CODES.ECLAIR)
public static double getBatteryLevel(Context context) { public static double getBatteryLevel(Context context) {
if (android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.ECLAIR) { Intent batteryIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
Intent batteryIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 1);
int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 1); return (level * 100.0) / scale;
return (level * 100.0) / scale;
} else {
return 0;
}
} }
} }
+2 -1
Просмотреть файл
@@ -16,6 +16,7 @@
package org.traccar.client; package org.traccar.client;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.util.Log;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -68,7 +69,7 @@ public class RequestManager {
inputStream.close(); inputStream.close();
} }
} catch (IOException secondError) { } catch (IOException secondError) {
return false; Log.w(RequestManager.class.getSimpleName(), secondError);
} }
} }
} }
+6 -6
Просмотреть файл
@@ -15,7 +15,6 @@
*/ */
package org.traccar.client; package org.traccar.client;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@@ -23,9 +22,10 @@ import android.location.Location;
import android.location.LocationManager; import android.location.LocationManager;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast; import android.widget.Toast;
public class ShortcutActivity extends Activity { public class ShortcutActivity extends AppCompatActivity {
public static final String EXTRA_ACTION = "action"; public static final String EXTRA_ACTION = "action";
public static final String EXTRA_ACTION_START = "start"; public static final String EXTRA_ACTION_START = "start";
@@ -60,11 +60,11 @@ public class ShortcutActivity extends Activity {
if (location != null) { if (location != null) {
Position position = new Position( Position position = new Position(
preferences.getString(MainActivity.KEY_DEVICE, null), preferences.getString(MainFragment.KEY_DEVICE, null),
location, PositionProvider.getBatteryLevel(this)); location, PositionProvider.getBatteryLevel(this));
String request = ProtocolFormatter.formatRequest( String request = ProtocolFormatter.formatRequest(
preferences.getString(MainActivity.KEY_URL, null), position, ALARM_SOS); preferences.getString(MainFragment.KEY_URL, null), position, ALARM_SOS);
RequestManager.sendRequestAsync(request, new RequestManager.RequestHandler() { RequestManager.sendRequestAsync(request, new RequestManager.RequestHandler() {
@Override @Override
@@ -94,13 +94,13 @@ public class ShortcutActivity extends Activity {
switch (action) { switch (action) {
case EXTRA_ACTION_START: case EXTRA_ACTION_START:
PreferenceManager.getDefaultSharedPreferences(this) PreferenceManager.getDefaultSharedPreferences(this)
.edit().putBoolean(MainActivity.KEY_STATUS, true).commit(); .edit().putBoolean(MainFragment.KEY_STATUS, true).commit();
startService(new Intent(this, TrackingService.class)); startService(new Intent(this, TrackingService.class));
Toast.makeText(this, R.string.status_service_create, Toast.LENGTH_SHORT).show(); Toast.makeText(this, R.string.status_service_create, Toast.LENGTH_SHORT).show();
break; break;
case EXTRA_ACTION_STOP: case EXTRA_ACTION_STOP:
PreferenceManager.getDefaultSharedPreferences(this) PreferenceManager.getDefaultSharedPreferences(this)
.edit().putBoolean(MainActivity.KEY_STATUS, false).commit(); .edit().putBoolean(MainFragment.KEY_STATUS, false).commit();
stopService(new Intent(this, TrackingService.class)); stopService(new Intent(this, TrackingService.class));
Toast.makeText(this, R.string.status_service_destroy, Toast.LENGTH_SHORT).show(); Toast.makeText(this, R.string.status_service_destroy, Toast.LENGTH_SHORT).show();
break; break;
+9 -7
Просмотреть файл
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012 - 2013 Anton Tananaev (anton.tananaev@gmail.com) * Copyright 2012 - 2017 Anton Tananaev (anton.tananaev@gmail.com)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -21,19 +21,20 @@ import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Set; import java.util.Set;
import android.app.ListActivity;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.ListView;
public class StatusActivity extends ListActivity { public class StatusActivity extends AppCompatActivity {
private static final int LIMIT = 20; private static final int LIMIT = 20;
private static final LinkedList<String> messages = new LinkedList<String>(); private static final LinkedList<String> messages = new LinkedList<>();
private static final Set<ArrayAdapter<String>> adapters = new HashSet<ArrayAdapter<String>>(); private static final Set<ArrayAdapter<String>> adapters = new HashSet<>();
private static void notifyAdapters() { private static void notifyAdapters() {
for (ArrayAdapter<String> adapter : adapters) { for (ArrayAdapter<String> adapter : adapters) {
@@ -62,8 +63,9 @@ public class StatusActivity extends ListActivity {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.status); setContentView(R.layout.status);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, messages); adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, android.R.id.text1, messages);
setListAdapter(adapter); ListView listView = findViewById(android.R.id.list);
listView.setAdapter(adapter);
adapters.add(adapter); adapters.add(adapter);
} }
+4 -9
Просмотреть файл
@@ -17,7 +17,6 @@ package org.traccar.client;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.PowerManager; import android.os.PowerManager;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
@@ -45,11 +44,7 @@ public class TrackingController implements PositionProvider.PositionListener, Ne
private PowerManager.WakeLock wakeLock; private PowerManager.WakeLock wakeLock;
private void lock() { private void lock() {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) { wakeLock.acquire(WAKE_LOCK_TIMEOUT);
wakeLock.acquire();
} else {
wakeLock.acquire(WAKE_LOCK_TIMEOUT);
}
} }
private void unlock() { private void unlock() {
@@ -62,7 +57,7 @@ public class TrackingController implements PositionProvider.PositionListener, Ne
this.context = context; this.context = context;
handler = new Handler(); handler = new Handler();
preferences = PreferenceManager.getDefaultSharedPreferences(context); preferences = PreferenceManager.getDefaultSharedPreferences(context);
if (preferences.getString(MainActivity.KEY_PROVIDER, "gps").equals("mixed")) { if (preferences.getString(MainFragment.KEY_PROVIDER, "gps").equals("mixed")) {
positionProvider = new MixedPositionProvider(context, this); positionProvider = new MixedPositionProvider(context, this);
} else { } else {
positionProvider = new SimplePositionProvider(context, this); positionProvider = new SimplePositionProvider(context, this);
@@ -71,7 +66,7 @@ public class TrackingController implements PositionProvider.PositionListener, Ne
networkManager = new NetworkManager(context, this); networkManager = new NetworkManager(context, this);
isOnline = networkManager.isOnline(); isOnline = networkManager.isOnline();
url = preferences.getString(MainActivity.KEY_URL, null); url = preferences.getString(MainFragment.KEY_URL, null);
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName()); wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
@@ -160,7 +155,7 @@ public class TrackingController implements PositionProvider.PositionListener, Ne
public void onComplete(boolean success, Position result) { public void onComplete(boolean success, Position result) {
if (success) { if (success) {
if (result != null) { if (result != null) {
if (result.getDeviceId().equals(preferences.getString(MainActivity.KEY_DEVICE, null))) { if (result.getDeviceId().equals(preferences.getString(MainFragment.KEY_DEVICE, null))) {
send(result); send(result);
} else { } else {
delete(result); delete(result);
+7 -18
Просмотреть файл
@@ -35,9 +35,8 @@ public class TrackingService extends Service {
private TrackingController trackingController; private TrackingController trackingController;
@SuppressWarnings("deprecation")
private static Notification createNotification(Context context) { private static Notification createNotification(Context context) {
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainFragment.class), 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
@@ -94,10 +93,8 @@ public class TrackingService extends Service {
trackingController = new TrackingController(this); trackingController = new TrackingController(this);
trackingController.start(); trackingController.start();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) { startForeground(NOTIFICATION_ID, createNotification(this));
startForeground(NOTIFICATION_ID, createNotification(this)); startService(new Intent(this, HideNotificationService.class));
startService(new Intent(this, HideNotificationService.class));
}
} }
@Override @Override
@@ -105,18 +102,12 @@ public class TrackingService extends Service {
return null; return null;
} }
@SuppressWarnings("deprecation")
@Override
public void onStart(Intent intent, int startId) {
if (intent != null) {
AutostartReceiver.completeWakefulIntent(intent);
}
}
@TargetApi(Build.VERSION_CODES.ECLAIR) @TargetApi(Build.VERSION_CODES.ECLAIR)
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId); if (intent != null) {
AutostartReceiver.completeWakefulIntent(intent);
}
return START_STICKY; return START_STICKY;
} }
@@ -125,9 +116,7 @@ public class TrackingService extends Service {
Log.i(TAG, "service destroy"); Log.i(TAG, "service destroy");
StatusActivity.addMessage(getString(R.string.status_service_destroy)); StatusActivity.addMessage(getString(R.string.status_service_destroy));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) { stopForeground(true);
stopForeground(true);
}
if (trackingController != null) { if (trackingController != null) {
trackingController.stop(); trackingController.stop();
Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 3.6 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 2.4 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 4.8 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 7.2 KiB

+30 -48
Просмотреть файл
@@ -1,56 +1,38 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" > android:layout_height="fill_parent"
android:layout_margin="@dimen/about_margin"
android:layout_toRightOf="@+id/logo"
android:layout_toEndOf="@+id/logo"
android:orientation="vertical" >
<ImageView <TextView
android:id="@+id/logo" android:id="@+id/title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_marginBottom="@dimen/about_spacing"
android:layout_alignParentStart="true" android:text="@string/app_name"
android:layout_alignParentTop="true" android:textAppearance="?android:attr/textAppearanceLarge" />
android:layout_marginLeft="@dimen/about_margin"
android:layout_marginStart="@dimen/about_margin"
android:layout_marginTop="@dimen/about_margin"
android:src="@drawable/logo"
android:contentDescription="@string/app_logo" />
<LinearLayout <TextView
android:layout_width="fill_parent" android:layout_width="wrap_content"
android:layout_height="fill_parent" android:layout_height="wrap_content"
android:layout_margin="@dimen/about_margin" android:layout_marginBottom="@dimen/about_spacing"
android:layout_toRightOf="@+id/logo" android:text="@string/about_description" />
android:layout_toEndOf="@+id/logo"
android:orientation="vertical" >
<TextView <TextView
android:id="@+id/title" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_marginBottom="@dimen/about_spacing"
android:layout_marginBottom="@dimen/about_spacing" android:text="@string/about_license" />
android:text="@string/app_name"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/about_spacing"
android:text="@string/about_description" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/about_spacing"
android:text="@string/about_license" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/about_spacing"
android:text="@string/about_web"
android:autoLink="web" />
</LinearLayout>
</RelativeLayout> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/about_spacing"
android:text="@string/about_web"
android:autoLink="web" />
</LinearLayout>
+4 -3
Просмотреть файл
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android" <ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/list" android:id="@android:id/list"
android:layout_width="fill_parent" android:layout_width="match_parent"
android:layout_height="fill_parent" /> android:layout_height="match_parent" />
+2 -2
Просмотреть файл
@@ -3,15 +3,15 @@
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
google()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:2.3.2' classpath 'com.android.tools.build:gradle:2.3.3'
} }
} }
allprojects { allprojects {
repositories { repositories {
jcenter() jcenter()
google()
} }
} }