我正在尝试开发android应用程序,这将有助于识别在无效模式/密码的情况下谁试图访问我的手机。我已以设备管理员的身份启用了我的应用程序,并实现了电子邮件功能以在模式/密码无效的情况下触发。现在,我想用前置摄像头拍照并附加到该电子邮件。我尝试调用另一个活动的startActivity方法,它将需要帮助来捕获照片。但效果不佳-抛出以下异常:
Unable to start receiver com.example.lock.MyAdmin:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.intent.addCategory(java.lang.String)' on a null object reference
我是Android应用程序的新手,所以任何人都可以帮助我实现此功能。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.lock">
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.CAMERA" />
<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=".CamActivity"
android:label="@string/title_activity_cam"
android:theme="@style/AppTheme.NoActionBar">
</activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".MyAdmin"
android:description="@string/sample_device_admin_description"
android:label="@string/sample_device_admin"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/policies" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
<action android:name="android.app.action.ACTION_PASSWORD_FAILED" />
</intent-filter>
</receiver>
</application>
</manifest>
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener
{
private Button lock, disable, enable;
public static final int RESULT_ENABLE = 11;
private DevicePolicyManager devicePolicyManager;
private ComponentName compName;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
devicePolicyManager = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
compName = new ComponentName(this, MyAdmin.class);
lock = (Button) findViewById(R.id.Lock);
enable = (Button) findViewById(R.id.enableBtn);
disable = (Button) findViewById(R.id.disableBtn);
lock.setOnClickListener(this);
enable.setOnClickListener(this);
disable.setOnClickListener(this);
}
@Override
protected void onResume() {
super.onResume();
boolean isActive = devicePolicyManager.isAdminActive(compName);
disable.setVisibility(isActive ? View.VISIBLE : View.GONE);
enable.setVisibility(isActive ? View.GONE : View.VISIBLE);
}
@Override
public void onClick(View view) {
if (view == lock) {
boolean active = devicePolicyManager.isAdminActive(compName);
if (active) {
devicePolicyManager.lockNow();
} else {
Toast.makeText(this, "You need to enable the Admin Device Features", Toast.LENGTH_SHORT).show();
}
} else if (view == enable) {
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, compName);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Additional text explaining why we need this permission");
startActivityForResult(intent, RESULT_ENABLE);
} else if (view == disable) {
devicePolicyManager.removeActiveAdmin(compName);
disable.setVisibility(View.GONE);
enable.setVisibility(View.VISIBLE);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode) {
case RESULT_ENABLE :
if (resultCode == Activity.RESULT_OK) {
Toast.makeText(MainActivity.this, "You have enabled the Admin Device features", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Problem to enable the Admin Device features", Toast.LENGTH_SHORT).show();
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
}
MyAdmin
package com.example.lock;
import android.app.admin.DeviceAdminReceiver;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
import android.content.ComponentName;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.os.Environment;
import java.io.File;
import android.net.Uri;
import android.content.pm.PackageManager;
public class MyAdmin extends DeviceAdminReceiver {
Context conn;
public MyAdmin(Context con) {
this.conn = con;
}
public MyAdmin() {
}
@Override
public void onEnabled(Context context, Intent intent) {
Toast.makeText(context, "Device Admin : enabled", Toast.LENGTH_SHORT).show();
ComponentName cn =new ComponentName(context, MyAdmin.class);
DevicePolicyManager mgr=
(DevicePolicyManager)context.getSystemService(Context.DEVICE_POLICY_SERVICE);
mgr.setPasswordQuality(cn,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
onPasswordChanged(context, intent);
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
ComponentName receiver = new ComponentName(context, CamActivity.class);
PackageManager pm = context.getPackageManager();
Intent i = pm.getLaunchIntentForPackage("com.example.lock.CamActivity");
i.addCategory(Intent.CATEGORY_LAUNCHER);
context.startActivity(intent);
//conn.startActivity(new Intent().setComponent(new ComponentName("com.example.lock", "com.example.lock.CamActivity")));
}
public void onPasswordChanged1(Context ctxt, Intent intent) {
DevicePolicyManager mgr=
(DevicePolicyManager)ctxt.getSystemService(Context.DEVICE_POLICY_SERVICE);
int msgId;
if (mgr.isActivePasswordSufficient()) {
msgId=R.string.compliant;
}
else {
msgId=R.string.not_compliant;
}
Toast.makeText(ctxt, msgId, Toast.LENGTH_LONG).show();
}
@Override
public void onPasswordFailed(Context context, Intent intent) {
int attempts =0;
DevicePolicyManager DevicePolicyManager=
(DevicePolicyManager)context.getSystemService(Context.DEVICE_POLICY_SERVICE);
if(DevicePolicyManager != null)
attempts = DevicePolicyManager.getCurrentFailedPasswordAttempts();
AsyncCall EmailAsyncClient =new AsyncCall();
EmailAsyncClient.execute("");
Toast.makeText(context, R.string.password_failed, Toast.LENGTH_LONG)
.show();
}
@Override
public void onPasswordSucceeded(Context ctxt, Intent intent) {
//MailService mailer = new MailService("From@gmail.com","To@gmail.com","Enable Attempt!","Please verify Your Phone!!!", "<b>HtmlBody</b>");
Toast.makeText(ctxt, R.string.password_success, Toast.LENGTH_LONG)
.show();
}
@Override
public void onDisabled(Context context, Intent intent) {
Toast.makeText(context, "Device Admin : disabled", Toast.LENGTH_SHORT).show();
}
}
MailService
package com.example.lock;
import android.util.Log;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import android.os.AsyncTask;
public class MailService {
// public static final String MAIL_SERVER = "localhost";
private String toList;
private String ccList;
private String bccList;
private String subject;
final private static String SMTP_SERVER = "smtp.gmail.com";
private String from;
private String txtBody;
private String htmlBody;
private String replyToList;
//private ArrayList<Attachment> attachments;
private boolean authenticationRequired = true;
public MailService(String from, String toList, String subject, String txtBody, String htmlBody){
//Attachment attachment) {
this.txtBody = txtBody;
this.htmlBody = htmlBody;
this.subject = subject;
this.from = from;
this.toList = toList;
this.ccList = null;
this.bccList = null;
this.replyToList = null;
this.authenticationRequired = true;
//this.attachments = new ArrayList<Attachment>();
//if (attachment != null) {
// this.attachments.add(attachment);
//}
}
public void sendAuthenticated() throws AddressException, MessagingException {
authenticationRequired = true;
send();
}
/**
* Send an e-mail
*
* @throws MessagingException
* @throws AddressException
*/
public void send() throws AddressException, MessagingException {
Properties props = new Properties();
// set the host smtp address
props.put("mail.smtp.host", SMTP_SERVER);
props.put("mail.user", from);
props.put("mail.smtp.starttls.enable", "true"); // needed for gmail
props.put("mail.smtp.auth", "true"); // needed for gmail
props.put("mail.smtp.port", "587"); // gmail smtp port
Authenticator auth = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("UserName", "Password");
}
};
Session session;
props.put("mail.smtp.auth", "true");
session = Session.getDefaultInstance(props, auth);
if (authenticationRequired) {
//Authenticator auth = new SMTPAuthenticator();
} else {
session = Session.getDefaultInstance(props, null);
}
// get the default session
//session.setDebug(true);
// create message
Message msg = new javax.mail.internet.MimeMessage(session);
// set from and to address
try {
msg.setFrom(new InternetAddress(from, from));
msg.setReplyTo(new InternetAddress[]{new InternetAddress(from,from)});
} catch (Exception e) {
new Throwable(e);
msg.setFrom(new InternetAddress(from));
msg.setReplyTo(new InternetAddress[]{new InternetAddress(from)});
}
// set send date
msg.setSentDate(Calendar.getInstance().getTime());
// parse the recipients TO address
java.util.StringTokenizer st = new java.util.StringTokenizer(toList, ",");
int numberOfRecipients = st.countTokens();
javax.mail.internet.InternetAddress[] addressTo = new javax.mail.internet.InternetAddress[numberOfRecipients];
int i = 0;
while (st.hasMoreTokens()) {
addressTo[i++] = new javax.mail.internet.InternetAddress(st
.nextToken());
}
msg.setRecipients(javax.mail.Message.RecipientType.TO, addressTo);
// parse the replyTo addresses
if (replyToList != null && !"".equals(replyToList)) {
st = new java.util.StringTokenizer(replyToList, ",");
int numberOfReplyTos = st.countTokens();
javax.mail.internet.InternetAddress[] addressReplyTo = new javax.mail.internet.InternetAddress[numberOfReplyTos];
i = 0;
while (st.hasMoreTokens()) {
addressReplyTo[i++] = new javax.mail.internet.InternetAddress(
st.nextToken());
}
msg.setReplyTo(addressReplyTo);
}
// parse the recipients CC address
if (ccList != null && !"".equals(ccList)) {
st = new java.util.StringTokenizer(ccList, ",");
int numberOfCCRecipients = st.countTokens();
javax.mail.internet.InternetAddress[] addressCC = new javax.mail.internet.InternetAddress[numberOfCCRecipients];
i = 0;
while (st.hasMoreTokens()) {
addressCC[i++] = new javax.mail.internet.InternetAddress(st
.nextToken());
}
msg.setRecipients(javax.mail.Message.RecipientType.CC, addressCC);
}
// parse the recipients BCC address
if (bccList != null && !"".equals(bccList)) {
st = new java.util.StringTokenizer(bccList, ",");
int numberOfBCCRecipients = st.countTokens();
javax.mail.internet.InternetAddress[] addressBCC = new javax.mail.internet.InternetAddress[numberOfBCCRecipients];
i = 0;
while (st.hasMoreTokens()) {
addressBCC[i++] = new javax.mail.internet.InternetAddress(st
.nextToken());
}
msg.setRecipients(javax.mail.Message.RecipientType.BCC, addressBCC);
}
// set header
msg.addHeader("X-Mailer", "MyAppMailer");
msg.addHeader("Precedence", "bulk");
// setting the subject and content type
msg.setSubject(subject);
Multipart mp = new MimeMultipart("related");
// set body message
MimeBodyPart bodyMsg = new MimeBodyPart();
bodyMsg.setText(txtBody, "iso-8859-1");
//if (attachments.size()>0) htmlBody = htmlBody.replaceAll("#filename#",attachments.get(0).getFilename());
//if (htmlBody.indexOf("#header#")>=0) htmlBody = htmlBody.replaceAll("#header#",attachments.get(1).getFilename());
//if (htmlBody.indexOf("#footer#")>=0) htmlBody = htmlBody.replaceAll("#footer#",attachments.get(2).getFilename());
bodyMsg.setContent(htmlBody, "text/html");
mp.addBodyPart(bodyMsg);
// set attachements if any
//if (attachments != null && attachments.size() > 0) {
// for (i = 0; i < attachments.size(); i++) {
// Attachment a = attachments.get(i);
// BodyPart att = new MimeBodyPart();
// att.setDataHandler(new DataHandler(a.getDataSource()));
// att.setFileName( a.getFilename() );
// att.setHeader("Content-ID", "<" + a.getFilename() + ">");
// mp.addBodyPart(att);
// }
// }
msg.setContent(mp);
// send it
try {
javax.mail.Transport.send(msg);
} catch (Exception e) {
new Throwable(e);
e.printStackTrace();
}
}
/**
* SimpleAuthenticator is used to do simple authentication when the SMTP
* server requires it.
*/
private static class SMTPAuthenticator extends javax.mail.Authenticator {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
String username = "username";
//DataService.getSetting(DataService.SETTING_SMTP_USER);
String password = "password";
//DataService.getSetting(DataService.SETTING_SMTP_PASSWORD);
return new PasswordAuthentication(username, password);
}
}
public String getToList() {
return toList;
}
public void setToList(String toList) {
this.toList = toList;
}
public String getCcList() {
return ccList;
}
public void setCcList(String ccList) {
this.ccList = ccList;
}
public String getBccList() {
return bccList;
}
public void setBccList(String bccList) {
this.bccList = bccList;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public void setFrom(String from) {
this.from = from;
}
public void setTxtBody(String body) {
this.txtBody = body;
}
public void setHtmlBody(String body) {
this.htmlBody = body;
}
public String getReplyToList() {
return replyToList;
}
public void setReplyToList(String replyToList) {
this.replyToList = replyToList;
}
public boolean isAuthenticationRequired() {
return authenticationRequired;
}
public void setAuthenticationRequired(boolean authenticationRequired) {
this.authenticationRequired = authenticationRequired;
}
}