全局变量神奇地设置为空?

时间:2014-10-08 07:33:33

标签: android sms google-maps-android-api-2

我正在使用一个SMSReceiver类来接收短信,然后将短信作为额外信息发送到我的主要活动,以便在地图应用程序中使用。在我的onReceive方法中,我提供额外的东西,我得到的值非常好,但是当我尝试使用变量稍后我的代码反转geoCode从地址获取坐标然后突然全局变量再次为null:(

该方法在第324行被称为showOnMapClicked,其中变量再次为null。

短信从DDMS发送。

有人请求帮助,我无法弄明白!

OnReceive Class:

    package com.example.maps;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.Toast;
import android.content.Intent;

public class SMSReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
    //Adding bundle extras to be used by the main class
    Bundle bundle = intent.getExtras();
    SmsMessage[] msgs = null;
    String str = "SMS from ";

    //Adding the sms to the array to be stored
    if (bundle != null)
    {
        Object[] pdus = (Object[]) bundle.get("pdus");
        msgs = new SmsMessage[pdus.length];
        for (int i = 0; i < msgs.length; i++) {
            msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
            if (i == 0)
            {
                //Appending the information to the string to be displayed
                str += msgs[i].getOriginatingAddress();
                str += ": \n";              
            }

            str += msgs[i].getMessageBody().toString();

        }

        Toast.makeText(context, str, Toast.LENGTH_LONG).show();

        //Creating the new intent 
        Intent mainActivityIntent = new Intent(context, MainActivity.class);
        mainActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(mainActivityIntent);

        //Making the intent broadcast to the main class and putting the extra in to be displayed
        Intent broadcastIntent = new Intent();
        broadcastIntent.setAction("SMS_RECEIVED_ACTION");
        //Setting the name of the string to "sms"
        broadcastIntent.putExtra("sms", str);
        context.sendBroadcast(broadcastIntent);

        //Stops the sms from going directly into the inbox
        this.abortBroadcast();
  }

 }
}

主要活动类:

 package com.example.maps;

//Daniel Tromp - Assignment 2 - 12002076
//Imports for DAYS!

import java.io.IOException;
import java.util.List;
import java.util.Locale;
import com.example.maps.R;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.text.InputFilter;
import android.text.InputType;
import android.text.method.DigitsKeyListener;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

//Implementing all the needed services
public class MainActivity extends Activity implements
        GooglePlayServicesClient.ConnectionCallbacks,
        GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {

    // Initializing the needed globals
    Location mLocation;
    String addressSms;
    String addressText;
    public GoogleMap mMap;
    private TextView mAddress;
    private ProgressBar mActivityIndicator;
    private LocationClient mLocationClient;
    BroadcastReceiver smsSentReceiver, smsDeliveredReceiver;
    IntentFilter intentFilter;

    // Milliseconds per second
    private static final int MILLISECONDS_PER_SECOND = 1000;
    // Update frequency in seconds
    public static final int UPDATE_INTERVAL_IN_SECONDS = 5;
    // Update frequency in milliseconds
    private static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND
            * UPDATE_INTERVAL_IN_SECONDS;
    // The fastest update frequency, in seconds
    private static final int FASTEST_INTERVAL_IN_SECONDS = 1;
    // A fast frequency ceiling in milliseconds
    private static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND
            * FASTEST_INTERVAL_IN_SECONDS;

    // Define an object that holds accuracy and frequency parameters
    private LocationRequest mLocationRequest;

    private BroadcastReceiver intentReceiver = new BroadcastReceiver() {
        @Override
        //On receiving a message, the textview is set to the sms message
        public void onReceive(Context context, Intent intent) {

          addressSms = intent.getStringExtra("sms");

         //Toasting the variable where it displays my sms message
         Toast.makeText(getBaseContext(), addressSms, Toast.LENGTH_LONG).show();
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setUpMapIfNeeded();
        mAddress = (TextView) findViewById(R.id.address);
        // As the app loads, the address bar will be displayed
        mActivityIndicator = (ProgressBar) findViewById(R.id.address_progress);
        // Setting the map type to be Hybrid
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        // Create the LocationRequest object
        mLocationRequest = LocationRequest.create();
        // Use high accuracy
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        // Set the update interval to 5 seconds
        mLocationRequest.setInterval(UPDATE_INTERVAL);
        // Set the fastest update interval to 1 second
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);

        /*
         * Create a new location client, using the enclosing class to handle
         * callbacks.
         */
        mLocationClient = new LocationClient(this, this, this);

        //Creating the new intent  
          intentFilter = new IntentFilter();
          intentFilter.addAction("SMS_RECEIVED_ACTION");
          registerReceiver(intentReceiver, intentFilter);

    }

    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the
        // map.
        if (mMap == null) {
            mMap = ((MapFragment) getFragmentManager().findFragmentById(
                    R.id.map)).getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                // The Map is verified. It is now safe to manipulate the map.
            }
        }
    }

    // When the application is started
    @Override
    protected void onStart() {
        super.onStart();
        // Connect the client.
        mLocationClient.connect();
    }

    private class GetAddressTask extends AsyncTask<Location, Void, String> {
        Context mContext;

        public GetAddressTask(Context context) {
            super();
            mContext = context;
        }

        protected String doInBackground(Location... params) {
            Geocoder geocoder = new Geocoder(mContext, Locale.getDefault());
            // Get the current location from the input parameter list
            Location loc = params[0];
            // Create a list to contain the result address
            List<Address> addresses = null;
            try {
                /*
                 * Return 1 address.
                 */
                addresses = geocoder.getFromLocation(loc.getLatitude(),
                        loc.getLongitude(), 1);
            } catch (IOException e1) {
                Log.e("LocationSampleActivity",
                        "IO Exception in getFromLocation()");
                e1.printStackTrace();
                return ("IO Exception trying to get address");
            } catch (IllegalArgumentException e2) {
                // Error message to post in the log
                String errorString = "Illegal arguments "
                        + Double.toString(loc.getLatitude()) + " , "
                        + Double.toString(loc.getLongitude())
                        + " passed to address service";
                Log.e("LocationSampleActivity", errorString);
                e2.printStackTrace();
                return errorString;
            }
            // If the reverse geocode returned an address
            if (addresses != null && addresses.size() > 0) {
                // Get the first address
                Address address = addresses.get(0);
                /*
                 * Format the first line of address (if available), city, and
                 * country name.
                 */
                addressText = String.format(
                        "%s, %s, %s",
                        // If there's a street address, add it
                        address.getMaxAddressLineIndex() > 0 ? address
                                .getAddressLine(0) : "",
                        // Locality is usually a city
                        address.getLocality(),
                        // The country of the address
                        address.getCountryName());
                // Return the text
                return addressText;

            } else {
                return "No address found";
            }
        }

        protected void onPostExecute(String address) {
            // Set activity indicator visibility to "gone"
            mActivityIndicator.setVisibility(View.GONE);
            // Display the results of the lookup.
            mAddress.setText(address);

        }
    }

    // When the connection is made to get live updates
    public void onConnected(Bundle dataBundle) {
        // Display the connection status
        Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
        // Start periodic updates
        mLocationClient.requestLocationUpdates(mLocationRequest, this);
    }

    // When the new coordinates are put into the DDMS, the map will change to
    // that location and get the new address
    public void onLocationChanged(Location location) {
        // Report to the UI that the location was updated

        LatLng latlng = new LatLng(location.getLatitude(),
                location.getLongitude());
        mMap.moveCamera(CameraUpdateFactory.newLatLng(latlng));

        mActivityIndicator.setVisibility(View.VISIBLE);
        /*
         * Reverse geocoding is long-running and synchronous. Run it on a
         * background thread. Pass the current location to the background task.
         * When the task finishes, onPostExecute() displays the address.
         */
        (new GetAddressTask(this)).execute(location);
    }

    @Override
    public void onConnectionFailed(ConnectionResult arg0) {

    }

    @Override
    public void onDisconnected() {

    }

    // Click on button to get the read me file to know how to use the
    // application
    public void readMeClicked(View v) {

        // Create a dialog to pop up and explain the application to the user
        AlertDialog alertDialog = new AlertDialog.Builder(this).create(); // Read
                                                                            // Update
        alertDialog.setTitle("Read Me");
        alertDialog
                .setMessage("My app was created to be able to quickly send out an emergency SMS to a certain individual which will contain the emergency message as well as their current location. By using the DDMS, the coordinates can be input and then my app will go to that specific location and pull the most correct address of that location");
        // Making the dialog show
        alertDialog.show();
    }

    public void getFromLocationClicked(View v) {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(
                MainActivity.this);

        // Setting Dialog Title
        alertDialog.setTitle("Emergency SMS");

        // Setting Dialog Message
        alertDialog.setMessage("Enter Emergency Contact Number");
        final EditText input = new EditText(MainActivity.this);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);
        input.setLayoutParams(lp);
        alertDialog.setView(input);

        // Setting Positive "Continue" Button
        alertDialog.setPositiveButton("Continue",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {

                        String testing = input.getText().toString();

                        getFromLocation(testing);

                    }
                });

        // Setting Negative "Cancel" Button
        alertDialog.setNegativeButton("Cancel",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {

                        dialog.cancel();
                    }
                });

        // Showing Alert Message
        alertDialog.show();
    };

    public void getFromLocation(String strAddress) {

        Geocoder coder = new Geocoder(this);
        List<Address> address;

        try {
            address = coder.getFromLocationName(strAddress, 5);
            if (address != null) {

                Address location = address.get(0);
                double recLat = location.getLatitude();
                double recLng = location.getLongitude();

                LatLng p = new LatLng(recLat, recLng);
                Toast.makeText(getBaseContext(), p + "", Toast.LENGTH_LONG)
                        .show();

                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(p, 16));
            }
        } catch (IOException ie) {
            ie.printStackTrace();
        }
    }

    //Showing the value when the show button is clicked
    public void showOnMapClicked(View v)
    {
        //When it toasts, the addressSms value is now null!?? 
        Toast.makeText(getBaseContext(), addressSms, Toast.LENGTH_LONG).show();
        //getFromLocation(addressSms);      
    }

    public void showToast(String message)
    {
        String test = message;
        Toast.makeText(getBaseContext(), test, Toast.LENGTH_LONG).show();
    }

    // Click the button to start to generate the emergency SMS
    public void sendAddressClicked(final View v) {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(
                MainActivity.this);

        // Setting Dialog Title
        alertDialog.setTitle("Emergency SMS");

        // Setting Dialog Message
        alertDialog.setMessage("Enter Emergency Contact Number");
        final EditText input = new EditText(MainActivity.this);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);
        input.setLayoutParams(lp);
        alertDialog.setView(input);

        input.setFilters(new InputFilter[] {
                // Maximum 2 characters.
                new InputFilter.LengthFilter(10),
                // Digits only.
                DigitsKeyListener.getInstance(), // Not strictly needed, IMHO.
        });

        // Setting Positive "Continue" Button
        alertDialog.setPositiveButton("Continue",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {

                        // Setting the SMS message and adding the current
                        // location which is gathered by the map.
                        String textMessage = input.getText().toString();

                        // Checking if the phone number is not blank
                        if (textMessage.isEmpty()) {
                            // If the phone number is not entered
                            Toast.makeText(getBaseContext(),
                                    "Cannot be blank. Enter phone number.",
                                    Toast.LENGTH_LONG).show();
                            sendAddressClicked(v);
                        }

                        else {
                            enterMessage(textMessage);
                        }

                    }
                });

        // Setting Negative "Cancel" Button
        alertDialog.setNegativeButton("Cancel",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {

                        dialog.cancel();
                    }
                });

        // Showing Alert Message
        alertDialog.show();
    };

    // Method to send the emergency method and the current location
    private void sendSMS(String phoneNumber, String message) {
        // Sending the sms to the emulator number input
        SmsManager sms = SmsManager.getDefault();
        sms.sendTextMessage(phoneNumber, null, message, null, null);
    }

    // Once the user has input the number, the message now will be asked for
    public void enterMessage(final String number) {
        // Creating the dialog to input the emergency message
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(
                MainActivity.this);

        // Setting Dialog Title
        alertDialog.setTitle("Emergency SMS");

        // Setting Dialog Message
        alertDialog.setMessage("Enter Emergency SMS");
        final EditText input = new EditText(MainActivity.this);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);
        input.setLayoutParams(lp);
        alertDialog.setView(input);

        input.setInputType(InputType.TYPE_CLASS_TEXT);

        // Setting Positive "SEND SMS" Button
        alertDialog.setPositiveButton("SEND SMS",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        // Write your code here to execute after dialog

                        // Setting the SMS message and adding the current
                        // location which is gathered by the map.
                        String textMessage = input.getText().toString();
                        String SMS = textMessage + "\n\n"
                                + "My Current Address Is: " + addressText;
                        String phoneNumber = number;

                        // Checking to see if the SMS is blank
                        if (textMessage.isEmpty()) {
                            Toast.makeText(getBaseContext(),
                                    "Cannot be blank. Enter emergency SMS.",
                                    Toast.LENGTH_LONG).show();
                            enterMessage(phoneNumber);
                        }

                        else {
                            // Sending the variables through to the sendSMS
                            // method to be sent
                            sendSMS(phoneNumber, SMS);
                        }
                    }
                });

        // Setting Negative "Cancel" Button
        alertDialog.setNegativeButton("Cancel",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        // Write your code here to execute after dialog
                        dialog.cancel();
                    }
                });

        // Showing Alert Message
        alertDialog.show();
    };
}

1 个答案:

答案 0 :(得分:0)

尝试覆盖MainActivity中的 onSaveInstanceState(Bundle bundle)方法,并使用日志查看是否在数据被清除之前调用它。我怀疑你会看到它被调用。如果是这样,只需将你的'全局'保存在包中并通过覆盖 onRestoreInstanceState(捆绑包)

来检索它们

DOC可以帮助您了解如何保存和恢复。每当需要为内存或方向更改而杀死活动时,onCreate将被调用,并且'globals'可能会以这种方式丢失。

This可能有助于了解更多细节。