0

「Share via」メニューにあるアプリを作成しました(Webで見つけたものやRSSリーダーで見たものへのリンクをすばやく自分にメールで送信するため)。 :

    <activity
        android:name="uk.co.baroquedub.checkit.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="text/plain" />
           </intent-filter>
    </activity>

MainActivity パッケージは、Intent からページ タイトルと URL を取得し、別の GMailSender クラスを使用してこの情報を直接メールで送信します。

package uk.co.baroquedub.checkit;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;

import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {

private static Dialog dialog;

String title;
String url;
String message;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent intent = getIntent();
    intent.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP );
    String action = intent.getAction();

    // if this is from the share menu
   if (Intent.ACTION_SEND.equals(action)) {   
           title = intent.getStringExtra(Intent.EXTRA_SUBJECT);
           url = intent.getStringExtra(Intent.EXTRA_TEXT);

           // Flipboard fix (remove title in URL)
           url = url.replace(title, "");

           if (url != null){
            url = title+"\n"+url;
           } else {
            url = "error getting URL";
           }

    // Asynch Task
                doSendTask task = new doSendTask();
                task.execute(new String[] { url });   

   }

}

protected void showDialog (String response){
dialog = new Dialog(this);
    dialog.setContentView(R.layout.dialog);
    dialog.setTitle(response);

    Button button = (Button) dialog.findViewById(R.id.Button01);
    button.setOnClickListener(new View.OnClickListener() {  
        @Override  
        public void onClick(View view) {  

            dialog.dismiss();   
            finish();
        }  
    });

    dialog.show();
}

private class doSendTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
      String response = "";

      String senderPassword = getResources().getString(R.string.senderPassword); 
      String senderEmail = getResources().getString(R.string.senderEmail); 
      String recipientEmail = getResources().getString(R.string.recipientEmail); 
      String subjectText = getResources().getString(R.string.subjectText);

      GMailSender sender = new GMailSender(senderEmail, senderPassword);
      try {
        sender.sendMail(subjectText,   
                url,   
                  senderEmail,   
                  recipientEmail);
            response = "Email sent";
        } catch (Exception e) {
            //Log.e("SendMail", e.getMessage(), e); 
            response = "Error sending email";
        }

      return response;
    }

    @Override
        protected void onPostExecute(String result) {
            showDialog(result);
    }
}

@Override
public void onDestroy() {
    super.onDestroy();

    /*
     * Kill application when the root activity is killed.
     */
    UIHelper.killApp(true);
}

}

バージョン 1 は問題なく動作しましたが、「onCreate」内からメールを送信していたため、「メールが送信されました」という通知が表示されるまで、携帯電話のブラウザが応答しなくなりました (スクロールしたり、新しいページに移動したりできませんでした)。次に、(上記のように) コードを変更して、電子メール送信コードを AsyncTask クラス内に配置しましたが、アプリは引き続き動作しますが、ダイアログが表示されるまでブラウザーは応答しません。AsyncTask は違いがないようです。

誰でも理由を説明できますか?解決策を提案してください。

4

4 に答える 4

1

答え?... 上記のコードを大幅に単純化して、何が問題なのかを突き止めました。ボグ標準アプリを作成し、以下を使用しました。

package uk.co.baroquedub.testcheck;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;

import android.widget.Toast;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    doSendTask task = new doSendTask();
    task.execute(new String[] { "urlString" });
}

protected void showDialog (String response){
    Toast.makeText(this, response, Toast.LENGTH_SHORT).show();
    finish();
}

private class doSendTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
      String response = "";

      try { 
          Thread.sleep(5000);
          response = "Waited";
      }
      catch (InterruptedException ex) {  }

      return response;
    }

    @Override
        protected void onPostExecute(String result) {
            showDialog(result);
    }
}

}

これにより、何が問題なのかを確認することができました: アプリがブラウザーの上に開いています (アプリの名前を示すタイトル バーが表示された白い画面が表示されます)。透明な背景を使用するテーマを使用していました。

参照:問題のデモのスクリーンキャスト

そのため、電子メールは AsyncTask として送信されていますが、これが発生している間、アプリ自体がブラウザーの上に表示されます。これが、アプリへのアクセスを妨げている原因です。(別の質問として、これに関するヘルプのリクエストを投稿します)

于 2012-12-05T16:54:31.040 に答える
0

ASyncTasks は、リファレンス ページに書かれているように、実際には独自のスレッドで実行されます。

このアクティビティのインテントを作成するときは、フラグ「FLAG_ACTIVITY_CLEAR_TOP」を渡します。これは、「...その上にある他のすべてのアクティビティが閉じられ、このインテントが (現在一番上にある) に配信されます」のようなものです。古いアクティビティを新しいインテントとして。これは、この新しいアクティビティが終了するまで、古いアクティビティがロックされているという意味ではありませんか?

于 2012-12-04T14:15:09.533 に答える
0

いいえ、AsyncTask は UI スレッドに結び付けられていないため、onCreate().

于 2012-12-04T13:37:05.877 に答える
0

コードに間違いがあると思います:

 doSendTask task = new doSendTask();
 task.execute(url); // if you want to put more urls  task.execute(url,url1,url2);
 try {
        sender.sendMail(subjectText,   
                url[0],             // get the first url
                  senderEmail,   
                  recipientEmail);
            response = "Email sent";
        } catch (Exception e) {
            //Log.e("SendMail", e.getMessage(), e); 
            response = "Error sending email";
        }
于 2012-12-04T13:58:17.240 に答える