本文介绍了如何在 Android 中覆盖两次甚至 3 次单击电源按钮甚至音量 UP/DOWN 键在后台使用服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个应用程序,我可以在 3-5 秒内听到 POWER_BUTTON 连续点击 3 次.

我已经搜索了所有 StackOverflow 的答案,但没有一个对我有用.

来自

3.在 Android 后台服务中注册和注销广播接收器

当您在活动中注册广播接收器时,活动退出后它将停止.

为了解决这个问题,我们将创建一个android服务对象,并在服务对象中注册和注销广播接收器.

因为android服务对象在activity退出后仍会在后台运行,所以广播接收器在android应用退出后仍会运行.

3.1 创建 Android 服务类.

3.1.1 创建一个扩展 android.app.Service 的 Java 类.

ScreenOnOffBackgroundService.java

import android.app.Service;导入 android.content.Intent;导入 android.content.IntentFilter;导入 android.os.IBinder;导入 android.support.annotation.Nullable;导入 android.util.Log;导入 ScreenOnOffReceiver;公共类 ScreenOnOffBackgroundService 扩展服务 {私有 ScreenOnOffReceiver screenOnOffReceiver = null;@Nullable@覆盖公共IBinder onBind(意图意图){返回空;}@覆盖public int onStartCommand(意图意图,int标志,int startId){return super.onStartCommand(intent, flags, startId);}@覆盖公共无效 onCreate() {super.onCreate();//创建一个 IntentFilter 实例.IntentFilter intentFilter = new IntentFilter();//添加网络连接更改操作.intentFilter.addAction("android.intent.action.SCREEN_ON");intentFilter.addAction("android.intent.action.SCREEN_OFF");//设置广播接收器优先级.intentFilter.setPriority(100);//创建一个网络更改广播接收器.screenOnOffReceiver = new ScreenOnOffReceiver();//使用意图过滤器对象注册广播接收器.注册接收器(screenOnOffReceiver,intentFilter);Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "Service onCreate: screenOnOffReceiver 已注册.");}@覆盖公共无效 onDestroy() {super.onDestroy();//销毁时注销 screenOnOffReceiver.if(screenOnOffReceiver!=null){取消注册接收器(screenOnOffReceiver);Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "Service onDestroy: screenOnOffReceiver 未注册.");}}}

3.1.2 在 AndroidManifest.xml 文件中添加服务 Xml 标签.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"包=放你自己的包"><申请机器人:allowBackup =真"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".broadcast.activity.ScreenOnOffActivity"><意图过滤器><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></意图过滤器></活动><service android:enabled="true" android:name=".broadcast.service.ScreenOnOffBackgroundService"/></应用程序></清单>

3.1.3 将活动 Java 代码更改为以下.

请注意启动服务对象的java代码.

Intent backgroundService = new Intent(getApplicationContext(), ScreenOnOffBackgroundService.class);启动服务(背景服务);

ScreenOnOffActivity.java

import android.content.Intent;导入 android.os.Bundle;导入 android.support.v7.app.AppCompatActivity;导入 android.util.Log;导入 com.dev2qa.example.R;导入 com.dev2qa.example.broadcast.receiver.ScreenOnOffReceiver;导入 com.dev2qa.example.broadcast.service.ScreenOnOffBackgroundService;公共类 ScreenOnOffActivity 扩展 AppCompatActivity {私有 ScreenOnOffReceiver screenOnOffReceiver = null;@覆盖protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_screen_on_off);setTitle("dev2qa.com - 应用退出后保持 BroadcastReceiver 运行.");Intent backgroundService = new Intent(getApplicationContext(), ScreenOnOffBackgroundService.class);启动服务(背景服务);Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "Activity onCreate");}@覆盖受保护的无效 onDestroy() {super.onDestroy();Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "Activity onDestroy");}}

再次运行示例,您可以看到下图.从logcat的输出中,我们可以看到android app退出后广播接收器仍在运行.

I am developing an application where I could listen to POWER_BUTTON clicked for 3 times consecutively in 3-5 seconds.

I have searched all the StackOverflow for answers but none of them has worked for me.

This answer from Lars D which should work on the activity doesn't work too though it is accepted.

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
    if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) {
        Intent i = new Intent(this, ActivitySetupMenu.class);
        startActivity(i);
        return true;
    }

    return super.dispatchKeyEvent(event);
}

There is an app that is intending to do this, I installed it but still, it doesn't work maybe the API they used are depreciated or even has been removed.

The Reasons why these solutions do not work :

  1. when the App gets killed/destroyed and it no longer detects.
  2. The screen is locked and again it no longer detects.
  3. Maybe the SDK does not support it.

Maybe we can find a way to do it on the activity but I want to listen to the actions using a service/broadcast Receiver while the app is killed/in the background/when screen locked/ when screen off.

Well, this question is definitely repeated many times on StackOverflow but no complete or working answer has been given.

解决方案

Since nobody tried to solve the question or maybe couldn't even understand the question, fortunately after many hours of searching the web I found this awesome website that solves exactly my problem and wanted to post it here too.

Problems which are solved now :

  1. My Application always runs in the background even if it is killed/destroyed or removed from the System Tray.
  2. The service always listens to the POWER_BUTTON when clicked.
  3. The SDK supports this since it uses only BroadCast Receivers and Services.

I am just writing down the steps in case the link may not work or be removed in future:

1.First we will create a broadcast receiver which can listen and process android screen on / off broadcast event as below.

ScreenOnOffReceiver.java

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class ScreenOnOffReceiver extends BroadcastReceiver {

private final static String SCREEN_TOGGLE_TAG = "SCREEN_TOGGLE_TAG";

@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    if(Intent.ACTION_SCREEN_OFF.equals(action))
    {
        Log.d(SCREEN_TOGGLE_TAG, "Screen is turn off.");
    }else if(Intent.ACTION_SCREEN_ON.equals(action))
    {
        Log.d(SCREEN_TOGGLE_TAG, "Screen is turn on.");
    }}
}

2. Register And Unregister ScreenOnOffReceiver In Activity.

Now we will create an activity and register ScreenOnOffReceiver in it’s onCreate() method, and unregister the receiver in it’s onDestroy() method as below.

ScreenOnOffActivity.java

import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.dev2qa.example.R;
import com.dev2qa.example.broadcast.receiver.ScreenOnOffReceiver;

public class ScreenOnOffActivity extends AppCompatActivity {

    private ScreenOnOffReceiver screenOnOffReceiver = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_screen_on_off);

        setTitle("dev2qa.com - Keep BroadcastReceiver Running After App Exit.");

        // Create an IntentFilter instance.
        IntentFilter intentFilter = new IntentFilter();

        // Add network connectivity change action.
        intentFilter.addAction("android.intent.action.SCREEN_ON");
        intentFilter.addAction("android.intent.action.SCREEN_OFF");

        // Set broadcast receiver priority.
        intentFilter.setPriority(100);

        // Create a network change broadcast receiver.
        screenOnOffReceiver = new ScreenOnOffReceiver();

        // Register the broadcast receiver with the intent filter object.
        registerReceiver(screenOnOffReceiver, intentFilter);

        Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "onCreate: screenOnOffReceiver is registered.");

    }

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

        // Unregister screenOnOffReceiver when destroy.
        if(screenOnOffReceiver!=null)
        {
            unregisterReceiver(screenOnOffReceiver);
            Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "onDestroy: screenOnOffReceiver is unregistered.");
        }
    }
}

Run Above Activity In Below Steps.

  1. Start the activity, there is a log message which said the broadcast receiver has been registered in the activity’s onCreate() method.
  2. Press the power button to turn off screen.
  3. Press the power button again to turn on screen.
  4. You can see log data in android monitor console for above steps.
  5. Type the back menu to exit the activity. You can see the broadcast receiver is unregistered in the activity’s onDestroy() method also.
  6. Press the power button to execute step 2 , 3 again, but there is not any log data printed in the android monitor console.

3. Register And Unregister Broadcast Receiver In Android Background Service

When you register the broadcast receiver in activity, it will be stopped after the activity exit.

To resolve this problem, we will create an android service object, and register and unregister the broadcast receiver in the service object.

Because the android service object will still run at the background after the activity exit, so the broadcast receiver will still run also after the android app exit.

3.1 Create Android Service Class.

3.1.1 Create A Java Class That Extends android.app.Service.

ScreenOnOffBackgroundService.java

import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

import ScreenOnOffReceiver;

public class ScreenOnOffBackgroundService extends Service {

    private ScreenOnOffReceiver screenOnOffReceiver = null;

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

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

        // Create an IntentFilter instance.
        IntentFilter intentFilter = new IntentFilter();

        // Add network connectivity change action.
        intentFilter.addAction("android.intent.action.SCREEN_ON");
        intentFilter.addAction("android.intent.action.SCREEN_OFF");

        // Set broadcast receiver priority.
        intentFilter.setPriority(100);

        // Create a network change broadcast receiver.
        screenOnOffReceiver = new ScreenOnOffReceiver();

        // Register the broadcast receiver with the intent filter object.
        registerReceiver(screenOnOffReceiver, intentFilter);

        Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "Service onCreate: screenOnOffReceiver is registered.");
    }

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

        // Unregister screenOnOffReceiver when destroy.
        if(screenOnOffReceiver!=null)
        {
            unregisterReceiver(screenOnOffReceiver);
            Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "Service onDestroy: screenOnOffReceiver is unregistered.");
        }
    }
}

3.1.2 Add Service Xml Tag In AndroidManifest.xml File.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="put your own package">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".broadcast.activity.ScreenOnOffActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:enabled="true" android:name=".broadcast.service.ScreenOnOffBackgroundService" />
    </application>

</manifest>

3.1.3 Change Activity Java Code To Below.

Please notice the java code that start the service object.

Intent backgroundService = new Intent(getApplicationContext(), ScreenOnOffBackgroundService.class);
startService(backgroundService);

ScreenOnOffActivity.java

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.dev2qa.example.R;
import com.dev2qa.example.broadcast.receiver.ScreenOnOffReceiver;
import com.dev2qa.example.broadcast.service.ScreenOnOffBackgroundService;

public class ScreenOnOffActivity extends AppCompatActivity {

    private ScreenOnOffReceiver screenOnOffReceiver = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_screen_on_off);

        setTitle("dev2qa.com - Keep BroadcastReceiver Running After App Exit.");

        Intent backgroundService = new Intent(getApplicationContext(), ScreenOnOffBackgroundService.class);
        startService(backgroundService);

        Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "Activity onCreate");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "Activity onDestroy");
    }
}

Run the example again, you can see below picture. From the logcat output, we can see the broadcast receiver still running after the android app exit.

这篇关于如何在 Android 中覆盖两次甚至 3 次单击电源按钮甚至音量 UP/DOWN 键在后台使用服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-31 04:42