第三方锁屏应用开发

        要开发一个解锁应用有两个途径,一个是直接修改framework,按系统解锁一样直接在framework层实现,另外的方法就是直接开发一个第三方锁屏的应用,在power off时启动这个应用, poweron时首先出现的是这个应用,只有解锁关闭这个应用时才会进入系统界面。

       开发这样一个的锁屏应用, 可以分为如下几个方面,

1)上锁

2)锁屏界面

3)解锁

1,上锁

       上锁要完成的事情是在power off时启动锁屏界面的activity,所以开启一个service只要监听android.intent.action.SCREEN_OFF这个消息即可,这个service一直运行,不会随着锁屏activity的结束而解锁。当启动了自定义的activity时,实际上系统的解锁还是存在的,所以还要调用系统的disableKeyguard把系统的解锁停掉。

private BroadcastReceiver mScreenMonitor = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
    //Utility.log("onReceive   " );                        
    String action = intent.getAction();
    ...                

    if (android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(intent.getAction()))
    {
     //在设置里更改系统解锁是要重新disable
        AntiKeyguard.getInstance(context).reenable(false); 
        AntiKeyguard.getInstance(context).disable(false);                                
        return;
    }
    else if (action.equals(Intent.ACTION_SCREEN_OFF)){
          startLockActivityWhenScreenOff(context);
    }
    }
};



private void startLockActivityWhenScreenOff(Context context)
{
    TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    int call_state = tm.getCallState();
    if (TelephonyManager.CALL_STATE_IDLE != call_state) {//通话状态时
        return;
}

Intent i = new Intent(context, LockerActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);//长按home键时不显示图标
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0);

try {
    pi.send();
} catch (PendingIntent.CanceledException ex) {

}

//允许第三方解锁继续接受
//abortBroadcast();                         
//play sound when lock
Water.soundPlayLock();

}

要注意的地方是android.intent.action.SCREEN_OFF不能在AndroidManifest.xml中注册,要动态注册。

public void onCreate() {
    super.onCreate();
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_SCREEN_OFF);//注册SCREEN_OFF事件
    filter.addAction("android.app.action.DEVICE_POLICY_MANAGER_STATE_CHANGED");

    //优先级设到最高
    filter.setPriority(2147483647);
    registerReceiver(mScreenMonitor, filter);//注册广播
    AntiKeyguard.getInstance(this).disable(false);//disable系统锁屏
}

2, 锁屏界面

锁屏界面可以分为两部分内容:

1)基本信息的显示,如时间,日期,电池状态,未接电话,未接来电等等信息,这部分基本是所有解锁通用的。为了显示这些信息,我们需要注册一些receiver来处理

//时间,电量

private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
    // Util.log("onReceive_activity");
    String action = intent.getAction();
    if (Intent.ACTION_TIME_TICK.equals(action)) {
         long millis = System.currentTimeMillis();
         showTime(millis);
         showDate(millis);
    } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
        if (0 != intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0)) {
            int state = intent.getIntExtra(BatteryManager.EXTRA_STATUS,BatteryManager.BATTERY_STATUS_UNKNOWN);
            int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL,0);
            int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE,0);
            int plugFlag = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
            showCharge(state, level, scale, plugFlag);
        } else {
            hideCharge();
        }
    }

}
};

//短信

private class MsgObserver extends ContentObserver {

public MsgObserver(Handler handler) {
    super(handler);
    // Util.log("MsgObserver");
}

@Override
public void onChange(boolean selfChange) {
    // Log.d("Test", "MsgObserver onChange");
    showMissedMsg();
}

}

//未接来电

private class CallObserver extends ContentObserver {

public CallObserver(Handler handler) {
    super(handler);
    // Util.log("CallObserver");
}

@Override
public void onChange(boolean selfChange) {
    // Log.d("Test", "CallObserver onChange");
    showMissedCall();
}

}

2)与解锁操作相关的ui显示,如一些图标,一些动画特效等等,这个每个解锁都会不一样

3,解锁后的处理

当解锁操作符合指定的条件时,如滑动了一定的长度,拖动到指定的icon上,这时就表示解锁完成,要离开解锁界面进入指定的应用或laucher,这部分基本所有的解锁也是一样的

public void onTrigger(View v, int target) {
    Intent intent = null;
    switch (target) {
        case 0:
            break;
        case 1:
            intent = new Intent(Intent.ACTION_DIAL);
            break;
        case 2:
            intent = new Intent(Intent.ACTION_MAIN);
            intent.setType("vnd.android-dir/mms-sms");
            break;
        case 3:
            intent = new Intent();
            intent.setComponent(new ComponentName("com.android.browser", "com.android.browser.BrowserActivity"));
            break;
        case 4:
            intent = new Intent();
            intent.setAction("android.media.action.STILL_IMAGE_CAMERA");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
            break;
        case 5:
            intent = new Intent(Intent.ACTION_VIEW);
            intent.setType("vnd.android.cursor.dir/calls");
            break;
        case 6:
            intent = new Intent(Intent.ACTION_MAIN);
            intent.setType("vnd.android-dir/mms-sms");
            break;
        default:
            break;
    }

    if (intent != null)
        startActivity(intent);
    finishMyself();
    overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
 }

4,常见问题

1)解锁完成时黑屏问题

public void onAttachedToWindow() {
    // getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);//导致解锁时屏幕变黑
    getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
}

android:theme="@android:style/Theme.Translucent.NoTitleBar"



2)侧键不能调节音量

在播放音乐时,不要屏蔽音量调节键

AudioManager manager = (AudioManager) 
this.getSystemService(Context.AUDIO_SERVICE);                
if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP)
&& manager.isMusicActive()) {
    return super.onKeyDown(keyCode, event);
}

3)来电或闹钟处理

public class PhoneReceiver extends BroadcastReceiver {

    private LockPatternUtils lockPatternUtils = null;
    public void onReceive(Context context, Intent intent) {
         if(intent.getAction().equals("android.intent.action.PHONE_STATE")) {
             TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
             int call_state = tm.getCallState();
             if (TelephonyManager.CALL_STATE_IDLE != call_state) {
                 if (Utility.COMPAT_SYSTEM_LOCK)
                 {
                     if (lockPatternUtils == null) {
                         lockPatternUtils = new LockPatternUtils(context);
                     }
                     if (!lockPatternUtils.isSecureDual()) {
                         pause(context);                                        
                     }
                 }
                 else
                     pause(context);
                 }
             else {
                 if (Utility.COMPAT_SYSTEM_LOCK)
                 {
                     if (lockPatternUtils == null) {
                         lockPatternUtils = new LockPatternUtils(context);
                     }
                     if (!lockPatternUtils.isSecureDual()) {
                         resume(context);
                     }
                 }
                 else
                     resume(context);
                 }
             }
         else  {
             if(intent.getAction().equals("com.android.deskclock.ALARM_ALERT")) {
                 Utility.log("ALARM_ALERT");
                 pause(context);
             }
             else if(intent.getAction().equals("com.android.deskclock.ALARM_DONE")) {
                 Utility.log("ALARM_killed");
                 resume(context);
             }
             else if(intent.getAction().equals("com.android.deskclock.ALARM_SNOOZE")) {
                 Utility.log("ALARM_cancel_snooze");
                 resume(context);
             }
         }
     }

private void pause(Context context) {
    LockerActivity activity = LockerActivity.getInstance();
    if(activity != null) {
        activity.finishMyself();
        LockerActivity.setStateStopTemp();
    }
}

private void resume(Context context) {
    if(!LockerActivity.getState()) {
        return;
    }
    Intent i = new Intent(context, LockerActivity.class);
    i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);//长按home键时不显示图标
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0);
    try {
        pi.send();
    } catch (PendingIntent.CanceledException ex) {
}

LockerActivity.resetState();
}

}

4, home键时不显示图标

i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);//长按home键时不显示图标

5,系统解锁屏蔽

.    在锁屏server  oncreate时调用一次

AntiKeyguard.getInstance(this).disable(false);

   在解锁完成后,锁屏activity的

protected void onDestroy() {
    if (!Utility.COMPAT_SYSTEM_LOCK) {
        AntiKeyguard.getInstance(this).reenable(false);
        if (mBVerifiedBinding)
            AntiKeyguard.getInstance(this).disable(false);        
    }
}

   在锁屏server  onDestroy时调用一次

AntiKeyguard.getInstance(this).reenable(false);

6, 系统设置里改动锁屏类型时重新打开系统锁屏

处理filter.addAction("android.app.action.DEVICE_POLICY_MANAGER_STATE_CHANGED");

if (android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(intent.getAction()))
{
    AntiKeyguard.getInstance(context).reenable(false);
    AntiKeyguard.getInstance(context).disable(false);                                
    return;
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在安卓系统中,第三方应用是无法直接修改系统锁屏方式的。但是,第三方应用可以通过调用系统提供的锁屏接口来实现自己的锁屏功能。具体来说,可以通过以下步骤来实现: 1. 在应用的AndroidManifest.xml文件中声明锁屏权限: ```xml <uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> ``` 2. 在应用中创建一个继承自`android.app.admin.DeviceAdminReceiver`的类,并在AndroidManifest.xml文件中注册: ```xml <receiver android:name=".MyDeviceAdminReceiver" android:description="@string/app_name" android:label="@string/app_name" android:permission="android.permission.BIND_DEVICE_ADMIN" > <meta-data android:name="android.app.device_admin" android:resource="@xml/device_admin" /> <intent-filter> <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /> </intent-filter> </receiver> ``` 3. 在应用中调用以下代码来激活设备管理员权限: ```java Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, new ComponentName(context, MyDeviceAdminReceiver.class)); startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN); ``` 4. 在应用中调用以下代码来锁屏: ```java DevicePolicyManager devicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); devicePolicyManager.lockNow(); ``` 通过以上步骤,第三方应用可以实现自己的锁屏功能。需要注意的是,用户必须在应用中授予设备管理员权限才能使用锁屏功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿部春光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值