Android:屏幕锁定时如何运行服务?

时间:2016-06-14 09:31:34

标签: android service android-service android-screen android-background

我正在开发一个Android应用程序,其中我想在来电期间显示一个吐司我的应用程序在屏幕解锁时正常运行。但是当主屏幕被锁定时它没有显示任何内容,任何人都可以帮助我。

这是我的整个代码

package com.example.lenovo.call_toast;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.PowerManager;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;


public class MainActivity_service extends Activity {

    private boolean detectEnabled;

    private TextView textViewDetectState;
    private Button buttonToggleDetect;
    private Button buttonExit;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        PowerManager mgr = (PowerManager)getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
        wakeLock.acquire();

        textViewDetectState = (TextView) findViewById(R.id.textViewDetectState);

        buttonToggleDetect = (Button) findViewById(R.id.buttonDetectToggle);
        buttonToggleDetect.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                setDetectEnabled(!detectEnabled);
            }
        });

        buttonExit = (Button) findViewById(R.id.buttonExit);
        buttonExit.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                setDetectEnabled(false);
                MainActivity_service.this.finish();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    private void setDetectEnabled(boolean enable) {
        detectEnabled = enable;

        Intent intent = new Intent(this, CallDetectService.class);
        if (enable) {
             // start detect service




            startService(intent);

            buttonToggleDetect.setText("Turn off");
            textViewDetectState.setText("Detecting");
        }
        else {
            // stop detect service
            stopService(intent);

            buttonToggleDetect.setText("Turn on");
            textViewDetectState.setText("Not detecting");
        }
    }

}

这是我检测电话的服务

 package com.example.lenovo.call_toast;

    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;


    public class CallDetectService extends Service {
        private CallHelper callHelper;

        public CallDetectService() {
        }

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            callHelper = new CallHelper(this);

            int res = super.onStartCommand(intent, flags, startId);
            callHelper.start();
            return res;
        }

        @Override
        public void onDestroy() {
            super.onDestroy();

            callHelper.stop();
        }

        @Override
        public IBinder onBind(Intent intent) {
            // not supporting binding
            return null;
        }
    }

这是另一个班级

package com.example.lenovo.call_toast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;


public class CallHelper {

    /**
     * Listener to detect incoming calls. 
     */
    private class CallStateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {

            switch (state) {
            case TelephonyManager.CALL_STATE_RINGING:
                // called when someone is ringing to this phone

                Toast.makeText(ctx,
                        "Incoming: " +incomingNumber,
                        Toast.LENGTH_LONG).show();

                break;

            }
        }
    }

    /**
     * Broadcast receiver to detect the outgoing calls.
     */
    public class OutgoingReceiver extends BroadcastReceiver {
        public OutgoingReceiver() {
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
            Log.e( "onCallStateChanged: ",number );
            Toast.makeText(ctx,"Outgoing: "+number,
                    Toast.LENGTH_LONG).show();
        }

    }

    private Context ctx;
    private TelephonyManager tm;
    private CallStateListener callStateListener;

    private OutgoingReceiver outgoingReceiver;

    public CallHelper(Context ctx) {
        this.ctx = ctx;

        callStateListener = new CallStateListener();
        outgoingReceiver = new OutgoingReceiver();
    }

    /**
     * Start calls detection.
     */
    public void start() {
        tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
        tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);

        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
        ctx.registerReceiver(outgoingReceiver, intentFilter);

    }

    /**
     * Stop calls detection.
     */
    public void stop() {
        tm.listen(callStateListener, PhoneStateListener.LISTEN_NONE);
        ctx.unregisterReceiver(outgoingReceiver);
    }

}

这是清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.lenovo.call_toast">

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK"/>



    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity_service">
            <intent-filter>-->
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!--<activity android:name=".MyCustomDialog"-->
            <!--android:theme="@android:style/Theme.Dialog"-->
            <!--android:noHistory="true"-->
            <!--/>-->
        <!--&lt;!&ndash;<receiver android:name=".CallReceiver" >&ndash;&gt;-->
            <!--&lt;!&ndash;<intent-filter>&ndash;&gt;-->
                <!--&lt;!&ndash;<action android:name="android.intent.action.PHONE_STATE" />&ndash;&gt;-->
            <!--&lt;!&ndash;</intent-filter>&ndash;&gt;-->
            <!--&lt;!&ndash;<intent-filter>&ndash;&gt;-->
                <!--&lt;!&ndash;<action android:name="android.intent.action.NEW_OUTGOING_CALL" />&ndash;&gt;-->
            <!--&lt;!&ndash;</intent-filter>&ndash;&gt;-->
        <!--</receiver>-->

        <service android:name=".CallDetectService"

            android:enabled="true"
            android:exported="false"/>

    </application>


</manifest>

1 个答案:

答案 0 :(得分:0)

当屏幕被锁定时,您编写的代码将不适用于新设备,因为现在Android负责电池电量消耗。因此它不允许后台服务与接收器一起运行。但是,如果您想这样做,请按照以下步骤操作:

  • 步骤1)制作接收器
  • 步骤2)启动onReceive方法上的服务/活动或任何任务 而不是连续运行它,因为接收器意味着要完成这项任务。

像:

    @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
    {

    Bundle bb = intent.getExtras();  
          String state = bb.getString(TelephonyManager.EXTRA_STATE);
          if ((state != null)&& (state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING)))     
          {
              incommingNumber = bb.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
    blockCall(context, bb);
    }
    }

    public void blockCall(Context c, Bundle b)
    {

      TelephonyManager telephony = (TelephonyManager) 
      c.getSystemService(Context.TELEPHONY_SERVICE);  
      try {
       Class cls = Class.forName(telephony.getClass().getName());
       Method m = cls.getDeclaredMethod("getITelephony");
       m.setAccessible(true);
       telephonyService = (ITelephony) m.invoke(telephony);
       //telephonyService.silenceRinger();
       telephonyService.endCall();

          new SendValue(c,incommingNumber);

      } catch (Exception e) {
       e.printStackTrace();
      }
}

SendValue(Context c,String incomingNumber);是接收调用时执行必要任务的其他Java类的构造函数,incommingNumber是一个全局String变量,以便在接收到调用时可以更改其值。