OnClickListener
ビューにリンクされたものから電子メールを送信するには、かなり単純な方法を使用します。
TextView emailAddr = (TextView) findViewById(R.id.tvEmailAddr);
emailAddr.setOnClickListener(emailClick);
同じアクティビティで、次のものがありOnClickListener
ます。
final OnClickListener emailClick = new OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_SENDTO,
Uri.parse("dearjohn@acme.com"));
intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.contactsEMailSubject));
startActivity(intent);
}
};
注: 匿名のリスナーを使用してこのセットアップを行ったところ、まったく同じ結果が得られました。
デフォルトの電子メール アプリがない場合、ユーザーには選択ウィンドウが表示されます。彼らが電子メールを送信し続ける場合はすべて問題ありませんが、そうでない場合は選択ダイアログをキャンセルし、アプリがクラッシュします。
refreshData()
この問題は、メソッド ( から呼び出される)で進行状況ダイアログを表示しようとしたことに起因することがわかりましたonResume()
。
私のprogressDialogコードは次のようになります:
public class HttpProgressDlg extends DialogFragment
implements OnCancelListener, OnDismissListener {
interface HttpProgressDlgCancelListener {
void onCancelHttpProgressDlg();
}
public HttpProgressDlg() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedinstanceState){
View view = inflater.inflate(R.layout.http_progress, container);
getDialog().setTitle(getString(R.string.dlgProgressTitle));
getDialog().setOnCancelListener(this);
return view;
}
@Override
public void onCancel(DialogInterface dialog) {
HttpProgressDlgCancelListener activity = (HttpProgressDlgCancelListener) getActivity();
activity.onCancelHttpProgressDlg(); // tell activity to cancel http request
this.dismiss(); // "close" the dialog
}
そしてそれを使用しようとするコード:
protected void showProgressDialog() {
FragmentManager fragmentMgr = getSupportFragmentManager();
httpProgressDlg = new HttpProgressDlg();
httpProgressDlg.show(fragmentMgr, "http_progress");
}
getSupportFragmentManager()
問題はnullを返すことだと思いました。(はい、私はそれを確認することができ、私は持っています - それについては後で詳しく説明します)
ユーザーが選択ダイアログをキャンセルしたときに何が起こるかというと、Android はもちろんアクティビティを再開したいということです。私のトレースは私を 1 に連れて行きますonSaveInstanceState
。2. onResume
- ビューのテキストを設定し、別のビューを非表示または表示してから、refreshData を呼び出しますshowProgressDialog()
。
今回はコードが呼び出されるたびに null を返しますが、実際にトレース/デバッグ プロセスを引きずり出す場合を除き、正常に動作します。これがnullを返すプロセスがあるようです。
LogCat は、呼び出し後に不正な状態になっているという奇妙なメッセージを表示しますonSavewInstanceState
。
08-15 10:49:55.187: D/AndroidRuntime(16016): Shutting down VM
08-15 10:49:55.187: W/dalvikvm(16016): threadid=1: thread exiting with uncaught exception (group=0x41b682a0)
08-15 10:49:55.227: E/AndroidRuntime(16016): FATAL EXCEPTION: main
08-15 10:49:55.227: E/AndroidRuntime(16016): java.lang.RuntimeException: Unable to resume activity {com.viterra.glencoregrain/com.viterra.glencoregrain.MainActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
08-15 10:49:55.227: E/AndroidRuntime(16016): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2616)
08-15 10:49:55.227: E/AndroidRuntime(16016): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2644)
08-15 10:49:55.227: E/AndroidRuntime(16016): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1269)
08-15 10:49:55.227: E/AndroidRuntime(16016): at android.os.Handler.dispatchMessage(Handler.java:99)
08-15 10:49:55.227: E/AndroidRuntime(16016): at android.os.Looper.loop(Looper.java:137)
08-15 10:49:55.227: E/AndroidRuntime(16016): at android.app.ActivityThread.main(ActivityThread.java:4898)
08-15 10:49:55.227: E/AndroidRuntime(16016): at java.lang.reflect.Method.invokeNative(Native Method)
08-15 10:49:55.227: E/AndroidRuntime(16016): at java.lang.reflect.Method.invoke(Method.java:511)
08-15 10:49:55.227: E/AndroidRuntime(16016): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
08-15 10:49:55.227: E/AndroidRuntime(16016): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
08-15 10:49:55.227: E/AndroidRuntime(16016): at dalvik.system.NativeStart.main(Native Method)
08-15 10:49:55.227: E/AndroidRuntime(16016): Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
08-15 10:49:55.227: E/AndroidRuntime(16016): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1327)
08-15 10:49:55.227: E/AndroidRuntime(16016): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1338)
08-15 10:49:55.227: E/AndroidRuntime(16016): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
08-15 10:49:55.227: E/AndroidRuntime(16016): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
08-15 10:49:55.227: E/AndroidRuntime(16016): at android.support.v4.app.DialogFragment.show(DialogFragment.java:127)
08-15 10:49:55.227: E/AndroidRuntime(16016): at com.viterra.glencoregrain.GlencoreBaseActivity.showProgressDialog(GlencoreBaseActivity.java:274)
08-15 10:49:55.227: E/AndroidRuntime(16016): at com.viterra.glencoregrain.MainActivity.refreshData(MainActivity.java:113)
08-15 10:49:55.227: E/AndroidRuntime(16016): at com.viterra.glencoregrain.GlencoreBaseActivity.onResume(GlencoreBaseActivity.java:103)
08-15 10:49:55.227: E/AndroidRuntime(16016): at com.viterra.glencoregrain.MainActivity.onResume(MainActivity.java:41)
08-15 10:49:55.227: E/AndroidRuntime(16016): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1188)
08-15 10:49:55.227: E/AndroidRuntime(16016): at android.app.Activity.performResume(Activity.java:5280)
08-15 10:49:55.227: E/AndroidRuntime(16016): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2606)
08-15 10:49:55.227: E/AndroidRuntime(16016): ... 10 more
08-15 10:50:09.132: I/Process(16016): Sending signal. PID: 16016 SIG: 9
このように、null 以外の値が返されるまでループが終了しないように、ループを配置しました (理解をテストするためだけに)。
FragmentManager fragmentMgr = null;
while (fragmentMgr == null) {
fragmentMgr = getSupportFragmentManager();
}
httpProgressDlg = new HttpProgressDlg();
httpProgressDlg.show(fragmentMgr, "http_progress");
その後、コードはクラッシュする部分に進みhttpProgressDlg.show(...)
ます...これはまったくわかりません。他のアクティビティに移動して戻る (また、「startActivity(intent...」コードを使用しても) このクラッシュは発生しません。セレクターをキャンセルした場合のみです。