我正在创建一个应用,只要用户按下电源按钮3次,就会启动活动。经过一些研究,我发现要做到这一点,首先你需要创建一个服务,启动广播接收器来检查屏幕的开/关状态。
基本上我希望即使应用程序关闭也能运行。一旦按下电源按钮3次或更多次,它应该开始另一个活动。
如果您知道解决方案,请告诉我完整的代码或答案的链接。
我以某种方式设法编写了这段代码,但它无法正常工作:
这是我使用的服务类:
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class UpdateService extends Service {
BroadcastReceiver mReceiver;
@Override
public void onCreate() {
super.onCreate();
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
mReceiver = new MyReceiver();
registerReceiver(mReceiver, filter);
}
@Override
public void onDestroy() {
unregisterReceiver(mReceiver);
Log.i("onDestroy Reciever", "Called");
super.onDestroy();
}
@Override
public void onStart(Intent intent, int startId) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
Log.i("screenON", "Called");
Toast.makeText(getApplicationContext(), "Awake", Toast.LENGTH_LONG)
.show();
} else {
Log.i("screenOFF", "Called");
Toast.makeText(getApplicationContext(), "Sleep",
Toast.LENGTH_LONG)
.show();
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyReceiver extends BroadcastReceiver {
private boolean screenOff;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
Intent i = new Intent(context, UpdateService.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
}
}
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.SCREEN_OFF"/>
<action android:name="android.intent.action.SCREEN_ON"/>
</intent-filter>
</receiver>
<service android:name=".UpdateService" />
另请注意,我是否必须在我的mainactivity.java
文件或要重定向到的活动中加入任何内容。
我使用了这些权限:
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
答案 0 :(得分:0)
没有完整的代码可以确定,但让我做出有根据的猜测:
你没有实现应用程序或活动是吗?
我认为你至少需要其中一个在onCreate()onResume()回调中注册接收器,只需说明清单中的接收器不可行。
在eclipse或任何其他具有android集成功能的IDE中进行调试可能非常有用,因为它显示了应用程序的过程,并且您可以确定它们是否已被启动。稍微调试就会告诉您接收器是否正常工作。
如果您想分享更多代码,我们当然可以进一步讨论。
答案 1 :(得分:0)
试试这个?
MyService
public class MyService extends Service {
@Override
public void onCreate() {
super.onCreate();
...
if (!registered) {
MyReceiver mybroadcast = new MyReceiver() {
registerReceiver(mybroadcast, new IntentFilter(Intent.ACTION_SCREEN_ON));
registerReceiver(mybroadcast, new IntentFilter(Intent.ACTION_SCREEN_OFF));
}
}
}
MyReceiver
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
...
}
}
BootStartUpReciever
public class BootStartUpReciever extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Start Service On Boot Start Up
Intent service = new Intent(context, MyService.class);
context.startService(service);
}
}
Manifest
<service android:name="my.package.MyService" />
<receiver
android:name="my.package.BootStartUpReciever" android:enabled="true" android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</receiver>
答案 2 :(得分:0)
我认为您的要求不需要服务类。因为在调用动作屏幕时您将开始活动。请参考我的以下实现并分享您的想法。
//Application class.
public class MyApplication extends Application {
static String TAG = "MyApplication";
@Override
public void onCreate() {
super.onCreate();
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// screen off
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.d(TAG, Intent.ACTION_SCREEN_OFF);
//screen on
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.d(TAG, Intent.ACTION_SCREEN_ON);
// To open your main activity.
Intent i = new Intent();
i.setClass(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
}, intentFilter);
}
}
// Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hopabit.wakeup"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.hopabit.wakeup.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
答案 3 :(得分:0)
为了让您的服务保持运行,您需要加入一个线程。确保service在一个额外的线程中,因为服务本身不是一个额外的进程或线程。这可以通过例如Handler来完成。
HandlerThread thread = new HandlerThread(SERVICE_THREAD_NAME);
thread.start();
handlerThreadId = thread.getId();
serviceLooper = thread.getLooper();
serviceHandler = new ServiceHandler(serviceLooper);
答案 4 :(得分:0)
我看到了你的代码。你非常接近解决方案。
注册您的广播接收器以关闭两个事件屏幕以及您活动的onCreate()内部的屏幕
if (!registered) {
MyReceiver mybroadcast = new MyReceiver() {
registerReceiver(mybroadcast, new IntentFilter(Intent.ACTION_SCREEN_ON));
registerReceiver(mybroadcast, new IntentFilter(Intent.ACTION_SCREEN_OFF));
}
在共享首选项或其他任何地方维护一个int计数器,首先用0初始化它并在onReceive()中递增该计数器:
public class MyReceiver extends BroadcastReceiver {
private boolean screenOff;
@Override
public void onReceive(Context context, Intent intent) {
int counter = get counter value from shared preference.
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
//increment the counter++
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
//increment the counter++
}
if(counter>3){
Intent i = new Intent(context, UpdateService.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
}
}
}
答案 5 :(得分:0)
您可以开始服务并经常重复它,也可以在Boot上监听事件。您可以使用此链接始终运行服务。 https://github.com/commonsguy/cwac-wakeful 它可以帮助解决你的问题。
答案 6 :(得分:0)
我认为您需要的是使用IntentService。
我会告诉你原因:
服务正在UI线程上运行(即使是在后台运行),因此这对于与UI的交互更好,但另一方面,它们不应该像你想要的那样长时间运行。 另外,IntentService在另一个Thread上运行,因此最好将它们用于更长的后台任务。
您应该做的是在屏幕ON / OFF状态下保存内存(使用Application对象)或其他Singleton。
如果您需要更多帮助,请告诉我