Текст книги "Разработка Android-приложений в деталях"
Автор книги: Тимур Машнин
Жанр: Компьютеры: прочее, Компьютеры
Возрастные ограничения: +12
сообщить о неприемлемом содержимом
Текущая страница: 13 (всего у книги 20 страниц)
editor. putLong («SAVING_INTERVAL», SAVING_INTERVAL);
editor.commit ();
}
mGoogleDriveApiClient = new GoogleApiClient. Builder (this)
.addApi (Drive. API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks (this)
.addOnConnectionFailedListener (this)
.addApi (AppIndex. API).build ();
mGoogleDriveApiClient.connect ();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener (new View. OnClickListener () {
@Override
public void onClick (View view) {
Boolean start = mSettings.getBoolean («APP_PREFERENCES_START_ALARM», false);
if (start == false) {
long interval = mSettings.getLong («TRACKING_INTERVAL», 15L * 1000 * 60);
StartAlarmIntentService.startActionAlarm (context, interval);
SharedPreferences. Editor editor = mSettings. edit ();
editor. putBoolean («APP_PREFERENCES_START_ALARM», true);
editor.commit ();
Snackbar snack = Snackbar.make (view, «Tracking started with " + interval / (1000 * 60) + " minutes interval», Snackbar. LENGTH_LONG);
View snackbarView = snack.getView ();
snackbarView.setBackgroundColor(Color.parseColor («#e1da21»));
TextView tv = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
tv.setGravity (Gravity. CENTER);
snack.setAction («Action», null).show ();
} else {
long interval = mSettings.getLong («TRACKING_INTERVAL», 15L * 1000 * 60);
Snackbar snack = Snackbar.make (view, «Tracking is already working with " + interval / (1000 * 60) + " minutes interval», Snackbar. LENGTH_LONG);
View snackbarView = snack.getView ();
snackbarView.setBackgroundColor(Color.parseColor («#e1da21»));
TextView tv = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
tv.setGravity (Gravity. CENTER);
snack.setAction («Action», null).show ();
}
}
});
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle (
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener (toggle);
toggle.syncState ();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener (this);
}
@Override
public void onSaveInstanceState (Bundle savedInstanceState) {
// Save custom values into the bundle
savedInstanceState. putLong («TRACKING_INTERVAL», TRACKING_INTERVAL);
savedInstanceState. putLong («SAVING_INTERVAL», SAVING_INTERVAL);
// Always call the superclass so it can save the view hierarchy state
super. onSaveInstanceState (savedInstanceState);
}
public void onRestoreInstanceState (Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super. onRestoreInstanceState (savedInstanceState);
// Restore state members from saved instance
TRACKING_INTERVAL = savedInstanceState.getLong («TRACKING_INTERVAL»);
SAVING_INTERVAL = savedInstanceState.getLong («SAVING_INTERVAL»);
}
@Override
public void onBackPressed () {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super. onBackPressed ();
}
}
@Override
public boolean onCreateOptionsMenu (Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
long interval=mSettings.getLong («TRACKING_INTERVAL», 15L * 1000 * 60);
int itemID = getResources().getIdentifier («action_" + (int) (interval / (1000 * 60)) + "_minute», «id», getPackageName ());
MenuItem item = menu.findItem (itemID);
item.setChecked (true);
long saving_interval=mSettings.getLong («SAVING_INTERVAL», 24L * 1000 * 60 * 60);
itemID = getResources().getIdentifier («action_data_" + (int) (saving_interval/ (1000*60*60*24)) +"_day», «id», getPackageName ());
item = menu.findItem (itemID);
item.setChecked (true);
return true;
}
@Override
public boolean onOptionsItemSelected (MenuItem item) {
int id = item.getItemId ();
if (id == R.id.action_setting_account) {
DialogFragment dialog = new LoginDialogFragment ();
dialog.show (getSupportFragmentManager (), «LoginDialogFragment»);
return true;
}
if (id == R.id.action_data_1_day) {
item.setChecked (true);
SAVING_INTERVAL=24L*1000*60*60;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («SAVING_INTERVAL», SAVING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_data_2_day) {
item.setChecked (true);
SAVING_INTERVAL=24L*1000*60*60*2;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («SAVING_INTERVAL», SAVING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_data_3_day) {
item.setChecked (true);
SAVING_INTERVAL=24L*1000*60*60*3;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («SAVING_INTERVAL», SAVING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_data_4_day) {
item.setChecked (true);
SAVING_INTERVAL=24L*1000*60*60*4;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («SAVING_INTERVAL», SAVING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_data_5_day) {
item.setChecked (true);
SAVING_INTERVAL=24L*1000*60*60*5;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («SAVING_INTERVAL», SAVING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_data_6_day) {
item.setChecked (true);
SAVING_INTERVAL=24L*1000*60*60*6;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («SAVING_INTERVAL», SAVING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_data_7_day) {
item.setChecked (true);
SAVING_INTERVAL=24L*1000*60*60*7;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («SAVING_INTERVAL», SAVING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_data_14_day) {
item.setChecked (true);
SAVING_INTERVAL=24L*1000*60*60*14;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («SAVING_INTERVAL», SAVING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_data_30_day) {
item.setChecked (true);
SAVING_INTERVAL=24L*1000*60*60*30;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («SAVING_INTERVAL», SAVING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_1_minute) {
item.setChecked (true);
TRACKING_INTERVAL=1L*1000*60;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («TRACKING_INTERVAL», TRACKING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_5_minute) {
item.setChecked (true);
TRACKING_INTERVAL=5L*1000*60;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («TRACKING_INTERVAL», TRACKING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_10_minute) {
item.setChecked (true);
TRACKING_INTERVAL=10L*1000*60;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («TRACKING_INTERVAL», TRACKING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_15_minute) {
item.setChecked (true);
TRACKING_INTERVAL=15L*1000*60;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («TRACKING_INTERVAL», TRACKING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_30_minute) {
item.setChecked (true);
TRACKING_INTERVAL=30L*1000*60;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («TRACKING_INTERVAL», TRACKING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_60_minute) {
item.setChecked (true);
TRACKING_INTERVAL=60L*1000*60;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («TRACKING_INTERVAL», TRACKING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_240_minute) {
item.setChecked (true);
TRACKING_INTERVAL=240L*1000*60;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («TRACKING_INTERVAL», TRACKING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_720_minute) {
item.setChecked (true);
TRACKING_INTERVAL=720L*1000*60;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («TRACKING_INTERVAL», TRACKING_INTERVAL);
editor.commit ();
return true;
}
if (id == R.id.action_1440_minute) {
item.setChecked (true);
TRACKING_INTERVAL=1440L*1000*60;
SharedPreferences. Editor editor = mSettings. edit ();
editor. putLong («TRACKING_INTERVAL», TRACKING_INTERVAL);
editor.commit ();
return true;
}
return super. onOptionsItemSelected (item);
}
@SuppressWarnings («StatementWithEmptyBody»)
@Override
public boolean onNavigationItemSelected (MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId ();
if (id == R.id.nav_start_tracking) {
Boolean start=mSettings.getBoolean («APP_PREFERENCES_START_ALARM», false);
if (start==false) {
long interval = mSettings.getLong («TRACKING_INTERVAL», 15L * 1000 * 60);
StartAlarmIntentService.startActionAlarm (context, interval);
SharedPreferences. Editor editor = mSettings. edit ();
editor. putBoolean («APP_PREFERENCES_START_ALARM», true);
editor.commit ();
View view = (View) findViewById(R.id.content);
Snackbar snack = Snackbar.make (view, «Tracking started with " + interval / (1000 * 60) + " minutes interval», Snackbar. LENGTH_LONG);
View snackbarView = snack.getView ();
snackbarView.setBackgroundColor(Color.parseColor («#e1da21»));
TextView tv = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
tv.setGravity (Gravity. CENTER);
snack.setAction («Action», null).show ();
} else {
long interval = mSettings.getLong («TRACKING_INTERVAL», 15L * 1000 * 60);
View view = (View) findViewById(R.id.content);
Snackbar snack = Snackbar.make (view, «Tracking is already working with " + interval / (1000 * 60) + " minutes interval», Snackbar. LENGTH_LONG);
View snackbarView = snack.getView ();
snackbarView.setBackgroundColor(Color.parseColor («#e1da21»));
TextView tv = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
tv.setGravity (Gravity. CENTER);
snack.setAction («Action», null).show ();
}
} else if (id == R.id.nav_stop_tracking) {
Intent intent = new Intent (getApplicationContext (), LocationReceiver.class);
final PendingIntent pIntent = PendingIntent.getBroadcast (getApplicationContext (), LocationReceiver.REQUEST_CODE, intent, PendingIntent. FLAG_CANCEL_CURRENT);
AlarmManager alarm = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarm.cancel (pIntent);
SharedPreferences. Editor editor = mSettings. edit ();
editor. putBoolean («APP_PREFERENCES_START_ALARM», false);
editor.commit ();
View view= (View) findViewById(R.id.content);
Snackbar snack = Snackbar.make (view, «Tracking has stopped», Snackbar. LENGTH_LONG);
View snackbarView = snack.getView ();
snackbarView.setBackgroundColor(Color.parseColor («#e1da21»));
TextView tv = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
tv.setGravity (Gravity. CENTER);
snack.setAction («Action», null).show ();
} else if (id == R.id.nav_clear_data) {
LocationDBHelper dbhelper=LocationDBHelper.getInstance (context);
dbhelper.clearLocation ();
View view= (View) findViewById(R.id.content);
Snackbar snack = Snackbar.make (view, «Location data removed», Snackbar. LENGTH_LONG);
View snackbarView = snack.getView ();
snackbarView.setBackgroundColor(Color.parseColor («#e1da21»));
TextView tv = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
tv.setGravity (Gravity. CENTER);
snack.setAction («Action», null).show ();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
@Override
protected void onStop () {
mGoogleDriveApiClient. disconnect ();
this.finish ();
super. onStop ();
}
@Override
public void onConnected (Bundle bundle) {
if (mSettings.contains («TRACKING_FILE»)) {
String fileID = mSettings.getString («TRACKING_FILE», «»);
DriveId sFileId = DriveId.decodeFromString (fileID);
DriveResource file = Drive.DriveApi.getFile (mGoogleDriveApiClient, sFileId);
file.getMetadata(mGoogleDriveApiClient).setResultCallback (new ResultCallback<DriveResource.MetadataResult> () {
@Override
public void onResult(DriveResource.MetadataResult result) {
if (!result.getStatus().isSuccess ()) {
createFile ();
} else {
if(result.getMetadata().isTrashed ()) {
createFile ();
}
}
}
});
} else {
createFile ();
}
}
private void createFile () {
MetadataChangeSet changeSet = new MetadataChangeSet. Builder ()
.setTitle («BabyTracking»).build ();
Drive.DriveApi.getRootFolder(mGoogleDriveApiClient).createFolder (
mGoogleDriveApiClient, changeSet).setResultCallback (new ResultCallback <DriveFolder. DriveFolderResult> () {
@Override
public void onResult (DriveFolder. DriveFolderResult result_) {
final DriveFolder. DriveFolderResult result = result_;
if (!result.getStatus().isSuccess ()) {
return;
}
String folderID = result.getDriveFolder().getDriveId().toString ();
SharedPreferences. Editor editor = mSettings. edit ();
editor. putString («TRACKING_FOLDER», folderID);
editor.commit ();
Toast.makeText (getApplicationContext (), «Folder BabyTracking created», Toast.LENGTH_LONG).show ();
DriveFolder folder = result.getDriveFolder ();
MetadataChangeSet changeSet = new MetadataChangeSet. Builder ()
.setTitle («Tracking»)
.setMimeType («text/plain»).build ();
folder.createFile (mGoogleDriveApiClient, changeSet, null)
.setResultCallback (new ResultCallback <DriveFolder. DriveFileResult> () {
@Override
public void onResult (DriveFolder. DriveFileResult result_) {
final DriveFolder. DriveFileResult result = result_;
if (!result.getStatus().isSuccess ()) {
return;
}
String fileID = result.getDriveFile().getDriveId().toString ();
SharedPreferences. Editor editor = mSettings. edit ();
editor. putString («TRACKING_FILE», fileID);
editor.commit ();
Toast.makeText (getApplicationContext (), «File Tracking created», Toast.LENGTH_LONG).show ();
}
});
}
});
}
@Override
public void onConnectionSuspended (int i) {
}
@Override
public void onConnectionFailed (ConnectionResult connectionResult) {
if (connectionResult. hasResolution ()) {
try {
connectionResult.startResolutionForResult (this, RESOLVE_CONNECTION_REQUEST_CODE);
} catch (IntentSender.SendIntentException e) {
}
} else {
GooglePlayServicesUtil.getErrorDialog(connectionResult.getErrorCode (), this, 0).show ();
}
}
@Override
protected void onActivityResult (final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case RESOLVE_CONNECTION_REQUEST_CODE:
if (resultCode == RESULT_OK) {
mGoogleDriveApiClient.connect ();
}
break;
}
}
@Override
public void onStart () {
super. onStart ();
mGoogleDriveApiClient.connect ();
}
public static class LoginDialogFragment extends DialogFragment {
private View view;
private AlertDialog alert;
private SharedPreferences mSettings;
@Override
public Dialog onCreateDialog (Bundle savedInstanceState) {
AlertDialog. Builder builder = new AlertDialog. Builder (getActivity ());
LayoutInflater inflater = getActivity().getLayoutInflater ();
view = (View) inflater.inflate(R.layout. dialog_login, null);
builder.setView (view)
// Add action buttons
.setPositiveButton(R.string. button_submit, new DialogInterface. OnClickListener () {
@Override
public void onClick (DialogInterface dialog, int id) {
}
})
.setNegativeButton(R.string. button_cancel, new DialogInterface. OnClickListener () {
public void onClick (DialogInterface dialog, int id) {
LoginDialogFragment.this.getDialog().cancel ();
}
});
alert = builder.create ();
alert.setOnShowListener (new DialogInterface. OnShowListener () {
@Override
public void onShow (DialogInterface dialog) {
Button btnPositive = alert.getButton (Dialog. BUTTON_POSITIVE);
btnPositive.setTextSize(TypedValue.COMPLEX_UNIT_PX, 25.0f);
btnPositive.setTextColor(Color.parseColor («#e1da21»));
btnPositive.setGravity (Gravity. CENTER);
Button btnNegative = alert.getButton (Dialog. BUTTON_NEGATIVE);
btnNegative.setTextSize(TypedValue.COMPLEX_UNIT_PX, 25.0f);
btnNegative.setTextColor(Color.parseColor («#e1da21»));
btnNegative.setGravity (Gravity. CENTER);
}
});
return alert;
}
@Override
public void onStart () {
super. onStart ();
alert.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener (new View. OnClickListener () {
@Override
public void onClick (View v) {
Boolean wantToCloseDialog = false;
EditText login = (EditText) view.findViewById(R.id.dialog_username);
EditText password = (EditText) view.findViewById(R.id.dialog_password);
if ((login. length ()!= 0) && (password. length ()!= 0)) {
mSettings = getContext().getSharedPreferences («APP_PREFERENCES», Context.MODE_PRIVATE);
SharedPreferences. Editor editor = mSettings. edit ();
editor. putString («APP_PREFERENCES_LOGIN», login.getText().toString ());
editor. putString («APP_PREFERENCES_PASSWORD», login.getText().toString ());
editor.commit ();
wantToCloseDialog=true;
} else {
Toast.makeText (getContext (), «The login or password is empty», Toast.LENGTH_LONG).show ();
}
if (wantToCloseDialog)
alert. dismiss ();
}
});
}
}
}
Файл компоновки activity_main:
<?xml version=«1.0» encoding=«utf-8»? >
http://schemas.android.com/apk/res/android"pport. v4.widget. DrawerLayout xmlns: android="<android.su
xmlns: app="http://schemas.android.com/apk/res-auto"
xmlns: tools="http://schemas.android.com/tools" android: id="@+id/drawer_layout»
android: layout_width=«match_parent» android: layout_height=«match_parent»
android: fitsSystemWindows=«true» tools: openDrawer=«start»>
<include layout="@layout/app_bar_main»
android: layout_width=«match_parent»
android: layout_height=«match_parent» />
<android.support.design.widget.NavigationView
android: id="@+id/nav_view»
android: layout_width=«wrap_content»
android: layout_height=«wrap_content»
android: layout_gravity=«start»
android: fitsSystemWindows=«true»
app: headerLayout="@layout/nav_header_main»
app: menu="@menu/activity_main_drawer»
app: itemTextColor="@color/item_drawer»
android: theme="@style/NavigationViewStyle»
/>
</android.support. v4.widget. DrawerLayout>
Файл компоновки app_bar_main:
<?xml version=«1.0» encoding=«utf-8»? >
<android.support.design.widget.CoordinatorLayout
xmlns: android="http://schemas.android.com/apk/res/android"
xmlns: app="http://schemas.android.com/apk/res-auto"
xmlns: tools="http://schemas.android.com/tools" android: layout_width=«match_parent»
android: layout_height=«match_parent» android: fitsSystemWindows=«true»
tools:context=".MainActivity»>
<android.support.design. widget. AppBarLayout android: layout_height=«wrap_content»
android: layout_width=«match_parent» android: theme="@style/AppTheme. AppBarOverlay»>
<android.support.v7.widget.Toolbar android: id="@+id/toolbar»
android: layout_width=«match_parent»
android: layout_height=»? attr/actionBarSize»
android: background=»? attr/colorPrimary»
app: popupTheme="@style/AppTheme. PopupOverlay»
app: layout_scrollFlags=«scroll|enterAlways»
/>
</android.support.design. widget. AppBarLayout>
<android.support.v4.widget.NestedScrollView
xmlns: android="http://schemas.android.com/apk/res/android"
xmlns: app="http://schemas.android.com/apk/res-auto"
xmlns: tools="http://schemas.android.com/tools"
android: layout_width=«wrap_content»
android: layout_height=«wrap_content»
android: paddingLeft="@dimen/activity_horizontal_margin»
android: paddingRight="@dimen/activity_horizontal_margin»
android: paddingTop="@dimen/activity_vertical_margin»
android: paddingBottom="@dimen/activity_vertical_margin»
android: fillViewport=«true»
android: layout_gravity=«fill_vertical»
app: layout_behavior="@string/appbar_scrolling_view_behavior»
tools:context=".MainActivity»
tools: showIn="@layout/app_bar_main»
>
<RelativeLayout
android: layout_width=«wrap_content»
android: layout_height=«wrap_content»
>
<com.google.android.gms.ads.AdView
android: id="@+id/adViewBan»
android: layout_width=«wrap_content»
android: layout_height=«wrap_content»
xmlns: ads="http://schemas.android.com/apk/res-auto"
ads: adSize=«BANNER»
ads: adUnitId="@string/banner_ad_unit_id»
android: layout_alignParentTop=«true»
android: layout_centerHorizontal=«true»>
</com.google.android.gms.ads.AdView>
<RelativeLayout
android: layout_width=«wrap_content»
android: layout_height=«wrap_content»
android: layout_below="@+id/adViewBan»
android: id="@+id/content»
>
<TextView android: text=«Start Tracking!»
android: layout_width=«wrap_content»
android: layout_height=«wrap_content»
android:textAppearance="@style/Base.TextAppearance.AppCompat.Large»
android: gravity=«right»
android: textColor=«#261860»
android: textStyle=«bold»
android: paddingLeft="@dimen/activity_horizontal_margin»
/>
</RelativeLayout>
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>
<android.support.design. widget. FloatingActionButton
android: id="@+id/fab»
android: layout_width=«wrap_content»
android: layout_height=«wrap_content»
android: layout_gravity=«bottom|end»
android: layout_margin="@dimen/fab_margin»
android: src="@android: drawable/ic_input_add»
app:layout_behavior="com.tmsoftstudio.babytracking.ScrollFABBehavior»
app: layout_anchorGravity=«bottom|center»
app: layout_anchor="@id/content»
/>
</android.support.design.widget.CoordinatorLayout>
Файл компоновки заголовка навигационной панели:
<?xml version=«1.0» encoding=«utf-8»? >
<LinearLayout xmlns: android="http://schemas.android.com/apk/res/android"
android: layout_width=«match_parent»
android: layout_height=«wrap_content»
android: background="@drawable/side_nav_bar»
android: paddingBottom="@dimen/activity_vertical_margin»
android: paddingLeft="@dimen/activity_horizontal_margin»
android: paddingRight="@dimen/activity_horizontal_margin»
android: paddingTop="@dimen/activity_vertical_margin»
android: theme="@style/ThemeOverlay. AppCompat. Dark»
android: orientation=«vertical»
android: gravity=«bottom»>
<ImageView
android: layout_width=«wrap_content»
android: layout_height=«100dp»
android: src="@drawable/logotracking»
android: id="@+id/imageView»
/>
<TextView android: layout_width=«match_parent»
android: layout_height=«wrap_content»
android: text=«Baby Tracking»
android:textAppearance="@style/Base.TextAppearance.AppCompat.Large»
android: gravity=«center»
android: textColor=«#261860»
android: textStyle=«bold»
/>
</LinearLayout>
В методе onCreate активности создается и включается объект GoogleApiClient, обеспечивающий доступ к облачному хранению Google Drive.
При первой загрузке приложения открывается диалоговое окно, предлагающее выбрать аккаунт для авторизации доступа к сервису Google Drive. После успешной авторизации – для этого также нужно зарегистрировать для проекта OAuth 2.0 client ID – создается папка и файл в Google Drive для хранения данных трекинга.
Кнопка FloatingActionButton запускает сервис StartAlarmIntentService, который в свою очередь запускает сервис оповещений с установленной периодичностью:
import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.Context;
public class StartAlarmIntentService extends IntentService {
static final String ACTION_START_ALARM = "com.tmsoftstudio.babytracking.action.START_ALARM»;
static final String EXTRA_PARAM_INTERVAL = "com.tmsoftstudio.babytracking.extra.PARAM_INTERVAL»;
static final String ACTION_START_ALARM_BOOT = "com.tmsoftstudio.babytracking.action.START_ALARM_BOOT»;
public static void startActionAlarm (Context context, long param) {
Intent intent = new Intent (context, StartAlarmIntentService.class);
intent.setAction (ACTION_START_ALARM);
intent. putExtra (EXTRA_PARAM_INTERVAL, param);
context.startService (intent);
}
public StartAlarmIntentService () {
super («StartAlarmIntentService»);
}
@Override
protected void onHandleIntent (Intent intent) {
if (intent!= null) {
final String action = intent.getAction ();
if (ACTION_START_ALARM. equals (action)) {
final long param = intent.getLongExtra (EXTRA_PARAM_INTERVAL, 15L*1000*60);
if (param!=0) {
startAlarm (param);
this.stopSelf ();
}
}
if (ACTION_START_ALARM_BOOT. equals (action)) {
final long param = intent.getLongExtra (EXTRA_PARAM_INTERVAL, 15L*1000*60);
if (param!=0) {
startAlarm (param);
BootReceiver.completeWakefulIntent (intent);
this.stopSelf ();
}
}
}
}
public void startAlarm (long interval) {
Intent intent = new Intent (getApplicationContext (), LocationReceiver.class);
final PendingIntent pIntent = PendingIntent.getBroadcast (getApplicationContext (), LocationReceiver.REQUEST_CODE, intent, PendingIntent. FLAG_CANCEL_CURRENT);
long firstMillis = System.currentTimeMillis ();
AlarmManager alarm = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
// alarm.setInexactRepeating (AlarmManager. RTC_WAKEUP, firstMillis, interval, pIntent);
alarm.setRepeating (AlarmManager. RTC_WAKEUP, firstMillis, interval, pIntent);
}
}
Сервис оповещений с установленной периодичностью запускает приемник LocationReceiver, запускающий сервис LocationIntentService сбора и сохранения дислокации:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class LocationReceiver extends BroadcastReceiver {
public static final int REQUEST_CODE = 1;
public LocationReceiver () {
}
@Override
public void onReceive (Context context, Intent intent) {
Intent i = new Intent (context, LocationIntentService.class);
context.startService (i);
}
}
При перезагрузке устройства и ранее запущенном трекинге, сервис StartAlarmIntentService запускается автоматически с помощью приемника BootReceiver:
import android.content.SharedPreferences;
import android.support.v4.content. WakefulBroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class BootReceiver extends WakefulBroadcastReceiver {
private SharedPreferences mSettings;
public BootReceiver () {
}
@Override
public void onReceive (Context context, Intent intent) {
mSettings = context.getSharedPreferences («APP_PREFERENCES», Context.MODE_PRIVATE);
if(mSettings.contains («APP_PREFERENCES_START_ALARM»)) {
Boolean start = mSettings.getBoolean («APP_PREFERENCES_START_ALARM», false);
if (start == true) {
Intent service = new Intent (context, StartAlarmIntentService.class);
service.setAction(StartAlarmIntentService.ACTION_START_ALARM_BOOT);
long interval=mSettings.getLong («TRACKING_INTERVAL», 15L*1000*60);
service. putExtra (StartAlarmIntentService. EXTRA_PARAM_INTERVAL, interval);
startWakefulService (context, service);
}
}
}
}
При запуске сервис LocationIntentService создает и включает два объекта GoogleApiClient – один для доступа к сервису локации LocationServices, а другой для доступа к сервису Google Drive.
При соединении с сервисом локации LocationServices инициируется обновление информации о местоположении, которая записывается в базу данных приложения с помощью объектов LocationDB и LocationDBHelper:
public class LocationDB {
public String date;
public double latitude;
public double longitude;
}
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android. database. sqlite. SQLiteDatabase;
import android. database. sqlite. SQLiteOpenHelper;
import java.util.ArrayList;
import java.util.List;
public class LocationDBHelper extends SQLiteOpenHelper {
private static LocationDBHelper ourInstance;
private static final String DATABASE_NAME = «locationDatabase»;
private static final int DATABASE_VERSION = 1;
private static final String TABLE_LOCATION = «location»;
private static final String KEY_LOCATION_ID = «id»;
private static final String KEY_LOCATION_DATE = «date»;
private static final String KEY_LOCATION_LATITUDE = «latitude»;
private static final String KEY_LOCATION_LONGITUDE = «longitude»;
public static LocationDBHelper getInstance (Context context) {
if (ourInstance == null) {
ourInstance = new LocationDBHelper(context.getApplicationContext ());
}
return ourInstance;
}
private LocationDBHelper (Context context) {
super (context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate (SQLiteDatabase db) {
String CREATE_LOCATION_TABLE = «CREATE TABLE " + TABLE_LOCATION +
«(» +
KEY_LOCATION_ID + " INTEGER PRIMARY KEY,» +
KEY_LOCATION_DATE + " TEXT,» +
KEY_LOCATION_LATITUDE + " DOUBLE,» +
KEY_LOCATION_LONGITUDE + " DOUBLE)»;
db. execSQL (CREATE_LOCATION_TABLE);
}
@Override
public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion!= newVersion) {
db. execSQL («DROP TABLE IF EXISTS " + TABLE_LOCATION);
onCreate (db);
}
}
public void addLocation (LocationDB locationDB) {
SQLiteDatabase db = getWritableDatabase ();
db.beginTransaction ();
try {
ContentValues values = new ContentValues ();
values. put (KEY_LOCATION_DATE, locationDB. date);
values. put (KEY_LOCATION_LATITUDE, locationDB.latitude);
values. put (KEY_LOCATION_LONGITUDE, locationDB. longitude);
db.insertOrThrow (TABLE_LOCATION, null, values);
db.setTransactionSuccessful ();
} catch (Exception e) {
} finally {
db. endTransaction ();
}
}
public void clearLocation () {
SQLiteDatabase db = getWritableDatabase ();
db. execSQL («DROP TABLE IF EXISTS " + TABLE_LOCATION);
onCreate (db);
}
public List <LocationDB> getLocations () {
List <LocationDB> locations = new ArrayList <> ();
String LOCATION_SELECT_QUERY = «SELECT * FROM " + TABLE_LOCATION;
SQLiteDatabase db = getReadableDatabase ();
Cursor cursor = db. rawQuery (LOCATION_SELECT_QUERY, null);
try {
if (cursor.moveToFirst ()) {
do {
LocationDB locationDB = new LocationDB ();
locationDB. date = cursor.getString(cursor.getColumnIndex (KEY_LOCATION_DATE));
locationDB.latitude = cursor.getDouble(cursor.getColumnIndex (KEY_LOCATION_LATITUDE));
locationDB. longitude = cursor.getDouble(cursor.getColumnIndex (KEY_LOCATION_LONGITUDE));
locations.add (locationDB);
} while(cursor.moveToNext ());
}
} catch (Exception e) {
} finally {
if (cursor!= null && !cursor.isClosed ()) {
cursor.close ();
}
}
return locations;
}
}
При превышении заранее установленного размера базы данных, она автоматически стирается и запись информации начинается заново.
После записи информации сервис LocationIntentService автоматически останавливается.
Правообладателям!
Это произведение, предположительно, находится в статусе 'public domain'. Если это не так и размещение материала нарушает чьи-либо права, то сообщите нам об этом.