Android: 如何运行锁屏服务?

Android: How to run service when screen is lock?

我正在开发一个 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;
        }
    }

这是另一个 class

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>

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

  • 第 1 步)制作接收器
  • 步骤 2) 在 onReceive 方法上启动 service/activity 或任何任务 而不是连续 运行 接收它,因为接收者应该执行此任务。

喜欢:

    @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();
      }
}

Where SendValue(Context c,String incomingNumber);是 other Java class 的构造函数,用于在收到调用时执行必要的任务,并且 incommingNumber 是一个全局字符串变量,以便在收到调用时可以更改其值。