无法在Android应用中获得服务

时间:2014-10-10 07:41:06

标签: android service location

我正在创建一个应用程序,当您在特定位置时应显示消息。只要你保持应用程序打开,一切都运行良好。但现在我使用服务没有任何反应。甚至没有在服务中调用LocationChanged。我在设置与服务的连接时做错了吗?我想在关闭应用程序时显示消息,以便它在后台运行。我之前问了一个问题,他们告诉我使用服务。我已经实施了教程中的服务(我已经从中理解了)但是当应用程序在后台运行时它不起作用。我有点像Android的新手,我不知道为什么服务部分不适合我。我可能已经忘记了一些非常重要的事情。

这是清单文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.geotodo"
android:versionCode="1"
android:versionName="1.0" >

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<!-- Required for accessing our current location -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="19" />

<uses-feature
    android:glEsVersion="0x00020000"
    android:required="true"/>

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <service android:name=".LocalService" />
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="KEY"/>

    <meta-data android:name="com.google.android.gms.version"
    android:value="@integer/google_play_services_version" />

</application>

我根据这个问题从服务中提供了哪些代码:Gps Location updates in android is not working

我一直试图在代码不工作时进行调试,而且显然只是&#34; Bound&#34;得到印刷。我希望其他印刷品陈述也可以得到满足。

logcat的输出只是标准输出,它不会给出任何错误或类似的错误。

到目前为止,这是我的代码:

public class MainActivity extends ActionBarActivity implements SensorEventListener {

private boolean notificationEntered; /* A boolean to check if a notification is entered before we check the range and stuff like that */
private int notificationID;

/* Sensors for handling the shake gesture */
private SensorManager senSensorManager;
private Sensor senAccelerometer;

/* Variables to deal with the shake gesture */
private long lastUpdate = 0;
private float last_x, last_y, last_z;
private static final int SHAKE_THRESHOLD = 600;

/* The locationclient */
private LocationClient locationClient;
Location currentLocation;

private double currentLocationX; /* The currentLocation in meters for X value */
private double currentLocationY; /* The currentLocation in meters for Y value */


/* The todo message save button */
private Button todoSaveButton;

/* The location that will be entered by the user, the location where the notification needs to pop up */
private LatLng location;
private double locationX; /* The location in meters for X value */
private double locationY; /* The location in meters for Y value */

private GoogleMap mMap;

private LocalService service;
private boolean isBound = false;

private ServiceConnection mConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
        System.out.println("TESTJE");
        // This is called when the connection with the service has been
        // established, giving us the service object we can use to
        // interact with the service.  Because we have bound to a explicit
        // service that we know is running in our own process, we can
        // cast its IBinder to a concrete class and directly access it.
        service = (IBinder) ((LocalService.LocalBinder)service).getService();

        System.out.println("TEST CONNECTIEE");

    }

    public void onServiceDisconnected(ComponentName className) {
        // This is called when the connection with the service has been
        // unexpectedly disconnected -- that is, its process crashed.
        // Because it is running in our same process, we should never
        // see this happen.
        service = null;
    }
};

void doBindService() {
    // Establish a connection with the service.  We use an explicit
    // class name because we want a specific service implementation that
    // we know will be running in our own process (and thus won't be
    // supporting component replacement by other applications).
    System.out.println("BOUND");
    getApplicationContext().bindService(new Intent(this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE);
    isBound = true;
}

void doUnbindService() {
    if (isBound) {
        // Detach our existing connection.
        unbindService(mConnection);
        isBound = false;
    }
}


protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    doBindService();

    senSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    senAccelerometer = senSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    senSensorManager.registerListener(this, senAccelerometer , SensorManager.SENSOR_DELAY_NORMAL);

    notificationEntered = false;
    notificationID = -1;

    /* Clear earlier saved data */
    clearPreferences();

    getMapSafely();

    if(mMap != null){
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

        mMap.setOnMapClickListener(new OnMapClickListener() {

            @Override
            public void onMapClick(LatLng latLng) {

                // Creating a marker
                MarkerOptions markerOptions = new MarkerOptions();

                // Setting the position for the marker
                markerOptions.position(latLng);

                // Setting the title for the marker.
                // This will be displayed on taping the marker
                markerOptions.title(latLng.latitude + " : " + latLng.longitude);

                // Clears the previously touched position
                mMap.clear();

                // Animating to the touched position
                mMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));

                // Placing a marker on the touched position
                mMap.addMarker(markerOptions);

                location = latLng;
            }
        });

        todoSaveButton = (Button) findViewById(R.id.button_todo);

        todoSaveButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                SharedPreferences sharedPref = MainActivity.this.getPreferences(Context.MODE_PRIVATE);
                EditText todoMessage = (EditText) findViewById(R.id.todo_message);
                EditText range = (EditText) findViewById(R.id.range);

                clearPreferences(); /* Delete the earlier doto messages because it's easier for this beginner app */


                SharedPreferences.Editor editor = sharedPref.edit();

                /* Save the todo message as a string */
                if (todoMessage.getText().toString() != null) {
                    editor.putString("todomessage", todoMessage.getText().toString());
                    /* Save the range as an integer */
                    if (range.getText().toString() != null) {
                        editor.putInt("range", Integer.parseInt(range.getText().toString()));
                        /* Save the location in two parts latitude & longitude */
                        if (location != null) {
                            editor.putFloat("longitude", (float) location.longitude);
                            editor.putFloat("latitude", (float) location.latitude);
                            editor.commit();
                            notificationEntered = true;

                            /* Show a pop up on the phone that everything is saved */
                            Context context = getApplicationContext();
                            CharSequence text = "Todo message & location saved.";
                            int duration = Toast.LENGTH_SHORT;

                            Toast toast = Toast.makeText(context, text, duration);
                            toast.show();
                        }
                    }
                }
                clearScreen();
                /* The output of the entered stuff -> works!
                SharedPreferences readPref = MainActivity.this.getPreferences(Context.MODE_PRIVATE);
                String todo = readPref.getString("todomessage", "Error");
                System.out.println(todo);

                int rangeOutput = readPref.getInt("range", 0);
                System.out.println(rangeOutput);

                String LatLng = readPref.getString("location", "Error");
                System.out.println(LatLng);*/

            }

            private void clearScreen() {
                mMap.clear(); /* Clear the marker from the map */

                EditText todoMessage = (EditText) findViewById(R.id.todo_message);
                EditText range = (EditText) findViewById(R.id.range);
                todoMessage.setText("");
                range.setText("");
            }
        });
    }
}

@TargetApi(Build.VERSION_CODES.HONEYCOMB) @SuppressLint("NewApi") private void getMapSafely() {
    // 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();
    }
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}


/**
 * Checks if we arrived at the location we need to be to show a notification
 */
private void checkIfArrived() {
    /* The difference between the currentLocation and the location where we need to be to show the notification */
    double differenceX;
    double differenceY;

    /* Convert degrees to meters */
    currentLocationX = currentLocation.getLatitude() * 40008000 / 360;
    currentLocationY = currentLocation.getLongitude() * 40075160 * Math.cos(currentLocation.getLatitude()) / 360;

    /* Get the saved location */
    SharedPreferences readPref = MainActivity.this.getPreferences(Context.MODE_PRIVATE);
    locationX = readPref.getFloat("latitude", (float) 0.0) * 40008000 / 360;
    locationY = readPref.getFloat("longitude", (float) 0.0) * 40075160 * Math.cos(readPref.getFloat("latitude", (float) 0.0)) / 360;

    /*Debug material
    System.out.println("Loc X in degrees : " + readPref.getFloat("latitude", (float) 0.0));
    System.out.println("Loc Y in degrees : " + readPref.getFloat("longitude", (float) 0.0));
    System.out.println("loc X in meters  " + locationX);
    System.out.println("loc Y in meters " + locationY);
    */

    /* Get the saved range */
    int range = readPref.getInt("range", 0);

    /* Get the absolute difference in meters */
    differenceX = Math.abs(currentLocationX - locationX);
    differenceY = Math.abs(currentLocationY - locationY);

    /*Debug material 
    System.out.println("Diff X " + differenceX);
    System.out.println("Diff Y " + differenceY);
    System.out.println(range); 
    */

    /* If we are close enough in any range we show the notification */
    if(differenceX <= range && differenceY <= range)
        showNotification();
}

/**
 * Show a notification with the todo message
 */
private void showNotification() {
    /* Get the saved todo message */
    SharedPreferences readPref = MainActivity.this.getPreferences(Context.MODE_PRIVATE);
    String todoMessage = readPref.getString("todomessage", "Error");

    /* Show the notification */
    if(todoMessage != "Error"){
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_launcher).setContentTitle("Todo message!").setContentText(todoMessage);

        // Sets an ID for the notification
        notificationID = 001;
        // Gets an instance of the NotificationManager service
        NotificationManager notifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        // Builds the notification and issues it.
        notifyMgr.notify(notificationID, builder.build());
    }
}
/**
 * Delete a specific notification
 */
private void deleteNotification() {
    NotificationManager notifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

    /* Delete the notification we showed before with this ID */
    if(notificationID != -1) /* If we have a notificationID */
        notifyMgr.cancel(notificationID);

    notificationID = -1; /* Reset the ID */

    clearPreferences(); /* Delete the todo message because the todomessage has been shown */
}

/**
 * Clear the preferences (todomessage that has been added)
 */
private void clearPreferences() {
    SharedPreferences sharedPref = MainActivity.this.getPreferences(Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPref.edit();
    editor.clear();
    editor.commit();
}


@Override
protected void onPause() {
    super.onPause();
    senSensorManager.unregisterListener(this);
}

@Override
protected void onResume() {
    super.onResume();
    senSensorManager.registerListener(this, senAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}

@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
    // TODO Auto-generated method stub

}

@Override
public void onSensorChanged(SensorEvent sensorEvent) {
    Sensor mySensor = sensorEvent.sensor;

    if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        float x = sensorEvent.values[0];
        float y = sensorEvent.values[1];
        float z = sensorEvent.values[2];

        long curTime = System.currentTimeMillis();

        if ((curTime - lastUpdate) > 100) {
            long diffTime = (curTime - lastUpdate);
            lastUpdate = curTime;

            float speed = Math.abs(x + y + z - last_x - last_y - last_z)/ diffTime * 10000;

            if (speed > SHAKE_THRESHOLD) {
                deleteNotification();
            }

            last_x = x;
            last_y = y;
            last_z = z;
        }
    }
}

public class LocalService extends Service implements LocationListener,
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener,
com.google.android.gms.location.LocationListener {
    /* Global constants for getting the current location */

    // 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 */
    LocationRequest locationRequest;



    /**
     * Class for clients to access.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with
     * IPC.
     */
    public class LocalBinder extends Binder {
        LocalService getService() {
            return LocalService.this;
        }
    }

    @Override
    public void onCreate() {
        System.out.println("ONCREATE");

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

        // Create the LocationRequest object
        locationRequest = LocationRequest.create();
        // Use high accuracy
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        // Set the update interval to 5 seconds
        locationRequest.setInterval(UPDATE_INTERVAL);
        // Set the fastest update interval to 1 second
        locationRequest.setFastestInterval(FASTEST_INTERVAL);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // Connect the client.
        locationClient.connect();

        // We want this service to continue running until it is explicitly
        // stopped, so return sticky.
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
    }

 // Define the callback method that receives location updates, will be called
    // every 5 seconds
    @Override
    public void onLocationChanged(Location location) {

        System.out.println("TEST LOCATIONNN");
        /* Change the currentLocation variable to the new location we are at */
        currentLocation = location;

        /*
         * Check if we arrived at the location we need to be to show a
         * notification
         */
        if (notificationEntered)
            checkIfArrived();
    }

    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("BOUNDED");
        return mBinder;
    }

    // This is the object that receives interactions from clients.  See
    // RemoteService for a more complete example.
    private final IBinder mBinder = new LocalBinder();

    @Override
    public void onConnectionFailed(ConnectionResult arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onConnected(Bundle arg0) {
        // Display the connection status
        Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();

        locationClient.requestLocationUpdates(locationRequest, this);

    }

    @Override
    public void onDisconnected() {
        // Display the connection status
        Toast.makeText(this, "Disconnected. Please re-connect.",
                Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onProviderDisabled(String arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderEnabled(String arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
        // TODO Auto-generated method stub

    }
}
}

请帮忙!

0 个答案:

没有答案