【问题标题】:'Share via' application that runs without a View在没有视图的情况下运行的“共享方式”应用程序
【发布时间】:2012-12-05 17:10:36
【问题描述】:

我想编写一个位于“共享方式”菜单中的应用程序(用于快速通过电子邮件向自己发送指向我在网络上找到的内容或在 RSS 阅读器中查看的内容的链接)为此,我声明我的应用程序是有意图的。 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 中的目的)。

见:screencast for demo of problem

见:related question with full code

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

【问题讨论】:

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


    【解决方案1】:
    1. 在没有任何 UI 的情况下启动活动
    2. 在 OnCreate 中启动一个服务来执行您的后台服务
    3. 一启动服务就结束活动
    4. 让服务发布关于完成的通知或 Toast。

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

    【讨论】:

    • 感谢 Nandeesh 让我走上了正确的道路。多一点指导会有所帮助:) 但是通过按照您的步骤并制定如何实施它们,我学到了很多东西。对于那些想确切知道如何做的人,我添加了一个完整的解决方案作为附加答案。
    【解决方案2】:

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

    1:在没有任何 UI 的情况下启动 Activity 为此,我在 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 方法)请参阅: link

    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>
    

    【讨论】:

      猜你喜欢
      • 2018-04-18
      • 1970-01-01
      • 2016-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多