简体   繁体   English

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

[英]Android: How to run service when screen is lock?

I m developing an android app in which I want to display a toast during incoming call my app is running fine when screen is unlocked. 我正在开发一个Android应用程序,其中我想在来电期间显示吐司我的应用程序在屏幕解锁时正常运行。 But its not displaying anything when home screen is locked, can anyone help me. 但是当主屏幕被锁定时它没有显示任何内容,任何人都可以帮助我。

Here is my whole code 这是我的整个代码

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");
        }
    }

}

This is my service to detect call 这是我检测呼叫的服务

 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;
        }
    }

And this is another 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);
    }

}

And here is the manifest file 这是清单文件

<?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>

The code you wrote will not work for new devices when the screen is locked because now android takes care of the battery drains. 当屏幕被锁定时,您编写的代码将无法用于新设备,因为现在Android负责电池电量消耗。 And so it will not allow a background service to run with the receiver. 因此它不允许后台服务与接收器一起运行。 But still, if you want to do this, follow these steps: 但是,如果您想这样做,请按照下列步骤操作:

  • Step 1) Make receiver 步骤1)制作接收器
  • Step 2) Start the service/activity or any task on onReceive method rather than continuously running it as receivers are meant to do this task. 步骤2)启动服务/活动或onReceive方法上的任何任务,而不是连续运行它,因为接收器意味着执行此任务。

Like: 喜欢:

    @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); 其中SendValue(Context c,String incomingNumber); is a constructor of other Java class to do the needful task when call is received and incommingNumber is a global String variable so that its value can be altered when call is received. 是接收调用时执行必要任务的其他Java类的构造函数,incommingNumber是一个全局String变量,以便在接收到调用时可以更改其值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM