如何在后台使用服务覆盖两次(甚至两次)单击电源按钮甚至音量上/下音量键? [英] How to override double or even 3 times clicking Power button or even Volume UP/DOWN keys in Android Using a service in the background?

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

问题描述

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

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

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

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

Lars D 中的答案尽管已被接受,但仍无法进行该活动.

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

有一个应用打算这样做,我安装了它,但仍然无法正常工作,也许他们使用的API已过时,甚至已被删除.

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.

这些解决方案不起作用的原因:

  1. 当该应用被杀死/破坏并且不再能够检测到时.
  2. 屏幕被锁定,再次无法检测.
  3. SDK可能不支持它.

也许我们可以找到一种在活动中执行此操作的方法,但是我想在应用被杀死/处于后台/屏幕锁定/时,使用服务/广播接收器来收听操作.屏幕关闭时.

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.

好吧,这个问题在StackOverflow上肯定重复了很多次,但是没有给出完整或可行的答案.

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.

现在已解决的问题:

  1. 即使我的应用程序被杀死/破坏或从系统托盘中删除,它也始终在后台运行.
  2. 该服务在单击时始终会监听POWER_BUTTON.
  3. SDK支持此功能,因为它仅使用BroadCast接收器和服务.

我只是写下步骤,以防将来链接无法正常工作或将其删除:

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

1.首先,我们将创建一个广播接收器,它可以按如下所示监听和处理android屏幕的开/关广播事件.

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.在活动中注册和注销ScreenOnOffReceiver.

现在,我们将创建一个活动并在其onCreate()方法中注册ScreenOnOffReceiver,并在其onDestroy()方法中注销该接收者,如下所示.

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

在下面的步骤中进行以上活动.

  1. 开始活动,有一条日志消息,指出广播接收机已在活动的onCreate()方法中注册.
  2. 按下电源按钮以关闭屏幕.
  3. 再次按电源按钮以打开屏幕.
  4. 您可以在android监视器控制台中查看上述步骤的日志数据.
  5. 键入后退菜单以退出活动.您还可以在活动的onDestroy()方法中看到广播接收器也未注册.
  6. 按下电源按钮再次执行第2步,第3步,但是android监视器控制台中没有打印任何日志数据.

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

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

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

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

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

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

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创建Android服务类.

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

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在AndroidManifest.xml文件中添加服务Xml标签.

<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将活动Java代码更改为以下.

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

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

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

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.

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆