私のアプリケーションでは、ユーザーがテキスト メッセージを作成し、送信したい日時を指定できます。私はいくつかの問題を抱えています。保留中のインテントの性質上、メッセージごとに新しいインテントを作成することはできません。したがって、保留中のインテントが実行される前にユーザーが送信する新しいテキストを送信すると、前のメッセージが上書きされます。現状では、複数のメッセージを送信するためにキューに入れることはできません。
これに対する私の解決策は、さまざまなメッセージの詳細を含む SQLite データベースを維持し、データベースで次に来るメッセージで保留中の意図を単純に更新することでした。これには、送信される現在のメッセージのリストを表示し、送信されるメッセージを編集する実装をより簡単にするという追加の利点もあります。
問題は、データベースを適切にセットアップしているとは思わないことです。デバッグ モードで実行すると、データベース ヘルパー クラス (MessagesHelper) に入り、データベース変数をインスタンス化していないようです。何が間違っているのかわからず、android SQLite dev guide に従っています。あなたが私に与えることができる助け/ヒントをいただければ幸いです。
テーブル コントラクト クラス
public class Messages {
private Messages(){}
public static abstract class Texts implements BaseColumns {
public static final String TABLE_NAME = "texts";
public static final String DEFAULT_SORT_ORDER = "stime DESC";
public static final String COLUMN_NAME_RECIPIENT = "recipient";
public static final String COLUMN_NAME_MESSAGE = "message";
public static final String COLUMN_NAME_SEND_TIME = "stime";
public static final String AUTHORITY = "com.rastelliJ.deferredSMS";
}
}
DB ヘルパー クラス
public class MessagesHelper extends SQLiteOpenHelper{
private static final String TAG = "MessagesHelper";
private static final String TEXT_TYPE = " TEXT";
private static final String COMMA_SEP = ",";
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + Messages.Texts.TABLE_NAME + " (" +
Messages.Texts._ID + " INTEGER PRIMARY KEY," +
Messages.Texts.COLUMN_NAME_MESSAGE + TEXT_TYPE + COMMA_SEP +
Messages.Texts.COLUMN_NAME_RECIPIENT + TEXT_TYPE + COMMA_SEP +
Messages.Texts.COLUMN_NAME_SEND_TIME + TEXT_TYPE + " )";
private static final String SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS " + Messages.Texts.TABLE_NAME;
// If you change the database schema, you must increment the database version.
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "Messages.db";
MessagesHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// This database is only a cache for online data, so its upgrade policy is
// to simply to discard the data and start over
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL(SQL_DELETE_ENTRIES);
onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}
主な活動
public class MainActivity extends FragmentActivity {
private CustomDateTimePicker customDT;
private MessagesHelper mDbHelper;
private EditText phoneName, messageText;
private String phoneNum, alarmtime;
private TextView alarmText;
private Button sendButt;
private int pickerHour = 0,
pickerMin = 0,
pickerYear = 0,
pickerMonth = 0,
pickerDay = 0;
private static final int CONTACT_PICKER_RESULT = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Set up the custom Date Time Picker
customDT = new CustomDateTimePicker(this, new CustomDateTimePicker.ICustomDateTimeListener() {
public void onSet(Dialog dialog, Calendar calendarSelected,
Date dateSelected, int year, String monthFullName,
String monthShortName, int monthNumber, int date,
String weekDayFullName, String weekDayShortName,
int hour24, int hour12, int min, int sec,
String AM_PM) {
// Do something with the time chosen by the user
pickerYear = year;
pickerMonth = monthNumber;
pickerDay = date;
pickerHour = hour24;
pickerMin = min;
alarmtime = weekDayFullName + ", " + monthFullName + " " + date + ", " + year + " " + hour12 + ":" + pickerMin + " " + AM_PM;
alarmText.setText("Send Date: " + alarmtime);
}
public void onCancel() {}
});
customDT.set24HourFormat(false);
customDT.setDate(Calendar.getInstance());
findViewById(R.id.startTimeSetDialog).setOnClickListener(new OnClickListener()
{
public void onClick(View v) {
customDT.showDialog();
}
});
// Setup global variables
phoneName = (EditText)findViewById(R.id.phoneNo);
messageText = (EditText)findViewById(R.id.txtMessage);
sendButt = (Button)findViewById(R.id.btnSendSMS);
alarmText = (TextView)findViewById(R.id.alarmPrompt);
//Create/Find DB
mDbHelper = new MessagesHelper(this);
// Start Contact finder
phoneName.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, CONTACT_PICKER_RESULT);
}
});
// "Send" the message
sendButt.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v) {
//Make sure the fields are filled
if (phoneName.getText().toString().trim().length() == 0)
{
Toast.makeText(getApplicationContext(), "Please enter a phone number", Toast.LENGTH_LONG).show();
return;
}
if (messageText.getText().toString().trim().length() == 0)
{
Toast.makeText(getApplicationContext(), "Please enter your message", Toast.LENGTH_LONG).show();
return;
}
//Create a calendar variable that equates to the desired time to be sent
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, pickerYear);
cal.set(Calendar.MONTH, pickerMonth);
cal.set(Calendar.DATE, pickerDay);
cal.set(Calendar.HOUR_OF_DAY, pickerHour);
cal.set(Calendar.MINUTE, pickerMin);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
//Set up the pending intent and assign put it in the alarm manger
//will change this process once db is set up proper
Intent sIntent = new Intent(MainActivity.this, SendTService.class);
sIntent.putExtra("phoneNo", phoneNum.toString());
sIntent.putExtra("msgTxt", messageText.getText().toString());
PendingIntent psIntent = PendingIntent.getService(MainActivity.this,0, sIntent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), psIntent);
//Add the latest message to the db
SQLiteDatabase db = mDbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Messages.Texts.COLUMN_NAME_MESSAGE, messageText.getText().toString());
values.put(Messages.Texts.COLUMN_NAME_RECIPIENT, phoneNum.toString());
values.put(Messages.Texts.COLUMN_NAME_SEND_TIME, cal.toString());
db.insert(Messages.Texts.TABLE_NAME, null, values);
//Clear all the fields and let the user know what's going on
phoneName.setText("");
messageText.setText("");
alarmText.setText("");
Toast.makeText(getApplicationContext(), "Your Message will be sent on " + alarmtime, Toast.LENGTH_LONG).show();
}
});
}
//Associated with the Contact picker getting it's results
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case CONTACT_PICKER_RESULT:
Cursor cursor = null;
String phoneNumber = "";
List<String> allNumbers = new ArrayList<String>();
int phoneIdx = 0;
try {
Uri result = data.getData();
String id = result.getLastPathSegment();
cursor = getContentResolver().query(Phone.CONTENT_URI, null, Phone.CONTACT_ID + "=?", new String[] { id }, null);
phoneIdx = cursor.getColumnIndex(Phone.DATA);
if (cursor.moveToFirst())
{
while (cursor.isAfterLast() == false)
{
phoneNumber = cursor.getString(phoneIdx);
allNumbers.add(phoneNumber);
cursor.moveToNext();
}
}
else
{
//no results actions
}
}
catch (Exception e)
{
//error actions
}
finally
{
if (cursor != null) cursor.close();
final CharSequence[] items = allNumbers.toArray(new String[allNumbers.size()]);
AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
builder.setTitle("Choose a number");
builder.setItems(items, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
phoneNum = items[item].toString();
phoneNum = phoneNum.replace("-", "");
phoneName.setText(phoneNum);
}
});
AlertDialog alert = builder.create();
if(allNumbers.size() > 1)
{
alert.show();
}
else
{
phoneNum = phoneNumber.toString();
phoneNum = phoneNum.replace("-", "");
phoneName.setText(phoneNum);
}
if (phoneNumber.length() == 0)
{
//no numbers found actions
}
}
break;
}
}
else
{
//activity result error actions
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}