<|start_filename|>src/main/java/com/anjlab/android/smsgateway/gcm/MainActivity.java<|end_filename|>
package com.anjlab.android.smsgateway.gcm;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.gcm.GoogleCloudMessaging;

import java.io.IOException;

import butterknife.ButterKnife;
import butterknife.InjectView;

public class MainActivity extends Activity
{

    public static final String PROPERTY_REG_ID = "registration_id";
    public static final String PROPERTY_SENDER_ID = "sender_id";
    private static final String PROPERTY_APP_VERSION = "app_version";
    public static final String PROPERTY_FORWARD_ENABLED = "forwarding_enabled";
    public static final String PROPERTY_FORWARD_URL = "forwarding_url";
    static final String TAG = "SMS Gateway";

    @InjectView(R.id.send)
    Button send;

    @InjectView(R.id.saveProjectId)
    Button saveProjectId;

    @InjectView(R.id.saveForwarning)
    Button saveForwarning;

    @InjectView(R.id.display)
    TextView display;

    @InjectView(R.id.senderIdInputView)
    EditText senderId;

    @InjectView(R.id.forwardingUrlInputView)
    EditText forwardingUrl;

    @InjectView(R.id.forwardingEnabled)
    CheckBox forwardingEnabled;

    @InjectView(R.id.senderIdPanel)
    View senderIdPanel;

    GoogleCloudMessaging gcm;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        ButterKnife.inject(this);

        send.setOnClickListener(new View.OnClickListener()
        {

            @Override
            public void onClick(View v)
            {
                Intent intent = new Intent(Intent.ACTION_SEND);
                intent.setType("text/plain");
                intent.putExtra(Intent.EXTRA_SUBJECT, "Your Android SMS Gateway Registration ID");
                intent.putExtra(Intent.EXTRA_TEXT, getRegistrationId());
                startActivity(Intent.createChooser(intent, "Send Email"));
            }
        });
        saveProjectId.setOnClickListener(new View.OnClickListener()
        {

            @Override
            public void onClick(View v)
            {
                storeSenderId(senderId.getText().toString());
                registerInBackground();
            }
        });
        saveForwarning.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                getGcmPreferences()
                        .edit()
                        .putString(PROPERTY_FORWARD_URL, forwardingUrl.getText().toString())
                        .putBoolean(PROPERTY_FORWARD_ENABLED, forwardingEnabled.isChecked())
                        .apply();
            }
        });

        forwardingUrl.setText(getForwardingUrl());
        forwardingEnabled.setChecked(getForwardingEnabled());

        // Check device for Play Services APK. If check succeeds, proceed with GCM registration.
        if (checkPlayServices())
        {
            gcm = GoogleCloudMessaging.getInstance(this);
            if (TextUtils.isEmpty(getRegistrationId()))
            {
                send.setVisibility(View.INVISIBLE);
                display.setText("");
            }
            else
                senderIdPanel.setVisibility(View.GONE);
        }
        else
        {
            display.setText(R.string.error_no_play_services);
        }
    }

    @Override
    protected void onResume()
    {
        super.onResume();

        checkPlayServices();
    }

    private boolean checkPlayServices()
    {
        return GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS;
    }

    private void storeRegistrationId(String regId)
    {
        getGcmPreferences()
                .edit()
                .putString(PROPERTY_REG_ID, regId)
                .putInt(PROPERTY_APP_VERSION, getAppVersion())
                .apply();
    }

    private String getRegistrationId()
    {
        SharedPreferences prefs = getGcmPreferences();
        String registrationId = prefs.getString(PROPERTY_REG_ID, "");
        if (registrationId.length() == 0)
        {
            Log.i(TAG, "Registration not found.");
            return "";
        }
        // Check if app was updated; if so, it must clear the registration ID
        // since the existing regID is not guaranteed to work with the new
        // app version.
        int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
        if (registeredVersion != getAppVersion())
        {
            Log.i(TAG, "App version changed.");
            return "";
        }
        return registrationId;
    }

    private String getSenderId()
    {
        return getGcmPreferences().getString(PROPERTY_SENDER_ID, "");
    }

    private void storeSenderId(String senderId)
    {
        getGcmPreferences()
                .edit()
                .putString(PROPERTY_SENDER_ID, senderId)
                .apply();
    }

    private void registerInBackground()
    {
        new AsyncTask<Void, Void, String>()
        {
            @Override
            protected String doInBackground(Void... params)
            {
                try
                {
                    if (gcm == null)
                        gcm = GoogleCloudMessaging.getInstance(getApplicationContext());
                    String id = gcm.register(getSenderId());
                    storeRegistrationId(id);
                    return "Device registered, Registration ID = " + id;
                }
                catch (IOException ex)
                {
                    return "Error: " + ex.getMessage();
                }
            }

            @Override
            protected void onPostExecute(final String msg)
            {
                runOnUiThread(new Runnable()
                {

                    @Override
                    public void run()
                    {
                        display.setText(msg);
                        if (!TextUtils.isEmpty(getRegistrationId()))
                        {
                            send.setVisibility(View.VISIBLE);
                            senderIdPanel.setVisibility(View.GONE);
                        }
                    }
                });
            }
        }.execute(null, null, null);
    }

    private int getAppVersion()
    {
        try
        {
            return getApplicationContext()
                    .getPackageManager()
                    .getPackageInfo(getApplicationContext().getPackageName(), 0)
                    .versionCode;
        }
        catch (NameNotFoundException e)
        {
            throw new RuntimeException("Could not get package name: " + e);
        }
    }

    private SharedPreferences getGcmPreferences()
    {
        return getSharedPreferences(getApplicationContext().getPackageName(), Context.MODE_PRIVATE);
    }

    private String getForwardingUrl()
    {
        return getGcmPreferences().getString(PROPERTY_FORWARD_URL, "");
    }

    private boolean getForwardingEnabled()
    {
        return getGcmPreferences().getBoolean(PROPERTY_FORWARD_ENABLED, false);
    }
}


<|start_filename|>src/main/java/com/anjlab/android/smsgateway/gcm/SmsMessageReceiver.java<|end_filename|>
package com.anjlab.android.smsgateway.gcm;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.telephony.SmsMessage;

public class SmsMessageReceiver extends BroadcastReceiver
{
    private static final String PDUS = "pdus";

    public void onReceive(Context context, Intent intent)
    {
        SharedPreferences preferences =
                context.getSharedPreferences(context.getApplicationContext().getPackageName(),
                                             Context.MODE_PRIVATE);
        if (preferences.getBoolean(MainActivity.PROPERTY_FORWARD_ENABLED, false))
        {
            Object[] pdus = (Object[]) intent.getExtras().get(PDUS);
            if (pdus != null && pdus.length > 0)
            {
                SmsMessage[] messages = new SmsMessage[pdus.length];
                for (int i = 0; i < pdus.length; i++)
                {
                    messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                }

                SmsMessage message = messages[0];
                String text;
                if (messages.length == 1 || message.isReplace())
                {
                    text = message.getDisplayMessageBody();
                }
                else
                {
                    StringBuilder textBuilder = new StringBuilder();
                    for (SmsMessage msg : messages)
                    {
                        textBuilder.append(msg.getMessageBody());
                    }
                    text = textBuilder.toString();
                }

                String number = message.getDisplayOriginatingAddress();

                Intent i = new Intent(context, HttpHookIntentService.class);
                i.putExtra(HttpHookIntentService.URL,
                           preferences.getString(MainActivity.PROPERTY_FORWARD_URL, ""));
                i.putExtra(HttpHookIntentService.TEXT, text);
                i.putExtra(HttpHookIntentService.SENDER, number);
                context.startService(i);
            }
        }
    }
}


<|start_filename|>src/main/java/com/anjlab/android/smsgateway/gcm/HttpHookIntentService.java<|end_filename|>
package com.anjlab.android.smsgateway.gcm;

import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;

import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

public class HttpHookIntentService extends IntentService {
    public static final String URL = "url";
    public static final String TEXT = "text";
    public static final String SENDER = "sender";

    public HttpHookIntentService() {
        super("HttpHookIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle extras = intent.getExtras();

        try
        {
            java.net.URL url = new URL(extras.getString(URL));
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("POST");
            conn.setDoInput(true);
            conn.setDoOutput(true);

            OutputStream os = conn.getOutputStream();
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
            writer.write(String.format("content=%s&from_number=%s",
                                       URLEncoder.encode(extras.getString(TEXT), "UTF-8"),
                                       extras.getString(SENDER)));
            writer.flush();
            writer.close();
            os.close();
            conn.getInputStream().close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }
}


<|start_filename|>src/main/java/com/anjlab/android/smsgateway/gcm/SmsIntentService.java<|end_filename|>
package com.anjlab.android.smsgateway.gcm;

import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.telephony.SmsManager;
import android.text.TextUtils;
import android.util.Log;

import com.google.android.gms.gcm.GoogleCloudMessaging;

import java.util.ArrayList;

public class SmsIntentService extends IntentService {
    public static final int NOTIFICATION_ID = 1;
    private NotificationManager mNotificationManager;

    public SmsIntentService() {
        super("GcmIntentService");
    }
    public static final String TAG = "SMS Gateway";

    @Override
    protected void onHandleIntent(Intent intent)
    {
        Bundle extras = intent.getExtras();
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
        String messageType = gcm.getMessageType(intent);

        if (!extras.isEmpty())
        {
            if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType))
            {
                String number = extras.getString("number");
                String message = extras.getString("message");
                if (!TextUtils.isEmpty(number) && !TextUtils.isEmpty(message))
                {
                    try
                    {
                        if (!number.startsWith("+"))
                        {
                            number = "+" + number;
                        }
                        SmsManager smsManager = SmsManager.getDefault();
                        ArrayList<String> parts = smsManager.divideMessage(message);
                        if (parts.size() > 1)
                        {
                            smsManager.sendMultipartTextMessage(number, null, parts, null, null);
                        }
                        else
                        {
                            smsManager.sendTextMessage(number, null, message, null, null);
                        }

                        String result = number + ": " + message;
                        Log.i(TAG, result);

                        sendNotification(result);

                        ContentValues values = new ContentValues();
                        values.put("address", number);
                        values.put("body", message);
                        getApplicationContext().getContentResolver()
                                               .insert(Uri.parse("content://sms/sent"), values);
                    }
                    catch (Exception ex)
                    {
                        Log.e(TAG, ex.toString());
                    }
                }
            }
        }
        SmsBroadcastReceiver.completeWakefulIntent(intent);
    }

    private void sendNotification(String msg) {
        mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);

        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.ic_stat_gcm)
        .setContentTitle(getText(R.string.app_name))
        .setStyle(new NotificationCompat.BigTextStyle()
        .bigText(msg))
        .setContentText(msg).setAutoCancel(true);

        mBuilder.setContentIntent(contentIntent);
        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
    }
}
