package com.wozia.nophonezone; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.util.ArrayList; import java.util.Date; import java.util.List; import com.google.i18n.phonenumbers.NumberParseException; import com.google.i18n.phonenumbers.PhoneNumberUtil; import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; import com.android.vending.licensing.LicenseChecker; import com.android.vending.licensing.LicenseCheckerCallback; import com.android.vending.licensing.ServerManagedPolicy; import com.android.vending.licensing.AESObfuscator; import android.app.AlertDialog; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.TabActivity; import android.location.Location; import android.location.LocationManager; import android.net.Uri; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.database.Cursor; import android.os.Bundle; import android.os.Handler; import android.provider.ContactsContract.PhoneLookup; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.Settings; import android.telephony.PhoneNumberUtils; import android.telephony.SmsManager; import android.telephony.TelephonyManager; //import android.util.Log; import android.widget.*; //-- TODO Known Bugs: none :D public class NoPhoneZone extends TabActivity { static DataHelper dh; private static String msgAdd_Address, msgAdd_Footer; static final int QUIT_APP = 5; static final int NOTIFY_APP = 15; static final String APP_VERSION = "1.3.0"; static Resources res = null; private PhoneReceiver PhoneR; private SMSReceiver SmsR; static Context context; @SuppressWarnings("unused") private LicenseCheckerCallback mLicenseCheckerCallback; private LicenseChecker mChecker; private static final String BASE64_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmyT5FFocrsMF8ixpsC0peGvHJaTr1ZL6JkwGykFjL03GcDJj4jkLw7Rpm2wOliTX3o5Th1G32E/8pg1alAV01FD8IzeE/oEsqTbLqF/3TcKqVe+72QsZ/+eG31vwj+cxVgxEnZsYbfS5BkPEA0V2IeIuQ8AXGsohAMMd/7bSC+IHAQfIeBvThbkmprpGt+JkNgW6oavyaxXuv5jUi2ZqYNE9K5jy4fhEfLRtJKCE9ndkJfd2pj+9nejMJ06iVPVio84TIqhb6N79JOOctIH90A7FZla4ufYCpa+0g5Obay7nd+pqg2Up2aO44xfjahZcevVtTQEQlq1/QaVUr+4M7QIDAQAB"; private static final byte[] SALT = new byte[] { 68, -46, 30, 118, -103, -13, 74, -64, 57, 88, -93, -45, 85, -117, -36, -113, -11, 22, -64, 19 }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final String deviceId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID); // Construct the LicenseCheckerCallback. The library calls this when done. mLicenseCheckerCallback = new MyLicenseCheckerCallback(); // Construct the LicenseChecker with a Policy. mChecker = new LicenseChecker(this, new ServerManagedPolicy(this, new AESObfuscator(SALT, getPackageName(), deviceId)), BASE64_PUBLIC_KEY ); res = getResources(); TabHost tabHost = getTabHost(); NoPhoneZone.context = getApplicationContext(); tabHost.addTab(tabHost.newTabSpec("about").setIndicator(res.getString(R.string.app_tab_title_about), res.getDrawable(R.drawable.ic_tab_about)).setContent(new Intent().setClass(this, AboutActivity.class))); tabHost.addTab(tabHost.newTabSpec("settings").setIndicator(res.getString(R.string.app_tab_title_settings), res.getDrawable(R.drawable.ic_tab_settings)).setContent(new Intent().setClass(this, SettingsActivity.class))); tabHost.addTab(tabHost.newTabSpec("sponsors").setIndicator(res.getString(R.string.app_tab_title_sponsors), res.getDrawable(R.drawable.ic_tab_sponsors)).setContent(new Intent().setClass(this, SponsorsActivity.class))); tabHost.addTab(tabHost.newTabSpec("credits").setIndicator(res.getString(R.string.app_tab_title_credits), res.getDrawable(R.drawable.ic_tab_credits)).setContent(new Intent().setClass(this, CreditsActivity.class))); tabHost.setCurrentTab(1); dh = new DataHelper(getApplicationContext()); msgAdd_Address = res.getString(R.string.nophonezone_msg_address); msgAdd_Footer = res.getString(R.string.nophonezone_msg_footer); AlertDialog disclaimer = new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setTitle(getString(R.string.nophonezone_disclaimer_title)).setMessage(getString(R.string.nophonezone_disclaimer_msg)).setPositiveButton(getString(R.string.ok), null).create(); long cDate = 0; Date date = new Date(); cDate = date.getTime(); String tmp = dh.get("disclaimer"); if (tmp.length() == 0) { dh.set("disclaimer", String.valueOf(cDate)); disclaimer.show(); } else { long oDate = Long.parseLong(tmp); long weekDiff = 1209600000;//604800000; if (cDate - oDate >= weekDiff) {// If Date is bigger than two weeks. dh.set("disclaimer", String.valueOf(cDate)); disclaimer.show(); } } Eula.show(this); } @Override public void onResume() { PhoneR = new PhoneReceiver(); registerReceiver(PhoneR, new IntentFilter("android.intent.action.PHONE_STATE")); SmsR = new SMSReceiver(); registerReceiver(SmsR, new IntentFilter("android.provider.Telephony.SMS_RECEIVED")); NotificationManager notifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); notifyManager.cancel(NOTIFY_APP); super.onResume(); } @Override public void onStop() { unregisterReceiver(PhoneR); unregisterReceiver(SmsR); NotificationManager notifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); Notification note = new Notification(R.drawable.icon, getString(R.string.nophonezone_notification_title), System.currentTimeMillis()); note.flags |= Notification.FLAG_ONGOING_EVENT; note.flags |= Notification.FLAG_NO_CLEAR; Intent intent = new Intent(this, NoPhoneZone.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pintent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); note.setLatestEventInfo(this, getString(R.string.nophonezone_notification_title), getString(R.string.nophonezone_notification_msg), pintent); notifyManager.notify(NOTIFY_APP, note); super.onStop(); } /** Useful functions **/ public static void sendMessage(Context context, String PhoneNumber) { SmsManager sm = SmsManager.getDefault(); //context = NoPhoneZone.context; String isContacts = dh.get("contacts_only"); String lessWarnings = dh.get("less_warnings"); //String msgText = dh.get("entry_txt"); String msgText = SettingsActivity.entry_txt.getText().toString(); boolean sendMsg = false; double[] gpsCoordinates = { 0, 0 }; String currentAddress = ""; boolean addAddress = false; Location l = new Location("gps"); if (isContacts.equalsIgnoreCase("true")) { if (contactExists(context, PhoneNumber)) sendMsg = true; } else { sendMsg = true; } //-- Less Warnings if (lessWarnings.equalsIgnoreCase("true") && sendMsg && dh.warningExists(PhoneNumber, 60)) { sendMsg = false; } dh.addWarning(PhoneNumber); //-- Check if number is in private group String[] tmp = { "", ""}; tmp = dh.getContact(PhoneNumber); //Log.v("nophonezone", "Private PhoneNumber = " + PhoneNumber + ", tmp0 = " + tmp[0] + ", tmp1 = " + tmp[1]); if (tmp[0].length() > 0 || tmp[1].length() > 0) { addAddress = true; } if (sendMsg && addAddress) { gpsCoordinates = getGPS(context); //Geocoder g = new Geocoder(context, Locale.getDefault()); //List<Address> addresses; String address = ""; //Log.v("nophonezone", "gps coordinates before: " + gpsCoordinates[0] + ", " + gpsCoordinates[1]); //gpsCoordinates[0] = 41.2047; //gpsCoordinates[1] = -8.3284; //Log.v("nophonezone", "gps coordinates after: " + gpsCoordinates[0] + ", " + gpsCoordinates[1]); //Toast.makeText(context, "gps coordinate are " + gpsCoordinates[0] + ", " + gpsCoordinates[1], Toast.LENGTH_LONG).show(); if (gpsCoordinates[0] != 0.0 || gpsCoordinates[1] != 0.0) { //try { //Log.v("nophonezone", "before getlocation"); //addresses = g.getFromLocation(gpsCoordinates[0], gpsCoordinates[1], 1); Geocoder g = new Geocoder(); l.setLatitude(gpsCoordinates[0]); l.setLongitude(gpsCoordinates[1]); address = g.reverseGeocode(l); //Toast.makeText(context, "address is " + address, Toast.LENGTH_LONG).show(); //Log.v("nophonezone", "after getlocation"); //Log.v("nophonezone", "addresses = " + addresses.toString()); //Log.v("nophonezone", "addresses = " + address); //if (!addresses.isEmpty()) { if (address.length() > 0) { currentAddress = address;//addresses.get(0).toString(); //Log.v("nophonezone", "current address is: " + currentAddress); msgText += "\n" + String.format(NoPhoneZone.msgAdd_Address, currentAddress); } /*} catch (IOException e) { e.printStackTrace(); }*/ } } msgText += "\n" + NoPhoneZone.msgAdd_Footer; if (sendMsg) { ArrayList<String> msgTexts = sm.divideMessage(msgText); sm.sendMultipartTextMessage(PhoneNumber, null, msgTexts, null, null); Toast.makeText(context, res.getString(R.string.nophonezone_toast_sms_sent) + " " + PhoneNumber, Toast.LENGTH_LONG).show(); /* ContentValues values = new ContentValues(); values.put("address", PhoneNumber); values.put("body", msgText); context.getContentResolver().insert(Uri.parse("content://sms/sent"), values); */ final ContentResolver cR = context.getContentResolver(); final String delayedPhone = PhoneNumber; final String delayedMsg = msgText; Handler h = new Handler(); h.postDelayed(new Runnable() { public void run() { ContentValues values = new ContentValues(); values.put("address", delayedPhone); values.put("body", delayedMsg); cR.insert(Uri.parse("content://sms/sent"), values); } }, 1000); } } private static double[] getGPS(Context context) { LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); List<String> providers = lm.getProviders(true); Location l = null; for (int i=providers.size()-1; i>=0; i--) { l = lm.getLastKnownLocation(providers.get(i)); if (l != null) break; } double[] gps = new double[2]; if (l != null) { gps[0] = l.getLatitude(); gps[1] = l.getLongitude(); } return gps; } public static boolean contactExists(Context context, String number) { //number = number.substring(4); //Log.v("nophonezone","debug: the parsed number = " + number); //-- Preferred method Uri lookupUri = Uri.withAppendedPath( PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)); String[] mPhoneNumberProjection = { PhoneLookup._ID, PhoneLookup.NUMBER, PhoneLookup.DISPLAY_NAME }; Cursor cur = context.getContentResolver().query(lookupUri,mPhoneNumberProjection, null, null, null); try { if (cur.moveToFirst()) { cur.close(); return true; } } finally { if (cur != null) cur.close(); } //-- Alternative method Uri slookupUri = Uri.withAppendedPath( Phone.CONTENT_FILTER_URI, Uri.encode(number)); String[] smPhoneNumberProjection = { Phone._ID, Phone.NUMBER, Phone.DISPLAY_NAME }; Cursor scur = context.getContentResolver().query(slookupUri,smPhoneNumberProjection, null, null, null); try { if (scur.moveToFirst()) { scur.close(); return true; } } finally { if (scur != null) scur.close(); } //-- Check on SIM String simUrl = "content://icc/adn"; Intent intent = new Intent(); intent.setData(Uri.parse(simUrl)); Uri simUri = intent.getData(); Cursor cursorSim = context.getContentResolver().query(simUri, null, null,null, null); while (cursorSim.moveToNext()) { String checkNum = cursorSim.getString(cursorSim.getColumnIndex("number")); //Log.v("nophonezone","debug: checkNum = " + checkNum); if (PhoneNumberUtils.compare(context, number, checkNum)) { return true; } } return false; } public static String parsePhoneNumber (String phone) { //Log.v("nophonezone", "phone before is: " + phone); phone = phone.replaceAll("[^0-9+]", ""); TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); try { PhoneNumber phoneN = phoneUtil.parse(phone, telephony.getSimCountryIso().toUpperCase()); phone = "+" + phoneN.getCountryCode() + phoneN.getNationalNumber(); } catch (NumberParseException e) { e.printStackTrace(); } /*if (PhoneNumberUtils.toaFromString(phone) != PhoneNumberUtils.TOA_International) { phone = PhoneNumberUtils.stringFromStringAndTOA(phone, PhoneNumberUtils.TOA_International); }*/ //Log.v("nophonezone", "phone after is: " + phone); return phone; } public static String formatCharset(String txtInicial) { /*try { msgText = new String(msgText.getBytes("UTF-8"), "UTF-8"); } catch (UnsupportedEncodingException e) { //e.printStackTrace(); }*/ Charset charsetOrigem = Charset.forName("UTF-8"); CharsetEncoder encoderOrigem = charsetOrigem.newEncoder(); Charset charsetDestino = Charset.forName("UTF-8"); CharsetDecoder decoderDestino = charsetDestino.newDecoder(); String txtFinal = ""; try { ByteBuffer bbuf = encoderOrigem.encode(CharBuffer.wrap( txtInicial )); CharBuffer cbuf = decoderDestino.decode(bbuf); txtFinal = cbuf.toString(); } catch (CharacterCodingException e) { e.printStackTrace(); //Log.v("nophonezone","error charset exception = " + e.toString()); } if (txtFinal.length() == 0) txtFinal = txtInicial; return txtFinal; } public void exitApplication () { SettingsActivity.setVolume(getApplicationContext(), false); dh.clearWarnings(); this.finish(); System.exit(RESULT_OK); } private class MyLicenseCheckerCallback implements LicenseCheckerCallback { @Override public void allow() { if (isFinishing()) { // Don't update UI if Activity is finishing. return; } // Should allow user access. } @Override public void dontAllow() { if (isFinishing()) { // Don't update UI if Activity is finishing. return; } // Should not allow access. An app can handle as needed, // typically by informing the user that the app is not licensed // and then shutting down the app or limiting the user to a // restricted set of features. // In this example, we show a dialog that takes the user to Market. showDialog(0); } @Override public void applicationError(ApplicationErrorCode errorCode) { showDialog(0); } } @Override protected void onDestroy() { super.onDestroy(); mChecker.onDestroy(); } }