使用钛模块启动android原生服务



我用以下服务类启动了一个移动模块项目:

package com.eliddell.testservice;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import org.appcelerator.titanium.TiBaseService;
import org.appcelerator.kroll.common.Log;
import android.app.ActivityManager;
import android.app.Service;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;

import android.net.wifi.WifiManager;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.IBinder;
import android.text.format.Time;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class ForegroundService extends Service {
    /* (non-Javadoc)
     * @see android.app.Service#onBind(android.content.Intent)
     */
    Timer timer;
    WindowManager.LayoutParams handleParams;
    WindowManager.LayoutParams indiParams;
    View disableStatusBar;
    WindowManager winMgr;
    int interval = 50;
    Handler mHandler;
    Boolean secDialog = false;

    ArrayList<String> allowedApps;
    int scale = -1;
    int level = -1;
    int charging = 0;
    BroadcastReceiver batteryReceiver;
    @Override
    public void onCreate() {
        Log.v("Nav Service: ", "{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{CREATED");
        // Start up the thread running the service.  Note that we create a
        // separate thread because the service normally runs in the process's
        // main thread, which we don't want to block.  We also make it
        // background priority so CPU-intensive work will not disrupt our UI.
        allowedApps = new ArrayList<String>();
        /*allowedApps.add("com.sapientnitro.lcinstore2");//LC
        allowedApps.add("com.adobe.reader");//acrobat
        allowedApps.add("com.dynamixsoftware.printershare");//printer share
        allowedApps.add("my.handrite.prem");//HandRite Pro
       */
        mHandler = new Handler();
        //batMan = new BatteryManager();
        winMgr = (WindowManager) getSystemService(WINDOW_SERVICE);
        //cTime = new Time(Time.getCurrentTimezone());


    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.v("Nav Service: ", "{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{started");
        disableStatusBar = new RelativeLayout(getApplicationContext());
        handleParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.FILL_PARENT, 50,
        // This allows the view to be displayed over the status bar
        // WindowManager.LayoutParams.TYPE_SYSTEM_ALERT |  
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                // this is to keep button presses going to the background window
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
                        // this is to enable the notification to recieve touch events
                        WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
                        // Draws over status bar
                        WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
                PixelFormat.TRANSPARENT);
        handleParams.gravity = Gravity.TOP;
        handleParams.y = 50;

        disableStatusBar.setBackgroundColor(0xffff0000);
        winMgr.addView(disableStatusBar, handleParams);


        statusChecker.run();
        // If we get killed, after returning from here, restart
        return START_REDELIVER_INTENT;
    }
    @Override
    public IBinder onBind(Intent intent) {
        // We don't provide binding, so return null
        return null;
    }
    @Override
    public void onDestroy() {
        unregisterReceiver(batteryReceiver);
        mHandler.removeCallbacks(statusChecker);
        winMgr.removeView(disableStatusBar);
        //Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); 
    }

    Runnable statusChecker = new Runnable() {
        public void run() {
            mHandler.postDelayed(statusChecker, interval);
        }
    };


    private void monitorUser() {
        String cProcess;
        try {
            ActivityManager am = (ActivityManager) getApplicationContext().getSystemService(
                    Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningTaskInfo> processList = am.getRunningTasks(5);
            //screen capture tool
            am.killBackgroundProcesses("com.diotek.screen_capture");
            cProcess = processList.get(0).baseActivity.getPackageName();
            //Log.v("","--------------------------------------------------------------------------------"+cProcess);
            if (cProcess.equals("com.android.settings")) {
                launchSecurity();
            } else if(!allowedApps.contains(cProcess)){
               goHome();
            }

            Object service = getSystemService("statusbar");
            Class<?> statusbarManager = Class.forName("android.app.StatusBarManager");
            Method collapse = statusbarManager.getMethod("collapse");
            Method disable = statusbarManager.getMethod("disable", Integer.TYPE);
            collapse.setAccessible(true);
            // disable.invoke(service,1);
            //collapse .invoke(service);
        } catch (Exception ex) {
            Log.v("WINDOW CHANGE", "exemption:" + ex);
        }
    }
    public void launchSecurity() {

            Log.v("LAUNCHING", "((((((((((((((((((((SECURITY)))))))))))))))))");
            Intent i = new Intent("com.eliddell.testservice.activities.AUTHENTICATE");
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(i);
    }
    private boolean isSecurityServiceRunning() {
        ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if ("com.eliddell.services_test.services.SecurityService".equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }
    public void goHome(){
        Intent startMain = new Intent(Intent.ACTION_MAIN);
        startMain.addCategory(Intent.CATEGORY_HOME);
        startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(startMain);
       /* Intent i = new Intent(Intent.ACTION_VIEW);
        i.setComponent(new ComponentName("com.sapientnitro.lcinstore2",
                "com.sapientnitro.lcinstore2.activities.MainActivity"));
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(i);*/
    }
}

我的模块加载到我的Titanium应用程序中很好,模块中调用服务的kroll方法看起来像这个

@Kroll.method
    public void startForegroundService()
    {                  
        Log.v("{{{{{{{{{{{{{{{{{", "ATTEMPTING TO start service");

        try{
            backOverlayService = new Intent();
            backOverlayService.setClassName("com.eliddell.testservice", "ForegroundService.class");
            //start it
            //this.getActivity().getApplicationContext().startService(backOverlayService);
            TiApplication.getInstance().startService(backOverlayService);
            Log.v("TestserviceModule{{{{{{{", "TRY SUCCESS");
        }catch(Exception ex)
        {
            Log.v("TestserviceModule{{{{{{{", "Exception caught:"+ex);
        }


    }

日志显示成功,但onCreate和onStart中实际服务的日志实际上从未启动。。

知道我做错了什么吗?

问题出在我设定意图的方式上。。

而不是:

backOverlayService = new Intent();
backOverlayService.setClassName("com.eliddell.testservice", "ForegroundService.class");

我使用:

backOverlayService = new Intent(TiApplication.getAppCurrentActivity(), ForegroundService.class);

最新更新