android 11 上未检测到 NFC
NFC not detected on android 11
我必须制作一个扫描 NFC 卡的应用程序,然后同时拍照并将此信息发送到服务器,但我的问题是 android 11 上的设备未检测到我的 NFC 标签与 android 6 到 android 9 上的设备不同。当我按下按钮(拍摄照片(in、in2b 和 out2b)然后仅在 onPause 方法中禁用它时,我启用了前台调度. 此外,当我的应用程序为 运行 时,其他应用程序(如 NFC 工具)无法检测到任何 NFC 标签,除非我停止我的应用程序。如果有人知道问题的根源,欢迎帮助,谢谢
这是我的代码:
public class ScanRes extends AppCompatActivity {
private NfcAdapter nfcAdapter;
private PendingIntent pintent;
private String nfcID = "";
private ImageView imgpts;
private int nbrClicks = 0;
private TextView battery;
private String URLAPI;
private TextView msg_in;
private TextView msg_out;
private static boolean netWorskStatus = true;
private NetworkChangeReceiver connectionState;
private SurfaceView cameraDisplay;
private Camera camera;
SurfaceHolder surfaceHolder;
//Valeurs Latitude et Longitude init au début
private String Longitude = null;
private String Latitude = null;
private String Accuracy = null;
private ImageView in;
private ImageView in2b;
private ImageView out2b;
private TextView msg_sans_btn;
private static final String SCAN_IN = "in";
private static final String SCAN_OUT = "ou";
private static final String SCAN = "u";
private String specialScanReason = "";
private String selectedChantier = "";
private String scanType="";
private TextView in_msg;
//Variables qui vont stocker les options téléchargées via le serveur
private int gps_frequency;
private boolean photo_on;
private int nbr_bouton;
private boolean saved;
private boolean mode_kiosque_on;
private boolean gps_force;
private boolean mode_chantier_on;
private boolean special_on;
private boolean gps_on;
private String nomChantierCourant;
private String base64Img = "";
private TextView msg_if_mode_boutons;
private boolean mode_controle_acces_on;
private boolean nfcScanRight = false;
public static Handler handler; //Attention, il était private avant
public static HandlerThread handlerThread;
public static Looper looper;
private Handler handlerUS;
public static HandlerThread handlerThreadUS;
public static Looper looperUS;
private static final int SPECIAL_SCAN_REQUEST_CODE = 00005;
private static final int SELECTION_CHANTIERS_REQUEST_CODE = 00010;
private static final int ADMIN_ACTIVITY_REQUEST_CODE = 5024;
String chantiers[];
private TextView chantierCourant;
private void takePictureAfterScan(Context currentContext, String fileName, int rapportDeDivision){
try{
camera.takePicture(null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
//startCameraSource();
Bitmap im = BitmapFactory.decodeByteArray(data, 0, data.length);
Matrix matrix = new Matrix();
matrix.postRotate(-90);
Bitmap image = Bitmap.createBitmap(im, 0, 0, im.getWidth(), im.getHeight(), matrix, true);
Bitmap resized = Bitmap.createScaledBitmap(image, im.getWidth()/rapportDeDivision, im.getHeight()/rapportDeDivision, false);
ByteArrayOutputStream byteArrayOutputStreamc = new ByteArrayOutputStream();
resized.compress(Bitmap.CompressFormat.JPEG, 50, byteArrayOutputStreamc);
byte[] byteArrayc = byteArrayOutputStreamc.toByteArray();
//String imgBuffc = Base64.encodeToString(byteArrayc, Base64.NO_WRAP);
base64Img = Base64.encodeToString(byteArrayc, Base64.NO_WRAP);
//WriteOnce(currentContext, imgBuffc, fileName);
}
});
}catch(Exception e){
e.printStackTrace();
}
}
private void startCameraSource(){
//cameraDisplay = (SurfaceView) findViewById(R.id.camera);
if ((cameraDisplay != null) && (cameraDisplay.getHolder() != null) && (camera != null)) {
try {
camera.setPreviewDisplay(cameraDisplay.getHolder());
camera.startPreview();
} catch (Exception e) {
}
}
}
//Fonction initialisant la caméra
private void initCamera() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 2552);
return;
}
//cameraDisplay = (SurfaceView) findViewById(R.id.camera);
try {
if (camera != null)
camera.release();
camera =null;
camera = Camera.open(1);
camera.setDisplayOrientation(90);
//cameraDisplay.setVisibility(View.VISIBLE);
cameraDisplay.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
startCameraSource();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
} catch (RuntimeException e) {
if (camera == null)
//setText("camera error");
Log.i("CAMERA", "CAMERA ERROR");
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan_res);
connectionState = new NetworkChangeReceiver();
registerNetworkBroadcastReceiver(connectionState);
surfaceHolder = cameraDisplay.getHolder();
handlerThread = new HandlerThread("MyHandlerThread", Thread.MAX_PRIORITY);
handlerThread.start();
looper = handlerThread.getLooper();
handler = new Handler(looper);
handler.post(new Runnable(){
@Override
public void run() {
if(photo_on) {
initCamera();
}
}
});
//Init NFC Adapter
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
//If no NfcAdapter, display that the device has no NFC
if (nfcAdapter == null){
Toast.makeText(this,"Votre appareil n'est pas compatible avec le NFC", Toast.LENGTH_SHORT).show();
finish();
}
pintent = PendingIntent.getActivity(this,0,new Intent(this,this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);
}
@SuppressLint("ClickableViewAccessibility")
@Override
protected void onStart(){
super.onStart();
in.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
nfcScanRight = true;
nfcAdapter.enableForegroundDispatch(ScanRes.this,pintent,null,null);
scanType = SCAN;
if(photo_on){
takePictureAfterScan(ScanRes.this, "base64.txt", 2);
handler.post(new Runnable(){
@Override
public void run() {
initCamera();
startCameraSource();
}
});
}
Toast.makeText(ScanRes.this, "Passez votre badge",Toast.LENGTH_SHORT).show();
}
});
in2b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
nfcScanRight = true;
nfcAdapter.enableForegroundDispatch(ScanRes.this,pintent,null,null);
scanType = SCAN_IN;
if(photo_on){
takePictureAfterScan(ScanRes.this, "base64.txt", 2);
handler.post(new Runnable(){
@Override
public void run() {
initCamera();
startCameraSource();
}
});
}
//cancelScan(5, ScanRes.this, ScanRes.this);
Toast.makeText(ScanRes.this, "Passez votre badge",Toast.LENGTH_SHORT).show();
}
});
out2b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
nfcScanRight = true;
nfcAdapter.enableForegroundDispatch(ScanRes.this,pintent,null,null);
scanType = SCAN_OUT;
if(photo_on){
takePictureAfterScan(ScanRes.this, "base64.txt", 2);
handler.post(new Runnable(){
@Override
public void run() {
initCamera();
startCameraSource();
}
});
}
//cancelScan(5, ScanRes.this, ScanRes.this);
Toast.makeText(ScanRes.this, "Passez votre badge",Toast.LENGTH_SHORT).show();
}
});
if(special_on){
in.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
scanType = SCAN;
if(photo_on){
takePictureAfterScan(ScanRes.this, "base64.txt", 2);
}
Intent ScanSpecial = new Intent(ScanRes.this, ScanSpecial.class);
startActivityForResult(ScanSpecial, SPECIAL_SCAN_REQUEST_CODE);
return true;
}
});
in2b.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
scanType = SCAN_IN;
if(photo_on){
takePictureAfterScan(ScanRes.this, "base64.txt", 2);
}
Intent ScanSpecial = new Intent(ScanRes.this, ScanSpecial.class);
startActivityForResult(ScanSpecial, SPECIAL_SCAN_REQUEST_CODE);
return true;
}
});
out2b.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
scanType = SCAN_OUT;
if(photo_on){
takePictureAfterScan(ScanRes.this, "base64.txt", 2);
}
Intent ScanSpecial = new Intent(ScanRes.this, ScanSpecial.class);
startActivityForResult(ScanSpecial, SPECIAL_SCAN_REQUEST_CODE);
return true;
}
});
}
Log.i("onstart", "onstart");
}
@Override
protected void onResume() {
super.onResume();
handler.post(new Runnable(){
@Override
public void run() {
if(photo_on){
initCamera();
startCameraSource();
}
//if(netWorskStatus) sendUnregisteredScans(ScanRes.this);
}
});
if(netWorskStatus) sendUnregisteredScans(ScanRes.this);
assert nfcAdapter != null;
//Dans le cas où l'on a pas de bouton, on active le foregroundDispatch pour lire la carte sans avoir à appuyer sur un bouton
if(nbr_bouton == 0){
nfcScanRight = true;
nfcAdapter.enableForegroundDispatch(ScanRes.this,pintent,null,null);
}
Log.i("onresume", "onresume");
}
@Override
protected void onPause() {
super.onPause();
if (nfcAdapter != null) {
nfcAdapter.disableForegroundDispatch(this);
}
Log.i("onpause", "onpause");
}
@Override
protected void onDestroy() {
super.onDestroy();
unRegisterNetworkBroadcastReceiver(connectionState);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if(camera != null){
camera.release();
}
Log.i("ondestroy", "ondestroy");
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
if(nfcScanRight){
resolveIntent(intent);
startCameraSource();
}
else{
Toast.makeText(this, "Veuillez appuyer sur l'un des boutons avant de Scanner", Toast.LENGTH_SHORT);
}
Log.i("onNewIntent", "onNewIntent");
}
private void resolveIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Tag tag = (Tag) intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
assert tag != null;
String nfc = getTagID(tag);
handler.post(new Runnable(){
@Override
public void run() {
if(nbr_bouton == 0){
takePictureAfterScan(ScanRes.this, "base64.txt", 2);
}
JSONObject data = new JSONObject();
data = JSONDataBuilder(nfcID, base64Img, Latitude, Longitude, Accuracy);
if(gps_force && Latitude!= null && Longitude != null && Accuracy != null){
if(!sendToServer(data)){
Toast.makeText(ScanRes.this,"Vous n'êtes pas connecté à internet, le pointage sera envoyé lorsque vous serez connecté", Toast.LENGTH_SHORT).show();
Write(ScanRes.this, data.toString(), "listePointagesNonEnvoyes.txt");
}
}
else{
if(!sendToServer(data)){
Toast.makeText(ScanRes.this,"Vous n'êtes pas connecté à internet, le pointage sera envoyé lorsque vous serez connecté", Toast.LENGTH_SHORT).show();
Write(ScanRes.this, data.toString(), "listePointagesNonEnvoyes.txt");
// Write(ScanRes.this, data.toString(), "listePointagesNonEnvoyes.txt");
}
}
}
});
}
}
private String getTagID(Tag tag){
byte[] id = tag.getId();
nfcID = toReversedHex(id).replaceAll("\s", "");
nfcScanRight = false;
return nfcID;
}
private String toReversedHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; ++i) {
if (i > 0) {
sb.append(" ");
}
int b = bytes[i] & 0xff;
if (b < 0x10)
sb.append('0');
sb.append(Integer.toHexString(b));
}
return sb.toString();
}
}
这是我的清单文件内容:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.digitalnomade.pointeusenomade"
android:versionCode="2"
android:versionName="3.0.0">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature
android:name="android.hardware.nfc"
android:required="true" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-feature android:name="android.hardware.location.gps" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:extractNativeLibs="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar">
<activity android:name=".sccanact"></activity>
<activity android:name=".SelectionChantiers" />
<activity android:name=".ScanSpecial" />
<activity android:name=".Infos" />
<activity android:name=".Admin" />
<activity
android:name=".ScanRes"
android:configChanges="orientation"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
最近有很多关于此的问题,它似乎非常特定于设备,旧相机的文档 API 说某些设备可能会阻止您应用程序的主事件循环,并且您正在使用的旧 NFC API 需要暂停和恢复您的应用程序,以便主事件循环接收来自 NFC 的数据。
如果您的应用程序的目标用户是 API 19 岁及以上,我将始终使用名为 enableReaderMode
的更新更好的 NFC API,而不是 enableForegroundDispatch
。
这个更新的 API 给了你更多的控制权,它不需要暂停和恢复你的应用程序,数据在它自己的线程中处理,不会被主事件阻塞由相机循环。
请注意,我没有尝试使用 enableReaderMode
进行相机操作,我总是将它用于 NFC 操作,因为它是使用 NFC 的更好方法。
我必须制作一个扫描 NFC 卡的应用程序,然后同时拍照并将此信息发送到服务器,但我的问题是 android 11 上的设备未检测到我的 NFC 标签与 android 6 到 android 9 上的设备不同。当我按下按钮(拍摄照片(in、in2b 和 out2b)然后仅在 onPause 方法中禁用它时,我启用了前台调度. 此外,当我的应用程序为 运行 时,其他应用程序(如 NFC 工具)无法检测到任何 NFC 标签,除非我停止我的应用程序。如果有人知道问题的根源,欢迎帮助,谢谢 这是我的代码:
public class ScanRes extends AppCompatActivity {
private NfcAdapter nfcAdapter;
private PendingIntent pintent;
private String nfcID = "";
private ImageView imgpts;
private int nbrClicks = 0;
private TextView battery;
private String URLAPI;
private TextView msg_in;
private TextView msg_out;
private static boolean netWorskStatus = true;
private NetworkChangeReceiver connectionState;
private SurfaceView cameraDisplay;
private Camera camera;
SurfaceHolder surfaceHolder;
//Valeurs Latitude et Longitude init au début
private String Longitude = null;
private String Latitude = null;
private String Accuracy = null;
private ImageView in;
private ImageView in2b;
private ImageView out2b;
private TextView msg_sans_btn;
private static final String SCAN_IN = "in";
private static final String SCAN_OUT = "ou";
private static final String SCAN = "u";
private String specialScanReason = "";
private String selectedChantier = "";
private String scanType="";
private TextView in_msg;
//Variables qui vont stocker les options téléchargées via le serveur
private int gps_frequency;
private boolean photo_on;
private int nbr_bouton;
private boolean saved;
private boolean mode_kiosque_on;
private boolean gps_force;
private boolean mode_chantier_on;
private boolean special_on;
private boolean gps_on;
private String nomChantierCourant;
private String base64Img = "";
private TextView msg_if_mode_boutons;
private boolean mode_controle_acces_on;
private boolean nfcScanRight = false;
public static Handler handler; //Attention, il était private avant
public static HandlerThread handlerThread;
public static Looper looper;
private Handler handlerUS;
public static HandlerThread handlerThreadUS;
public static Looper looperUS;
private static final int SPECIAL_SCAN_REQUEST_CODE = 00005;
private static final int SELECTION_CHANTIERS_REQUEST_CODE = 00010;
private static final int ADMIN_ACTIVITY_REQUEST_CODE = 5024;
String chantiers[];
private TextView chantierCourant;
private void takePictureAfterScan(Context currentContext, String fileName, int rapportDeDivision){
try{
camera.takePicture(null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
//startCameraSource();
Bitmap im = BitmapFactory.decodeByteArray(data, 0, data.length);
Matrix matrix = new Matrix();
matrix.postRotate(-90);
Bitmap image = Bitmap.createBitmap(im, 0, 0, im.getWidth(), im.getHeight(), matrix, true);
Bitmap resized = Bitmap.createScaledBitmap(image, im.getWidth()/rapportDeDivision, im.getHeight()/rapportDeDivision, false);
ByteArrayOutputStream byteArrayOutputStreamc = new ByteArrayOutputStream();
resized.compress(Bitmap.CompressFormat.JPEG, 50, byteArrayOutputStreamc);
byte[] byteArrayc = byteArrayOutputStreamc.toByteArray();
//String imgBuffc = Base64.encodeToString(byteArrayc, Base64.NO_WRAP);
base64Img = Base64.encodeToString(byteArrayc, Base64.NO_WRAP);
//WriteOnce(currentContext, imgBuffc, fileName);
}
});
}catch(Exception e){
e.printStackTrace();
}
}
private void startCameraSource(){
//cameraDisplay = (SurfaceView) findViewById(R.id.camera);
if ((cameraDisplay != null) && (cameraDisplay.getHolder() != null) && (camera != null)) {
try {
camera.setPreviewDisplay(cameraDisplay.getHolder());
camera.startPreview();
} catch (Exception e) {
}
}
}
//Fonction initialisant la caméra
private void initCamera() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 2552);
return;
}
//cameraDisplay = (SurfaceView) findViewById(R.id.camera);
try {
if (camera != null)
camera.release();
camera =null;
camera = Camera.open(1);
camera.setDisplayOrientation(90);
//cameraDisplay.setVisibility(View.VISIBLE);
cameraDisplay.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
startCameraSource();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
} catch (RuntimeException e) {
if (camera == null)
//setText("camera error");
Log.i("CAMERA", "CAMERA ERROR");
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan_res);
connectionState = new NetworkChangeReceiver();
registerNetworkBroadcastReceiver(connectionState);
surfaceHolder = cameraDisplay.getHolder();
handlerThread = new HandlerThread("MyHandlerThread", Thread.MAX_PRIORITY);
handlerThread.start();
looper = handlerThread.getLooper();
handler = new Handler(looper);
handler.post(new Runnable(){
@Override
public void run() {
if(photo_on) {
initCamera();
}
}
});
//Init NFC Adapter
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
//If no NfcAdapter, display that the device has no NFC
if (nfcAdapter == null){
Toast.makeText(this,"Votre appareil n'est pas compatible avec le NFC", Toast.LENGTH_SHORT).show();
finish();
}
pintent = PendingIntent.getActivity(this,0,new Intent(this,this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);
}
@SuppressLint("ClickableViewAccessibility")
@Override
protected void onStart(){
super.onStart();
in.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
nfcScanRight = true;
nfcAdapter.enableForegroundDispatch(ScanRes.this,pintent,null,null);
scanType = SCAN;
if(photo_on){
takePictureAfterScan(ScanRes.this, "base64.txt", 2);
handler.post(new Runnable(){
@Override
public void run() {
initCamera();
startCameraSource();
}
});
}
Toast.makeText(ScanRes.this, "Passez votre badge",Toast.LENGTH_SHORT).show();
}
});
in2b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
nfcScanRight = true;
nfcAdapter.enableForegroundDispatch(ScanRes.this,pintent,null,null);
scanType = SCAN_IN;
if(photo_on){
takePictureAfterScan(ScanRes.this, "base64.txt", 2);
handler.post(new Runnable(){
@Override
public void run() {
initCamera();
startCameraSource();
}
});
}
//cancelScan(5, ScanRes.this, ScanRes.this);
Toast.makeText(ScanRes.this, "Passez votre badge",Toast.LENGTH_SHORT).show();
}
});
out2b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
nfcScanRight = true;
nfcAdapter.enableForegroundDispatch(ScanRes.this,pintent,null,null);
scanType = SCAN_OUT;
if(photo_on){
takePictureAfterScan(ScanRes.this, "base64.txt", 2);
handler.post(new Runnable(){
@Override
public void run() {
initCamera();
startCameraSource();
}
});
}
//cancelScan(5, ScanRes.this, ScanRes.this);
Toast.makeText(ScanRes.this, "Passez votre badge",Toast.LENGTH_SHORT).show();
}
});
if(special_on){
in.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
scanType = SCAN;
if(photo_on){
takePictureAfterScan(ScanRes.this, "base64.txt", 2);
}
Intent ScanSpecial = new Intent(ScanRes.this, ScanSpecial.class);
startActivityForResult(ScanSpecial, SPECIAL_SCAN_REQUEST_CODE);
return true;
}
});
in2b.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
scanType = SCAN_IN;
if(photo_on){
takePictureAfterScan(ScanRes.this, "base64.txt", 2);
}
Intent ScanSpecial = new Intent(ScanRes.this, ScanSpecial.class);
startActivityForResult(ScanSpecial, SPECIAL_SCAN_REQUEST_CODE);
return true;
}
});
out2b.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
scanType = SCAN_OUT;
if(photo_on){
takePictureAfterScan(ScanRes.this, "base64.txt", 2);
}
Intent ScanSpecial = new Intent(ScanRes.this, ScanSpecial.class);
startActivityForResult(ScanSpecial, SPECIAL_SCAN_REQUEST_CODE);
return true;
}
});
}
Log.i("onstart", "onstart");
}
@Override
protected void onResume() {
super.onResume();
handler.post(new Runnable(){
@Override
public void run() {
if(photo_on){
initCamera();
startCameraSource();
}
//if(netWorskStatus) sendUnregisteredScans(ScanRes.this);
}
});
if(netWorskStatus) sendUnregisteredScans(ScanRes.this);
assert nfcAdapter != null;
//Dans le cas où l'on a pas de bouton, on active le foregroundDispatch pour lire la carte sans avoir à appuyer sur un bouton
if(nbr_bouton == 0){
nfcScanRight = true;
nfcAdapter.enableForegroundDispatch(ScanRes.this,pintent,null,null);
}
Log.i("onresume", "onresume");
}
@Override
protected void onPause() {
super.onPause();
if (nfcAdapter != null) {
nfcAdapter.disableForegroundDispatch(this);
}
Log.i("onpause", "onpause");
}
@Override
protected void onDestroy() {
super.onDestroy();
unRegisterNetworkBroadcastReceiver(connectionState);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if(camera != null){
camera.release();
}
Log.i("ondestroy", "ondestroy");
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
if(nfcScanRight){
resolveIntent(intent);
startCameraSource();
}
else{
Toast.makeText(this, "Veuillez appuyer sur l'un des boutons avant de Scanner", Toast.LENGTH_SHORT);
}
Log.i("onNewIntent", "onNewIntent");
}
private void resolveIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Tag tag = (Tag) intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
assert tag != null;
String nfc = getTagID(tag);
handler.post(new Runnable(){
@Override
public void run() {
if(nbr_bouton == 0){
takePictureAfterScan(ScanRes.this, "base64.txt", 2);
}
JSONObject data = new JSONObject();
data = JSONDataBuilder(nfcID, base64Img, Latitude, Longitude, Accuracy);
if(gps_force && Latitude!= null && Longitude != null && Accuracy != null){
if(!sendToServer(data)){
Toast.makeText(ScanRes.this,"Vous n'êtes pas connecté à internet, le pointage sera envoyé lorsque vous serez connecté", Toast.LENGTH_SHORT).show();
Write(ScanRes.this, data.toString(), "listePointagesNonEnvoyes.txt");
}
}
else{
if(!sendToServer(data)){
Toast.makeText(ScanRes.this,"Vous n'êtes pas connecté à internet, le pointage sera envoyé lorsque vous serez connecté", Toast.LENGTH_SHORT).show();
Write(ScanRes.this, data.toString(), "listePointagesNonEnvoyes.txt");
// Write(ScanRes.this, data.toString(), "listePointagesNonEnvoyes.txt");
}
}
}
});
}
}
private String getTagID(Tag tag){
byte[] id = tag.getId();
nfcID = toReversedHex(id).replaceAll("\s", "");
nfcScanRight = false;
return nfcID;
}
private String toReversedHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; ++i) {
if (i > 0) {
sb.append(" ");
}
int b = bytes[i] & 0xff;
if (b < 0x10)
sb.append('0');
sb.append(Integer.toHexString(b));
}
return sb.toString();
}
}
这是我的清单文件内容:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.digitalnomade.pointeusenomade"
android:versionCode="2"
android:versionName="3.0.0">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature
android:name="android.hardware.nfc"
android:required="true" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-feature android:name="android.hardware.location.gps" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:extractNativeLibs="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar">
<activity android:name=".sccanact"></activity>
<activity android:name=".SelectionChantiers" />
<activity android:name=".ScanSpecial" />
<activity android:name=".Infos" />
<activity android:name=".Admin" />
<activity
android:name=".ScanRes"
android:configChanges="orientation"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
最近有很多关于此的问题,它似乎非常特定于设备,旧相机的文档 API 说某些设备可能会阻止您应用程序的主事件循环,并且您正在使用的旧 NFC API 需要暂停和恢复您的应用程序,以便主事件循环接收来自 NFC 的数据。
如果您的应用程序的目标用户是 API 19 岁及以上,我将始终使用名为 enableReaderMode
的更新更好的 NFC API,而不是 enableForegroundDispatch
。
这个更新的 API 给了你更多的控制权,它不需要暂停和恢复你的应用程序,数据在它自己的线程中处理,不会被主事件阻塞由相机循环。
请注意,我没有尝试使用 enableReaderMode
进行相机操作,我总是将它用于 NFC 操作,因为它是使用 NFC 的更好方法。