'分享'在没有View的情况下运行的应用程序

时间:2012-12-05 17:10:37

标签: android android-intent asynchronous android-asynctask android-view

我想写一个位于“分享通过”菜单中的应用程序(用于快速通过电子邮件发送自己的链接到我在网上找到的内容或在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

任何人都可以告诉我如何启动我的应用程序(从“共享通过”菜单)并执行我的代码,但实际上没有“查看”(如果这是空白屏幕和标题栏的正确术语)?

2 个答案:

答案 0 :(得分:1)

  1. 启动没有任何UI的活动
  2. 启动服务以在OnCreate中执行后台服务
  3. 启动服务后立即完成活动
  4. 让服务发布通知或Toast关于完成。
  5. 如果你想要显示一个对话框,你可以只使用来自服务的对话框开始一个单独的活动,但它通常会侵入显示对话框。

答案 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>
相关问题