2015-09-20 123 views
0

我运行下面的后台服务:无法停止后台服务的Android

public class TranslationService extends IntentService implements ClipboardManager.OnPrimaryClipChangedListener { 

    private Language mFrom; 
    private Language mTo; 
    private String mTranslation; 
    private ClipboardManager mClipboardManager; 

    public TranslationService() { 
     super("hello"); 
    } 

    public TranslationService(String name) { 
     super(name); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 

    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     mFrom = (Language) intent.getSerializableExtra(MainActivity.FROM_STRING); 
     mTo = (Language) intent.getSerializableExtra(MainActivity.TO_STRING); 
     mClipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); 
     mClipboardManager.addPrimaryClipChangedListener(this); 

     return super.onStartCommand(intent, flags, startId); 
    } 

    @Override 
    public void onPrimaryClipChanged() { 

     ClipData clip = mClipboardManager.getPrimaryClip(); 
     String copiedText = clip.getItemAt(0).getText().toString(); 
     connectToTranslationApi(copiedText); 

     //TODO solve concurrency problems if app works inconsistently. 
     try { 
      Thread.sleep(500); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

      new Handler(Looper.getMainLooper()).post(new Runnable() { 
       @Override 
       public void run() { 
        Toast.makeText(getBaseContext(), mTranslation, Toast.LENGTH_SHORT).show(); 
       } 
      }); 

    } 

    private void connectToTranslationApi(String copiedPhrase) { 

     String apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxx"; 
     String fromInitials = mFrom.initials; 
     String toInitials = mTo.initials; 
     String yandexUrl = "https://translate.yandex.net/api/v1.5/tr.json/translate?key="+ 
       apiKey + "&lang=" + 
       fromInitials + "-" + toInitials + 
       "&text="+ copiedPhrase; 

     OkHttpClient okHttpClient = new OkHttpClient(); 
     Request request = new Request.Builder().url(yandexUrl).build(); 
     Call call = okHttpClient.newCall(request); 
     call.enqueue(new Callback() { 
      @Override 
      public void onFailure(Request request, IOException e) { 
       //TODO handle failure 
      } 

      @Override 
      public void onResponse(Response response) throws IOException { 
       if (response.isSuccessful()) { 
        String jsonData = response.body().string(); 
        try {mTranslation = getTextTranslation(jsonData);} 
        catch (JSONException e) {e.printStackTrace();} 
       } 
      } 
     }); 
    } 

    private String getTextTranslation(String jsonData) throws JSONException { 
     JSONObject data = new JSONObject(jsonData); 
     String translation = data.getString("text"); 
     translation = translation.replace("]", "") 
        .replace("[", "") 
        .replace("\"", ""); 
     return translation; 
    } 

} 

该服务在后台运行,并翻译,我复制到剪贴板(甚至当我使用其他应用程序文本服务只会停止,如果我删除从RAM启动它的应用程序),这一切都很好。

但是,当我回到应用程序的主要活动并按下“停止服务”它不会停止。这里是开始(并应该停止)服务的代码

  if(mIsServiceRunning == false) { 
      Intent i = new Intent(MainActivity.this, TranslationService.class); 
      i.putExtra(FROM_STRING, mLanguageFrom); 
      i.putExtra(TO_STRING, mLanguageTo); 
      startService(i); 
      mIsServiceRunning = true; 
      startButton.setText("Stop Service"); 
      Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show(); 
     } 
     else { 
      Intent i = new Intent(MainActivity.this, TranslationService.class); 
      stopService(i); 
      mIsServiceRunning = false; 
      startButton.setText("Start Service"); 
     } 

任何想法如何阻止它?

+0

你怎么知道它不停止? – JozeRi

回答

0

我并非确切地确定您确定您的服务是否仍在运行。 但我建议不要将其基于mIsServiceRunning布尔值。

,你可以用这个方法来确保它的运行与否:

public static boolean isServiceRunning(Class<?> serviceClass) { 
    ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 
    for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { 
    if (serviceClass.getName().equals(service.service.getClassName())) { 
     return true; 
    } 
    } 
    return false; 
} 

此方法将返回一个布尔值,它会告诉你,如果该服务在后台运行与否, 你可以使用它像这样例如:

if (isServiceRunning(TranslationService.class)) { 
    Toast.makeText(this, "Service is Running", Toast.LENGTH_SHORT).show(); 
} else { 
    Toast.makeText(this, "Service is NOT Running", Toast.LENGTH_SHORT).show(); 
} 

也许我错过了它,但我没有看到您的代码中有任何错误。

context.stopService(new Intent(context, TranslationService.class)); 

应该停止您的服务。

希望可以帮助你,如果不是,尝试并在尝试后提供更多信息。

+0

那么,每次我复制到剪贴板时,翻译仍会弹出并执行方法顺便说一句,在你建议的代码中,在WorkoutApplication.getInstance()中,我应该如何替换WorkoutApplication? –

+0

aw对不起,对不起,对不起,我不知道它是否可以运行。 ,我会编辑它,WorkoutApplication.getInstance()是上下文。 – JozeRi

0

存在内存泄漏,因为您留下了剪贴板方法而没有破坏它。 您需要为清除剪贴板的对象听众从RAM后,特定活动destroyed.Despite服务停止,但在memory.You运行此剪贴板方法需要停止这段代码

clipboardManager.removePrimaryClipChangedListener(监听);

on whatever onDestroy(),onPause()方法。

试着去了解这下面的代码

public class MySecretService extends Service { 

ClipboardManager clipboardManager; 
ClipData clipData; 
ClipData.Item item; 
String text; 
//declare Listener 
ClipboardManager.OnPrimaryClipChangedListener listener; 

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

@Override 
public void onCreate() { 
    Toast.makeText(this, "Service is Started !!!", Toast.LENGTH_SHORT).show(); 
    clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); 

} 


@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 

    Toast.makeText(this, "Service is Created !!! ", Toast.LENGTH_SHORT).show(); 
    //fire intent 
    intent = new Intent(MySecretService.this, DictionaryActivity.class); 
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

    final Intent finalIntent = intent; 

    //asign listener to onPrimaryClipChangedListner 
    clipboardManager.addPrimaryClipChangedListener(listener = new ClipboardManager.OnPrimaryClipChangedListener() { 
     @Override 
     public void onPrimaryClipChanged() { 
      clipData = clipboardManager.getPrimaryClip(); 
      item = clipData.getItemAt(0); 
      try { 
       text = item.getText().toString(); 

      } catch (NullPointerException e) { 
       Toast.makeText(MySecretService.this, "exception " + e, Toast.LENGTH_SHORT).show(); 
      } 
      Toast.makeText(MySecretService.this, "Text is Copiyed " + text, Toast.LENGTH_SHORT).show(); 

      //startActivity when copy triggered on text 
      startActivity(finalIntent); 
     } 

    }); 


    return super.onStartCommand(intent, flags, startId); 
} 


@Override 
public void onDestroy() { 
    super.onDestroy(); 
    // DictionaryActivity.finishAll(); 
    Toast.makeText(this, "Service is Destroyed !!! ", Toast.LENGTH_SHORT).show(); 

    //free from memroy 
    clipboardManager.removePrimaryClipChangedListener(listener); 

}} 
0

我做我注意到,只要应用程序在运行服务的内存缓存同样的事情。我将尝试在服务中添加if语句以检查首选项/设置,以便即使运行或缓存的服务将检查共享首选项并决定是继续还是停止。 (这是不好的检查,如果它关闭,但我不能找到其他的东西