我正在基于旧project from github创建新项目。这是link to my project.这是基于NFC的项目,它使用NFC标签写入数据,然后对其执行操作,如暂停/播放音乐,发送短信等
我做了哪些更改
在为暂停/播放音乐写入数据时,新项目崩溃。我对Android和Android工作室也是全新的。
旧项目运作良好但新项目一度崩溃。 我正在使用运行5.0.1的Nexus 4。旧项目工作得非常好,但新项目在使用时崩溃
我标记了错误行,注释大到足以引起注意。
抱歉我的英文不好
这是writeractivity.java
package nfc.sidharthchaudhari.com.nfctrigger.writers;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import java.io.IOException;
import java.nio.charset.Charset;
/**
* Abstract class that all activities that write to a tag extend.
*/
public abstract class WriterActivity extends Activity {
/**
* MIME-types for custom activities to be activated
* when tag is tapped.
*/
public static final String PREV = "application/c23";
public static final String NEXT = "application/c22";
public static final String TOGGLE = "application/c24";
public static final String CALL = "application/c20";
public static final String SMS = "application/c21";
public static final String LAUNCH = "application/c25";
private String m_mimeType;
private boolean m_writeModeOn = false;
private String[] m_payload;
private String m_uriString;
private AlertDialog m_ad; // "tap tag now"-type dialog
protected NfcAdapter m_nfcAdapter;
protected PendingIntent m_pendingIntent;
protected IntentFilter[] m_writeTagFilters;
protected Tag m_detectedTag;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setUpLayout();
m_nfcAdapter = NfcAdapter.getDefaultAdapter(this);
m_pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter ndefIntent = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
m_writeTagFilters = new IntentFilter[]{ndefIntent};
this.setUpActivity();
}
@Override
public void onResume() {
super.onResume();
if (m_nfcAdapter != null) {
m_nfcAdapter.enableForegroundDispatch(this, m_pendingIntent, m_writeTagFilters, null);
}
}
@Override
public void onPause() {
super.onPause();
if (m_nfcAdapter != null) {
m_nfcAdapter.disableForegroundDispatch(this);
}
}
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
performTagOps(intent); //---------------------line 92------------//
finish();
}
@Override
public void onDestroy() {
super.onDestroy();
if (m_ad != null) {
m_ad.dismiss();
}
}
/**
* Creates the NDEF message to be written to tag
* (either MIME or URI, with or without payload)
* @param uriName name of URI to write on tag
* @return an NDEF message
*/
public NdefMessage createMessage(String uriName) {
NdefRecord[] records;
// MIME type
if (uriName == null) {
String mType = getMimeType();
String[] pl = getPayload();
if (pl != null) {
records = new NdefRecord[pl.length];
for (int i=0; i<pl.length; i++) {
byte[] plBytes = pl[i].getBytes(Charset.forName("UTF-8"));
records[i] = NdefRecord.createMime(mType, plBytes);
}
} else {
records = new NdefRecord[1];
records[0] = NdefRecord.createMime(mType, new byte[0]);
if (mType.equals(TOGGLE) || mType.equals(NEXT) || mType.equals(PREV)) {
Intent intent = new Intent("android.intent.action.MUSIC_PLAYER");
startService(intent); //---------------------line 128------------//
}
}
} else { // URI
if (uriName.isEmpty()) {
Toast.makeText(getApplicationContext(), "URL is empty", Toast.LENGTH_LONG).show();
return null;
}
Uri uri = Uri.parse(uriName);
NdefRecord ndefRecord = NdefRecord.createUri(uri);
records = new NdefRecord[] {ndefRecord};
}
return new NdefMessage(records);
}
/**
* Writes intended message to tag
* @param tag
* @return true iff tag was written to successfully.
*/
public boolean writeTag(Tag tag) {
String uriName = getUriString();
NdefMessage message = createMessage(uriName); //---------------------line 152------------//
if (message == null) {
return false;
}
try {
// see if tag is already NDEF formatted
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
ndef.connect();
if (!ndef.isWritable()) {
Toast.makeText(getApplicationContext(), "Read-only tag",
Toast.LENGTH_LONG).show();
return false;
}
// figure out how much space we need
int size = message.toByteArray().length;
Log.d("msg size", String.valueOf(size));
Log.d("tag size", String.valueOf(ndef.getMaxSize()));
if (ndef.getMaxSize() < size) {
Toast.makeText(getApplicationContext(), "Not enough space on tag", Toast.LENGTH_LONG).show();
return false;
}
ndef.writeNdefMessage(message);
Toast.makeText(getApplicationContext(), "Successfully written to tag", Toast.LENGTH_LONG).show();
return true;
} else {
// try to format tag to NDEF
NdefFormatable format = NdefFormatable.get(tag);
if (format != null) {
try {
format.connect();
format.format(message);
Toast.makeText(getApplicationContext(), "Successfully written to tag", Toast.LENGTH_LONG).show();
return true;
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Unable to format to NDEF", Toast.LENGTH_LONG).show();
return false;
}
} else {
Toast.makeText(getApplicationContext(), "Tag does not support NDEF", Toast.LENGTH_LONG).show();
return false;
}
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
}
return false;
}
/**
* Writes to tag if tag detected
* @param intent
*/
public void performTagOps(Intent intent) {
if (intent.getAction().equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
m_detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (m_detectedTag == null) {
Toast.makeText(getApplicationContext(), "Tag not found.", Toast.LENGTH_LONG).show();
} else {
if (getWriteMode()) {
writeTag(m_detectedTag); //---------------------line 219------------//
}
setWriteModeOff();
}
}
}
/**
* @return String indicating the MIME-type
*/
public String getMimeType() {
return m_mimeType;
}
/**
* Set the MIME-type
* @param mimeType String indicating the MIME-type
*/
public void setMimeType(String mimeType) {
this.m_mimeType = mimeType;
}
/**
* @return true iff write mode is on
*/
public boolean getWriteMode() {
return this.m_writeModeOn;
}
/**
* Set write mode to on
*/
public void setWriteModeOn() {
this.m_writeModeOn = true;
}
/**
* Set write mode to off
*/
public void setWriteModeOff() {
this.m_writeModeOn = false;
}
/**
* Returns payload to be written to tag.
* @return String[]
*/
public String[] getPayload() {
return this.m_payload;
}
/**
* Set the payload to be written to tag.
* @param payload String array which is the payload
*/
public void setPayload(String[] payload) {
this.m_payload = payload;
}
/**
* Returns the URI to be written to tag.
* @return String
*/
public String getUriString() {
return this.m_uriString;
}
/**
* Set the URI to be written to tag.
* @param uriString
*/
public void setUriString(String uriString) {
this.m_uriString = uriString;
}
/**
* Shows the user a dialog which instructs to tap phone on tag.
* @return the AlertDialog
*/
public AlertDialog showDialog() {
AlertDialog.Builder adb = new AlertDialog.Builder(this);
adb.setTitle("Please bring NFC tag near to phone");
adb.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setWriteModeOff();
dialog.dismiss();
}
}).setIcon(android.R.drawable.ic_dialog_alert);
m_ad = adb.create();
m_ad.show();
return m_ad;
}
/**
* Sets user preferences for UI text fields.
* @param key String
* @param value String
*/
public void setPrefs(String key, String value) {
PreferencesHelper prefHelper = new PreferencesHelper(getApplicationContext());
prefHelper.savePreferences(key, value);
}
/**
* Retrieves preferences for UI text fields.
* @param key String
* @return String, the value of the preference
*/
public String getPrefs(String key) {
PreferencesHelper prefHelper = new PreferencesHelper(getApplicationContext());
return prefHelper.getPreferences(key);
}
/**
* Set up the visual layout of the activity
*/
public void setUpLayout() { }
/**
* Set up objects needed for the activity on the onCreate method of child classes.
*/
public abstract void setUpActivity();
}
错误
04-12 12:20:22.722 31614-31614/nfc.sidharthchaudhari.com.nfctrigger E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: nfc.sidharthchaudhari.com.nfctrigger, PID: 31614
java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=android.intent.action.MUSIC_PLAYER }
at android.app.ContextImpl.validateServiceIntent(ContextImpl.java:1674)
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1703)
at android.app.ContextImpl.startService(ContextImpl.java:1687)
at android.content.ContextWrapper.startService(ContextWrapper.java:515)
at nfc.sidharthchaudhari.com.nfctrigger.writers.WriterActivity.createMessage(WriterActivity.java:128)
at nfc.sidharthchaudhari.com.nfctrigger.writers.WriterActivity.writeTag(WriterActivity.java:152)
at nfc.sidharthchaudhari.com.nfctrigger.writers.WriterActivity.performTagOps(WriterActivity.java:219)
at nfc.sidharthchaudhari.com.nfctrigger.writers.WriterActivity.onNewIntent(WriterActivity.java:92)
at android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1210)
at android.app.ActivityThread.deliverNewIntents(ActivityThread.java:2430)
at android.app.ActivityThread.performNewIntents(ActivityThread.java:2443)
at android.app.ActivityThread.handleNewIntent(ActivityThread.java:2452)
at android.app.ActivityThread.access$1600(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)