我想写一个位于“分享通过”菜单中的应用程序(用于快速通过电子邮件发送自己的链接到我在网上找到的内容或在RSS阅读器中查看)为此我正在宣布我的应用程序。 action.SEND intent-filter:
<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);
}
}
}
问题是我的应用程序在浏览器顶部打开(出现一个白色屏幕,标题栏显示应用程序的名称) - 这阻止浏览器在“等待”完成之前可访问(因此在asyncTask中失败包装sendEmail功能的目的)。
请参阅:screencast for demo of problem
请参阅:related question with full code
任何人都可以告诉我如何启动我的应用程序(从“共享通过”菜单)并执行我的代码,但实际上没有“查看”(如果这是空白屏幕和标题栏的正确术语)?
答案 0 :(得分:1)
如果你想要显示一个对话框,你可以只使用来自服务的对话框开始一个单独的活动,但它通常会侵入显示对话框。
答案 1 :(得分:0)
感谢Nandeesh让我走上了正确的道路。对于那些想知道如何做到这一点的人来说,这是完整的解决方案:
1:启动没有任何UI的活动 要做到这一点,我在AndroidManifest中使用了以下主题:
机器人:主题= “@机器人:风格/ Theme.NoDisplay”
这使得初始应用程序不仅透明而且完全没有UI
2:启动服务以在OnCreate中执行后台服务 在这里,我仍然必须从共享意图中“抓取”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方法)请参阅: link
4:让服务发布通知或Toast关于完成。 我无法让服务打开一个Dialog通知(根据我的原始应用程序),这使应用程序/服务崩溃,但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();
}
}
NB。记得在清单中声明服务(在应用程序标记内):
<service
android:name=".EmailSendService"
android:label="CheckIt EmailSendService" >
</service>