package ru.perm.trubnikov.gps2sms;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.database.Cursor;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.telephony.SmsManager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Locale;
public class MainActivity extends BaseActivity {
// Menu
public static final int IDM_SETTINGS = 101;
public static final int IDM_RATE = 105;
public static final int IDM_DONATE = 106;
public static final int IDM_CONVERTER = 107;
// Activities
private static final int ACT_RESULT_CHOOSE_CONTACT = 1001;
private static final int ACT_RESULT_SETTINGS = 1002;
private static final int ACT_RESULT_FAV = 1003;
private static final int ACT_RESULT_REPO = 1004;
// Dialogs
private static final int SEND_SMS_DIALOG_ID = 0;
private final static int SAVE_POINT_DIALOG_ID = 1;
ProgressDialog mSMSProgressDialog;
// My GPS states
public static final int GPS_PROVIDER_DISABLED = 1;
public static final int GPS_GETTING_COORDINATES = 2;
public static final int GPS_GOT_COORDINATES = 3;
//public static final int GPS_PROVIDER_UNAVIALABLE = 4;
//public static final int GPS_PROVIDER_OUT_OF_SERVICE = 5;
public static final int GPS_PAUSE_SCANNING = 6;
public static final int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1001;
// Location manager
private LocationManager manager;
// SMS thread
ThreadSendSMS mThreadSendSMS;
// Views
ImageButton chooseContactBtn;
ImageButton sendpbtn;
ImageButton btnShare;
ImageButton btnMap;
ImageButton btnCopy;
ImageButton btnSave;
ImageButton btnFav;
EditText plainPh;
Button enableGPSBtn;
TextView GPSstate;
Menu mMenu;
// Globals
private String coordsToSend;
private String gAccuracy;
private String phoneToSendSMS;
ColorStateList gGpsStateColorDefault;
// Database
DBHelper dbHelper;
// SMS send thread. Result handling
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
String res_send = msg.getData().getString("res_send");
dismissDialog(SEND_SMS_DIALOG_ID);
DBHelper.ShowToastT(MainActivity.this, res_send,
Toast.LENGTH_SHORT);
}
};
// Location events (we use GPS only)
private LocationListener locListener = new LocationListener() {
public void onLocationChanged(Location argLocation) {
printLocation(argLocation, GPS_GOT_COORDINATES);
}
@Override
public void onProviderDisabled(String arg0) {
printLocation(null, GPS_PROVIDER_DISABLED);
}
@Override
public void onProviderEnabled(String arg0) {
}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
}
};
private void printLocation(Location loc, int state) {
switch (state) {
case GPS_PROVIDER_DISABLED:
GPSstate.setText(R.string.gps_state_disabled);
setGPSStateAccentColor();
enableGPSBtn.setVisibility(View.VISIBLE);
break;
case GPS_GETTING_COORDINATES:
GPSstate.setText(R.string.gps_state_in_progress);
setGPSStateNormalColor();
enableGPSBtn.setVisibility(View.INVISIBLE);
break;
case GPS_PAUSE_SCANNING:
GPSstate.setText("");
enableGPSBtn.setVisibility(View.INVISIBLE);
break;
case GPS_GOT_COORDINATES:
if (loc != null) {
// Accuracy
if (loc.getAccuracy() < 0.0001) {
gAccuracy = "?";
} else if (loc.getAccuracy() > 99) {
gAccuracy = "> 99";
} else {
gAccuracy = String.format(Locale.US, "%2.0f",
loc.getAccuracy());
}
String separ = System.getProperty("line.separator");
String la = String
.format(Locale.US, "%2.7f", loc.getLatitude());
String lo = String.format(Locale.US, "%3.7f",
loc.getLongitude());
coordsToSend = la + "," + lo;
GPSstate.setText(getString(R.string.info_print1) + ": "
+ gAccuracy + " " + getString(R.string.info_print2)
+ separ + getString(R.string.info_latitude) + ": " + la
+ separ + getString(R.string.info_longitude) + ": " + lo);
setGPSStateNormalColor();
btnShare.setVisibility(View.VISIBLE);
btnCopy.setVisibility(View.VISIBLE);
btnMap.setVisibility(View.VISIBLE);
btnSave.setVisibility(View.VISIBLE);
btnFav.setVisibility(View.VISIBLE);
ShowSendButton();
enableGPSBtn.setVisibility(View.INVISIBLE);
} else {
GPSstate.setText(R.string.gps_state_unavialable);
setGPSStateAccentColor();
enableGPSBtn.setVisibility(View.VISIBLE);
}
break;
}
}
// Menu
@Override
public boolean onCreateOptionsMenu(Menu menu) {
mMenu = menu;
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
menu.add(Menu.NONE, IDM_CONVERTER, Menu.NONE, R.string.menu_converter);
menu.add(Menu.NONE, IDM_SETTINGS, Menu.NONE,
R.string.menu_item_settings);
menu.add(Menu.NONE, IDM_RATE, Menu.NONE, R.string.menu_item_rate);
menu.add(Menu.NONE, IDM_DONATE, Menu.NONE, R.string.menu_item_donate);
return (super.onCreateOptionsMenu(menu));
}
// Dialogs
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case SEND_SMS_DIALOG_ID:
mSMSProgressDialog = new ProgressDialog(MainActivity.this);
// mCatProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mSMSProgressDialog.setCanceledOnTouchOutside(false);
mSMSProgressDialog.setCancelable(false);
mSMSProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mSMSProgressDialog.setMessage(getString(R.string.info_please_wait)
+ " " + phoneToSendSMS);
return mSMSProgressDialog;
case SAVE_POINT_DIALOG_ID:
LayoutInflater inflater_sp = getLayoutInflater();
View layout_sp = inflater_sp.inflate(R.layout.repo_save_point_dialog,
(ViewGroup) findViewById(R.id.repo_save_point_dialog_layout));
AlertDialog.Builder builder_sp = new AlertDialog.Builder(this);
builder_sp.setView(layout_sp);
final EditText lPointName = (EditText) layout_sp
.findViewById(R.id.point_edit_text);
builder_sp.setPositiveButton(getString(R.string.save_btn_txt),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dbHelper = new DBHelper(MainActivity.this);
dbHelper.insertMyCoord(lPointName.getText()
.toString(), coordsToSend);
dbHelper.close();
lPointName.setText(""); // Чистим
DBHelper.ShowToast(MainActivity.this,
R.string.point_saved, Toast.LENGTH_LONG);
}
});
builder_sp.setNegativeButton(getString(R.string.cancel_btn_txt),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
lPointName.setText(""); // Чистим
dialog.cancel();
}
});
builder_sp.setCancelable(true);
AlertDialog dialog = builder_sp.create();
dialog.setTitle(getString(R.string.save_point_dlg_header));
// show keyboard automatically
dialog.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
return dialog;
}
return null;
}
// Menu
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case IDM_SETTINGS:
Intent sett_intent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
sett_intent = new Intent(this, PreferencesActivity.class);
} else {
sett_intent = new Intent(this, PreferencesLegacyActivity.class);
}
startActivityForResult(sett_intent, ACT_RESULT_SETTINGS);
break;
case R.id.action_sms_regexp:
Intent repo_intent = new Intent(this, SlideTabsActivity.class);
startActivityForResult(repo_intent, ACT_RESULT_REPO);
break;
case IDM_DONATE:
Intent donate_intent = new Intent(this, DonateActivity.class);
startActivity(donate_intent);
break;
case IDM_CONVERTER:
Intent converter_intent = new Intent(this, ConverterActivity.class);
startActivity(converter_intent);
break;
case IDM_RATE:
Intent int_rate = new Intent(Intent.ACTION_VIEW,
Uri.parse("market://details?id="
+ getApplicationContext().getPackageName()));
int_rate.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
getApplicationContext().startActivity(int_rate);
} catch (Exception e) {
}
break;
default:
return false;
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED
&& grantResults[2] == PackageManager.PERMISSION_GRANTED
&& grantResults[3] == PackageManager.PERMISSION_GRANTED
&& grantResults[4] == PackageManager.PERMISSION_GRANTED) {
this.startLocation();
} else {
// permission denied
DBHelper.ShowToast(MainActivity.this, R.string.text_insufficient_privileges, Toast.LENGTH_LONG);
finish();
}
return;
}
}
}
private void stopLocation() {
try {
manager.removeUpdates(locListener);
} catch (SecurityException e) {
}
}
private void startLocation() {
// Возобновляем работу с GPS-приемником
try {
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener);
btnShare.setVisibility(View.INVISIBLE);
btnCopy.setVisibility(View.INVISIBLE);
btnMap.setVisibility(View.INVISIBLE);
btnSave.setVisibility(View.INVISIBLE);
btnFav.setVisibility(View.INVISIBLE);
HideSendButton();
if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
printLocation(null, GPS_GETTING_COORDINATES);
}
} catch (SecurityException e) {
}
}
@Override
protected void onResume() {
super.onResume();
// Держать ли экран включенным?
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
if (sharedPrefs.getBoolean("prefKeepScreen", true)) {
getWindow()
.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
} else {
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
// For Android 6.0 ask for permissions in runtime
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (GpsHelper.canAccessLocation(MainActivity.this))
this.startLocation();
} else
this.startLocation();
}
@Override
protected void onPause() {
super.onPause();
// For Android 6.0 ask for permissions in runtime
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (GpsHelper.canAccessLocation(MainActivity.this))
this.stopLocation();
} else
this.stopLocation();
}
public void showSelectedNumber(String number) {
plainPh.setText(number);
plainPh.setSelection(plainPh.getText().length());
}
@Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
switch (reqCode) {
case (ACT_RESULT_CHOOSE_CONTACT):
String number;
String name;
// int type = 0;
if (data != null) {
Uri uri = data.getData();
if (uri != null) {
Cursor c = null;
try {
c = getContentResolver()
.query(uri,
new String[]{
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME},
null, null, null);
if (c != null && c.moveToFirst()) {
number = c.getString(0);
number = number.replace("-", "").replace(" ", "")
.replace("(", "").replace(")", "").replace(".", "");
// type = c.getInt(1);
name = c.getString(2);
showSelectedNumber(number);
// update saved number
dbHelper = new DBHelper(MainActivity.this);
dbHelper.setSlot(0, name, number);
dbHelper.close();
}
} finally {
if (c != null) {
c.close();
}
}
}
}
break;
case ACT_RESULT_SETTINGS:
DBHelper.updateFavIcon(MainActivity.this, btnFav);
restartApp();
break;
case ACT_RESULT_FAV:
DBHelper.updateFavIcon(MainActivity.this, btnFav);
break;
case ACT_RESULT_REPO:
DBHelper.updateFavIcon(MainActivity.this, btnFav);
break;
}
}
public void chooseContact(View v) {
Intent intent = new Intent(Intent.ACTION_PICK,
ContactsContract.Contacts.CONTENT_URI);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, ACT_RESULT_CHOOSE_CONTACT);
//IncomingSms.sendNotification(MainActivity.this, "56.5555555,56.7777777");
}
public void showGpsSystemDialog(View v) {
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
startActivity(new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
}
public void copyToClipboard(View v) {
GpsHelper.clipboardCopy(getApplicationContext(), coordsToSend);
DBHelper.ShowToast(MainActivity.this, R.string.text_copied, Toast.LENGTH_LONG);
}
public void openOnMap(View v) {
GpsHelper.openOnMap(getApplicationContext(), coordsToSend);
}
public void saveCoordinates(View v) {
showDialog(SAVE_POINT_DIALOG_ID);
}
public void chooseFavApp(View v) {
if (!DBHelper.shareFav(MainActivity.this, GpsHelper.getShareBody(MainActivity.this, coordsToSend, gAccuracy))) {
Intent intent = new Intent(MainActivity.this, ChooseFavActivity.class);
startActivityForResult(intent, ACT_RESULT_FAV);
}
}
// ------------------------------------------------------------------------------------------
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Setting up app language. This code MUST BE placed BEFORE setContentView!
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
String languageToLoad = sharedPrefs.getString("prefLang", "");
if (!languageToLoad.equalsIgnoreCase("")) {
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
}
// EOF Setting up app language
setContentView(R.layout.activity_main);
// Plain phone number
plainPh = (EditText) findViewById(R.id.editText1);
plainPh.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String lPhone = ((EditText) v).getText().toString().replace("-", "")
.replace(" ", "").replace("(", "").replace(")", "").replace(".", "");
if (lPhone.length() >= 5) {
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(lPhone));
String[] projection = new String[]{"display_name"};
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
if (cursor.moveToFirst()) {
DBHelper.ShowToastT(MainActivity.this, cursor.getString(0),
Toast.LENGTH_SHORT);
}
cursor.close();
}
}
});
// Select contact
chooseContactBtn = (ImageButton) findViewById(R.id.choose_contact);
// Stored phone number -> to EditText
dbHelper = new DBHelper(this);
showSelectedNumber(dbHelper.getSlot(0, "phone"));
dbHelper.close();
// GPS init
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Enable GPS button
enableGPSBtn = (Button) findViewById(R.id.button3);
enableGPSBtn.setVisibility(View.INVISIBLE);
// Share buttons
btnShare = (ImageButton) findViewById(R.id.btnShare);
btnCopy = (ImageButton) findViewById(R.id.btnCopy);
btnMap = (ImageButton) findViewById(R.id.btnMap);
btnSave = (ImageButton) findViewById(R.id.btnSave);
btnFav = (ImageButton) findViewById(R.id.btnFav);
btnShare.setVisibility(View.INVISIBLE);
btnCopy.setVisibility(View.INVISIBLE);
btnMap.setVisibility(View.INVISIBLE);
btnSave.setVisibility(View.INVISIBLE);
btnFav.setVisibility(View.INVISIBLE);
btnFav.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
Intent intent = new Intent(MainActivity.this, ChooseFavActivity.class);
startActivityForResult(intent, ACT_RESULT_FAV);
return true;
}
});
btnShare.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
GpsHelper.shareCoordinates(MainActivity.this, GpsHelper.getShareBody(MainActivity.this, coordsToSend, gAccuracy));
}
});
// Send buttons
sendpbtn = (ImageButton) findViewById(R.id.send_plain);
HideSendButton();
// GPS-state TextView init
GPSstate = (TextView) findViewById(R.id.textView1);
gGpsStateColorDefault = GPSstate.getTextColors();
setGPSStateNormalColor();
DBHelper.updateFavIcon(MainActivity.this, btnFav);
// For Android 6.0 ask for All permissions in runtime
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.SEND_SMS,
android.Manifest.permission.RECEIVE_SMS,
android.Manifest.permission.READ_SMS,
android.Manifest.permission.READ_PHONE_STATE,
android.Manifest.permission.READ_CONTACTS
}, MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
}
private void setGPSStateNormalColor() {
GPSstate.setTextColor(gGpsStateColorDefault);
}
private void setGPSStateAccentColor() {
GPSstate.setTextColor(DBHelper.determineAccendcolor(MainActivity.this));
}
protected String handleSMSText(String lMsg) {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
String tBefore = sharedPrefs.getString("prefTextBefore", "");
String tAfter = sharedPrefs.getString("prefTextAfter", "");
if (!tBefore.equalsIgnoreCase("")) {
lMsg = tBefore + " " + lMsg;
}
if (!tAfter.equalsIgnoreCase("")) {
lMsg = lMsg +" "+ tAfter;
}
return lMsg;
}
// ------------------------------------------------------------------------------------------
public void sendSMS_Debug(String lMsg) {
phoneToSendSMS = plainPh.getText().toString().replace("-", "")
.replace(" ", "").replace("(", "").replace(")", "").replace(".", "");
if (phoneToSendSMS.equalsIgnoreCase("")) {
DBHelper.ShowToast(MainActivity.this,
R.string.error_no_phone_number, Toast.LENGTH_LONG);
} else {
try {
// update saved number
dbHelper = new DBHelper(MainActivity.this);
dbHelper.setSlot(0, "", phoneToSendSMS);
dbHelper.close();
SmsManager smsManager = SmsManager.getDefault();
ArrayList<String> parts = smsManager.divideMessage(lMsg);
smsManager.sendMultipartTextMessage(phoneToSendSMS, null, parts, null, null);
DBHelper.ShowToastT(MainActivity.this, getString(R.string.info_sms_sent),
Toast.LENGTH_SHORT);
} catch (Exception e) {
DBHelper.ShowToastT(MainActivity.this, e.getMessage(),
Toast.LENGTH_LONG);
}
}
}
protected void sendSMS(String lMsg) {
phoneToSendSMS = plainPh.getText().toString().replace("-", "")
.replace(" ", "").replace("(", "").replace(")", "").replace(".", "");
if (phoneToSendSMS.equalsIgnoreCase("")) {
DBHelper.ShowToast(MainActivity.this,
R.string.error_no_phone_number, Toast.LENGTH_LONG);
} else {
// update saved number
dbHelper = new DBHelper(MainActivity.this);
dbHelper.setSlot(0, "", phoneToSendSMS);
dbHelper.close();
showDialog(SEND_SMS_DIALOG_ID);
// Запускаем новый поток для отправки SMS
mThreadSendSMS = new ThreadSendSMS(handler, getApplicationContext());
mThreadSendSMS.setMsg(handleSMSText(lMsg));
mThreadSendSMS.setPhone(phoneToSendSMS);
mThreadSendSMS.setState(ThreadSendSMS.STATE_RUNNING);
mThreadSendSMS.start();
}
}
public void initiateSMSSend(View v) {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
sendSMS(GpsHelper.getLinkByProvType(sharedPrefs.getString("prefSMSContent", "2"), coordsToSend));
}
protected void ShowSendButton() {
sendpbtn.setVisibility(View.VISIBLE);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) plainPh.getLayoutParams();
params.addRule(RelativeLayout.LEFT_OF, R.id.send_plain);
plainPh.setLayoutParams(params); //causes layout update
}
protected void HideSendButton() {
sendpbtn.setVisibility(View.INVISIBLE);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) plainPh.getLayoutParams();
params.addRule(RelativeLayout.LEFT_OF, 0);
plainPh.setLayoutParams(params); //causes layout update
}
private void restartApp() {
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage(getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
/*
* TODO
*
* Автоматическая отправка координат через интервалы времени
* Функционал "найти мой телефон" по СМС
*
* Виджет
* Программа не видит координаты в смс, пример: клевое место N56°04,1747' E61°21,8289'
* В настройках в СМС добавить все типы координат
* Показывать все типы координат на главном экране?
*/
/*
* v3.4.9
* Запрос прав доступа во время выполнения для Android 6+
* Пересобрано с использованием обновленного инструментария
* Изменен значок хранилища координат
* В окне, подтверждающем отправку СМС, теперь отображается текст отосланной СМС и кнопка перехода в приложение, управляющее СМСками
* Конвертирование координат (отдельная опция меню)
* */
}