如何在屏幕醒来或按下锁定按钮时启动相机
问题描述:
我正在开发一款应用程序,可以将其假定为手机锁定应用程序。我的应用程序最初设置了由用户设置的锁定图像,然后开始在服务中运行。我只是想启动相机,当我唤醒我的屏幕时点击一张照片。我一周以来一直在寻找这个。请帮助。我附上我的代码以及这个问题。如何在屏幕醒来或按下锁定按钮时启动相机
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button btncam;
private ImageView imgcam;
static final int REQUEST_IMAGE_CAPTURE=1;
private Uri imguri;
private File f2;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btncam=(Button) findViewById(R.id.btncam);
imgcam=(ImageView) findViewById(R.id.imgcam);
if(!hasCamera())
{
btncam.setEnabled(false);
}
f2=getOutputMediaFile();
imguri=FileProvider.getUriForFile(MainActivity.this,BuildConfig.APPLICATION_ID + ".provider", f2);
if(BitmapFactory.decodeFile(imguri.getPath())!=null)
{
startService();
}
else
{
Toast.makeText(this,"no lock set....please set a lock image",Toast.LENGTH_SHORT).show();
}
btncam.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,imguri);
startActivityForResult(intent,REQUEST_IMAGE_CAPTURE);
}
});
}
File getOutputMediaFile() {
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "CameraDemo");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
return new File(mediaStorageDir.getPath() + File.separator +
"IMG.png");
}
private boolean hasCamera()
{
return getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
}
public void startService()
{
Intent intent=new Intent(this,MyService.class);
startService(intent);
}
public void stopService()
{
Intent intent=new Intent(this,MyService.class);
stopService(intent);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode==REQUEST_IMAGE_CAPTURE && resultCode==RESULT_OK)
{
Bitmap b=BitmapFactory.decodeFile(imguri.getPath());
imgcam.setImageBitmap(b);
Toast.makeText(this,"Lock saved",Toast.LENGTH_SHORT).show();
startService();
}
}
}
Myservice.java
public class MyService extends Service {
@Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new LockReceiver();
registerReceiver(mReceiver, filter);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service started", Toast.LENGTH_SHORT).show();
KeyguardManager myKM = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
boolean isPhoneLocked = myKM.inKeyguardRestrictedInputMode();
if(isPhoneLocked==true)
{
Log.v("result","phone is locked");
//Toast.makeText(MyService.this,"Phone is locked",Toast.LENGTH_SHORT).show();
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
// YOUR CODE
Log.v("ans","phone wakes up");
} else {
// YOUR CODE
Log.v("ans","phone sleeping");
}
}
else
{
Log.v("result","phone is unlocked");
//Toast.makeText(MyService.this,"Phone is not locked",Toast.LENGTH_SHORT).show();
}
return START_STICKY;
}
@Override
public void onDestroy() {
Toast.makeText(this, "Service stopped", Toast.LENGTH_SHORT).show();
}
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Intent restartServiceTask = new Intent(getApplicationContext(),this.getClass());
restartServiceTask.setPackage(getPackageName());
PendingIntent restartPendingIntent =PendingIntent.getService(getApplicationContext(), 1,restartServiceTask, PendingIntent.FLAG_ONE_SHOT);
AlarmManager myAlarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
myAlarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() +10, restartPendingIntent);
super.onTaskRemoved(rootIntent);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
LockReceiver.java
public class LockReceiver 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,MyService.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
}
}
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.user.objunlck.MainActivity">
<Button
android:text="set lock"
android:layout_marginRight="75dp"
android:layout_marginLeft="75dp"
android:id="@+id/btncam"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/imgcam"
android:layout_marginTop="25dp"
android:layout_gravity="center_horizontal"
android:layout_width="300dp"
android:layout_height="300dp" />
</LinearLayout>
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="/storage/emulated/0" path="."/>
</paths>
的Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.user.objunlck">
<uses-feature
android:name="android.hardware.camera2"
android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<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=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<service android:name=".MyService"
android:exported="false"
android:stopWithTask="false"
android:enabled="true">
</service>
</application>
</manifest>
感谢...请大家帮忙
答
我假设你没有得到正确的ON/OFF事件。
该两个动作为屏幕和关闭是:
android.intent.action.SCREEN_OFF
android.intent.action.SCREEN_ON
下面是接收器的代码:
public class ScreenStateReciever extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.i("TAG","Screen went OFF");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.i("TAG","Screen went ON");
// start your camera activity
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}
}
}
创建服务类接收器的对象:
ScreenStateReceiver mScreenStateReceiver = new ScreenStateReceiver();
为接收者创建一个IntentFilter来监听事件(将其写入Service的onStartCommand()):
IntentFilter screenStateFilter = new IntentFilter();
screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mScreenStateReceiver, screenStateFilter);
注销onDestroy()和onTerminated()服务中的接收器。
unregisterReceiver(mScreenStateReceiver);
要保存图像的任何文件夹中,使用getExternalStorageDirectory()在getOutputMediaFile()方法。 getExternalStoragePublicDirectory(String type)将返回该类型文件夹的根路径,在这里是图片。你可以阅读更多关于它here。
File getOutputMediaFile() {
File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), "CameraDemo");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
return new File(mediaStorageDir.getPath() + File.separator +
"IMG.png");
}
答
public class MyService extends Service {
@Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new LockReceiver();
registerReceiver(mReceiver, filter);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service started", Toast.LENGTH_SHORT).show();
KeyguardManager myKM = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
boolean isPhoneLocked = myKM.inKeyguardRestrictedInputMode();
if(isPhoneLocked==true)
{
Log.v("result","phone is locked");
//Toast.makeText(MyService.this,"Phone is locked",Toast.LENGTH_SHORT).show();
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
// YOUR CODE
Log.v("ans","phone wakes up");
Intent in=new Intent(MediaStore.ACTION_IMAGE_CAPTURE_SECURE);
startActivity(in);
Log.v("act","camera opened for lock comparing");
} else {
// YOUR CODE
Log.v("ans","phone sleeping");
}
}
else
{
Log.v("result","phone is unlocked");
//Toast.makeText(MyService.this,"Phone is not locked",Toast.LENGTH_SHORT).show();
}
return START_STICKY;
}
@Override
public void onDestroy() {
Toast.makeText(this, "Service stopped", Toast.LENGTH_SHORT).show();
}
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Intent restartServiceTask = new Intent(getApplicationContext(),this.getClass());
restartServiceTask.setPackage(getPackageName());
PendingIntent restartPendingIntent =PendingIntent.getService(getApplicationContext(), 1,restartServiceTask, PendingIntent.FLAG_ONE_SHOT);
AlarmManager myAlarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
myAlarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() +10, restartPendingIntent);
super.onTaskRemoved(rootIntent);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
是的,我是越来越开关事件also.Now我是最初能够打开相机时的画面被ACTION_IMAGE_CAPTURE_SECURE,这是我的手机的默认摄像头锁定屏幕。但这里的问题是,我想通过这个相机存储在任何想要的文件夹点击图像,但图像进入DCIM文件夹。请help.I附加更新的服务类代码here.Rest一切都与以前相同帖子... –