0

我想编写一个位于“共享方式”菜单中的应用程序(用于快速向自己发送电子邮件链接到我在网络上找到的内容或在 RSS 阅读器中查看的内容)为此,我使用 intent.action.SEND 声明我的应用程序意图过滤器:

    <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 包的骨架

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);

// real code here grabs URL from intent then emails it as an asyncTask:
    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 = "";
      // Real code here sends the email
      // Simulate waiting for the email to be sent:
      try { 
          Thread.sleep(5000);
          response = "Waited";
      }
      catch (InterruptedException ex) {  }

      return response;
    }

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

}

问题是我的应用程序正在浏览器顶部打开(出现一个白色屏幕,标题栏显示应用程序的名称) - 这会阻止浏览器访问,直到“等待”完成(因此破坏了目的将我的 sendEmail 功能包装在 asyncTask 中)。

请参阅:问题演示的截屏视频

请参阅:完整代码的相关问题

谁能告诉我如何让我的应用程序启动(从“共享方式”菜单)并执行我的代码,但实际上没有“视图”(如果这是空白屏幕和标题栏的正确术语)?

4

2 回答 2

1
  1. 在没有任何 UI 的情况下启动活动
  2. 在 OnCreate 中启动一个服务来做你的后台服务
  3. 开始服务后立即完成活动
  4. 让服务发布通知或 Toast 完成。

如果您确实想显示一个对话框,您可以只使用来自服务的对话框启动一个单独的活动,但显示对话框通常是侵入性的。

于 2012-12-05T17:20:29.073 回答
0

感谢 Nandeesh 让我走上了正确的道路。对于那些想确切知道如何做到这一点的人,这里是完整的解决方案:

1:在没有任何 UI 的情况下启动一个活动 我在 AndroidManifest 中使用了以下主题:

android:theme="@android:style/Theme.NoDisplay"

这使得初始应用程序不仅透明,而且完全没有 UI

2:在 OnCreate 中启动一个服务来执行您的后台服务在 这里,我仍然必须从 Share Intent 中“获取” URL,并将其作为 Extra 传递给该服务:

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

    // get url
    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";
           }

    // prepare service
    Intent emailSendIntent = new Intent(getApplicationContext(), EmailSendService.class);
    emailSendIntent.putExtra("extraData", url);
    startService(emailSendIntent);

    finish();
   }

}

3:开始服务后立即完成活动 - 见上文

请注意,在服务中,Extras 被传递给 OnStart 方法(而不是预期的 On Create 方法)请参阅: 链接

4:让服务发布通知或Toast关于完成。 我无法让服务打开对话框通知(根据我的原始应用程序),这不断使应用程序/服务崩溃,但 Toast 效果很好 - 正如 Nandeesh 所建议的那样,它可能不那么具有侵入性。

这是服务包:

public class EmailSendService extends Service {

String url;
String message;


@Override
public IBinder onBind(Intent arg0) {
    return null;
}

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

}


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

@Override 
public void onStart(Intent intent, int startId) {
      super.onStart(intent, startId);
      url = intent.getExtras().getString("extraData");

      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);
                message = "Email sent";
            } catch (Exception e) {
                message = "Error sending email";
            }
        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
    }

}

注意。记得在清单中声明服务(在应用程序标签内):

    <service
        android:name=".EmailSendService"
        android:label="CheckIt EmailSendService" >
    </service>
于 2012-12-06T11:14:35.607 回答