我构建了一个自定义锁屏应用程序,该应用程序使用广播接收器和服务来监听用户打开或关闭屏幕并从那里启动我的活动。该活动应该完全取代锁定屏幕。为了做到这一点,我的应用程序应该禁用Android股票锁定,以便我的应用程序可以作为新的锁定屏幕。
相反,发生的事情是,首次安装应用程序后,首次启动的服务应用程序似乎正在运行。当用户首次关闭手机屏幕时,当他们将手机重新打开时,会看到我的应用程序在顶部运行,并且可以使用我的应用程序解锁手机。但是一旦进入Android操作系统,如果用户按下主页按钮,下次他们关闭屏幕并重新打开而不是被带回我的应用程序,他们会被带到股票解锁屏幕,我的应用程序打开它下面,什么时候它应该在顶部。
这是我的代码:
我的服务:
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.d("MyService","Service STARTED");
final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
final BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
}
}
我的广播接收器:
public class ScreenReceiver extends BroadcastReceiver {
public static ArrayList<String> runningApplications = new ArrayList<String>();
private Context ctext;
public static boolean screenIsLocked;
public static KeyguardManager keyguardManager;
public static KeyguardLock lock;
@Override
public void onReceive(final Context context, final Intent intent) {
ctext = context;
keyguardManager = (KeyguardManager)ctext.getSystemService(Activity.KEYGUARD_SERVICE);
lock = keyguardManager.newKeyguardLock(Context.KEYGUARD_SERVICE);
lock.disableKeyguard();
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenIsLocked = true;
Log.d("ScreenReceiver", "False");
Intent intenti = new Intent();
intenti.setClass(context, starterActivity.class);
intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intenti);
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenIsLocked = false;
Log.d("ScreenReceiver", "True");
Intent intenti = new Intent();
intenti.setClass(context, starterActivity.class);
intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intenti);
}
}
我的活动基本上是空的,只有一个解锁按钮,按下时会调用finish();
。
答案 0 :(得分:4)
密钥保护相关逻辑的行为因设备而异。这是因为锁屏通常是由设备制造商定制的(即不是库存),其中一些尊重您使用的键盘保护逻辑,有些则不然。
此外,afaik控制键盘的新方法是使用窗口标志:
// inside activity
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
但这并不能解决问题,设备仍然对此有所说明。
E.g。根据我的经验,Galaxy Nexus会将你的活动窗口显示在键盘上方,但不会忽略它(你认为Google品牌的设备应该尊重旗帜,呃),所以如果你在活动中点击后退按钮 - 你会得到标准锁屏---虽然HTC One X似乎正确处理了解散部分:您的活动窗口将导致标准锁屏被按预期被解雇。
我发现无法强制所有设备正常运行。 Android API并不是为了让您能够创建自定义锁定屏幕(至少目前不是)。看看商店里的那些 - 它们都有完全相同的问题,不够稳定。
作为Dianne Hackborn says in this Google Groups answer,你在这方面可以做的任何事情都是黑客行为,所以期望它不时出现。
答案 1 :(得分:2)
我尝试编译你的代码并得到你所说的相同错误。我试图修改它以使其工作,最后得到问题!!!
public class ScreenReceiver extends BroadcastReceiver {
public static ArrayList<String> runningApplications = new ArrayList<String>();
private Context ctext;
public static boolean screenIsLocked;
public static KeyguardManager keyguardManager;
public static KeyguardLock lock;
@Override
public void onReceive(final Context context, final Intent intent) {
ctext = context;
keyguardManager = (KeyguardManager)ctext.getSystemService(Activity.KEYGUARD_SERVICE);
lock = keyguardManager.newKeyguardLock(Context.KEYGUARD_SERVICE);
lock.disableKeyguard();
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenIsLocked = true;
Log.d("ScreenReceiver", "False");
Intent intenti = new Intent();
intenti.setClass(context, starterActivity.class);
intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intenti);
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenIsLocked = false;
Log.d("ScreenReceiver", "True");
Intent intenti = new Intent();
intenti.setClass(context, starterActivity.class);
intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intenti);
}
}
通过对广播接收器类的这种改变,我能够克服这个问题
尝试并告诉我是否有任何问题。
编辑:我认为问题可能在于finish()
方法...... Android在需要内存时转储应用程序...我认为finish()
可能会帮助Android删除应用程序(和这可能是您的问题随机发生的原因)