我有一个记录加速度计数据的应用程序,并在通过treshhold时发送短信。手机醒着时工作正常。我需要做什么,这也可以在手机锁定/睡眠时也这样做:
我有两个活动SendSMSActivity.java:
package com.example.sendsms;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.Menu;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.FilterQueryProvider;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class SendSMSActivity extends Activity implements SensorEventListener {
SendSMS mSender = new SendSMS();
private SensorManager senSensorManager;
private Sensor senAccelerometer;
private long lastUpdate;
private float last_x, last_y, last_z;
//Contacts variable
AutoCompleteTextView emailText;
ContentResolver cr;
SimpleCursorAdapter emailAdapter;
protected void onResume() {
super.onResume();
senSensorManager.registerListener(this, senAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
senSensorManager.unregisterListener(this);
}
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
//To change body of implemented methods use File | Settings | File Templates.
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();
// only allow one update every 100ms.
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;
TextView threshText = (TextView)findViewById(R.id.thresh);
if (speed > Float.parseFloat(threshText.getText().toString())) {
Toast.makeText(this, "shake detected w/ speed: " + speed, Toast.LENGTH_SHORT).show();
Toast.makeText(this, "shake detected w/ speed: " + speed, Toast.LENGTH_SHORT).show();
TextView resultText = (TextView)findViewById(R.id.xacc);
resultText.setText("shake detected w/ speed: " + speed);
sendit2();
}
last_x = x;
last_y = y;
last_z = z;
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// can be safely ignored for this demo
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Get an instance of the SensorManager
senSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
senAccelerometer = senSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
senSensorManager.registerListener(this, senAccelerometer , SensorManager.SENSOR_DELAY_NORMAL);
//Contacts
cr = getContentResolver();
emailText = (AutoCompleteTextView) findViewById(R.id.mobileNo);
String[] fromCols = {
ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.DATA,
};
int[] toViewIds = { R.id.list_name, R.id.list_email };
emailAdapter = new SimpleCursorAdapter(this, R.layout.email_and_name, getNamesAndEmails(null), fromCols, toViewIds);
// Important 1: You have to provide a way of making the chosen choice look presentable.
// emailAdapter.setStringConversionColumn(1); // 1=DISPLAY_NAME, 2=Email
emailAdapter.setCursorToStringConverter(new SimpleCursorAdapter.CursorToStringConverter() {
@Override
public CharSequence convertToString(Cursor cursor) {
return String.format("%s <%s>", cursor.getString(1).trim(), cursor.getString(2).trim());
}
});
// Important 2: You have to provide a query containing the values on demand
emailAdapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
String partialItemName = null;
if (constraint != null) {
partialItemName = constraint.toString();
}
return getNamesAndEmails(partialItemName);
}
});
emailText.setAdapter(emailAdapter);
}
//Contacts
@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;
}
final static String[] PROJECTION = new String[] {
ContactsContract.RawContacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.DATA,
ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,
};
/** Get the contacts that have email addresses matching "partialName".
* @author Modified from code obtained from
* http://stackoverflow.com/questions/5205999/android-get-a-cursor-only-with-contacts-that-have-an-email-listed-android-2-0
* @return
*/
Cursor getNamesAndEmails(String partialName) {
// Look for partialName either in display name (person name) or in email
final String filter =
ContactsContract.Contacts.DISPLAY_NAME + " LIKE '%" + partialName + "%'" +
" OR " +
ContactsContract.CommonDataKinds.Phone.DATA + " LIKE '%" + partialName + "%'";
// If display name contains "@" (maybe it's null so Contacts provides email here),
// order by email, else order by display name.
final String order = "CASE WHEN "
+ ContactsContract.Contacts.DISPLAY_NAME
+ " NOT LIKE '%@%' THEN 1 ELSE 2 END, "
+ ContactsContract.Contacts.DISPLAY_NAME
+ ", "
+ ContactsContract.CommonDataKinds.Phone.DATA
+ " COLLATE NOCASE";
// Now make a Cursor containing the contacts that now match partialName as per "filter".
return cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, filter, null, order);
}
public void sendit(View v) {
TextView mobileNum = (TextView)findViewById(R.id.mobileNo);
boolean success = mSender.sendSMSMessage(mobileNum.getText().toString(),
// This is standard lorem-ipsum text, do not bother
// trying to wrap it, there's about 500 characters...
"Movement detected."
);
Toast.makeText(this, "Message sent " + (
success ? "successfully" : "unsuccessfully"),
Toast.LENGTH_SHORT).show();
TextView resultText = (TextView)findViewById(R.id.xacc);
resultText.setText("Message Sent");
}
public void sendit2() {
TextView mobileNum = (TextView)findViewById(R.id.mobileNo);
boolean success = mSender.sendSMSMessage(mobileNum.getText().toString(),
// This is standard lorem-ipsum text, do not bother
// trying to wrap it, there's about 500 characters...
"Movement detected."
);
Toast.makeText(this, "Message sent " + (
success ? "successfully" : "unsuccessfully"),
Toast.LENGTH_SHORT).show();
TextView resultText = (TextView)findViewById(R.id.xacc);
resultText.setText("Message Sent");
}
}
和SendSMS.java:
package com.example.sendsms;
import java.util.ArrayList;
import android.telephony.SmsManager;
import android.util.Log;
/** The code for dealing with the SMS manager;
* called from the GUI code.
*/
public class SendSMS {
static String TAG = "SendSMS";
SmsManager mSMSManager = null;
/* The list of message parts our messge
* gets broken up into by SmsManger */
ArrayList<String> mFragmentList = null;
/* Service Center - not used */
String mServiceCentreAddr = null;
SendSMS() {
mSMSManager = SmsManager.getDefault();
}
/* Called from the GUI to send one message to one destination */
public boolean sendSMSMessage(
String aDestinationAddress,
String aMessageText) {
if (mSMSManager == null) {
return (false);
}
mFragmentList = mSMSManager.divideMessage(aMessageText);
int fragmentCount = mFragmentList.size();
if (fragmentCount > 1) {
Log.d(TAG, "Sending " + fragmentCount + " parts");
mSMSManager.sendMultipartTextMessage(aDestinationAddress,
mServiceCentreAddr,
mFragmentList, null, null);
} else {
Log.d(TAG, "Sendine one part");
mSMSManager.sendTextMessage(aDestinationAddress,
mServiceCentreAddr,
aMessageText, null, null);
}
return true;
}
}