12

Я пытаюсь отправить String через NFC, когда мое приложение использует screen pinning. Это не работает: передача не происходит; но если я отключу экран, закрепляющий передачу String работ.Как я могу отправить строку через NFC во время Screen-Pinning?

Я могу отключить привязку экрана немного, а затем выполнить передачу, но это риск для безопасности.

Как я могу это сделать?


Вот код, если вы хотите попробовать. Все, что вам нужно сделать, это разрешить привязку экрана вручную через настройки вашего приложения (так что это меньше кода и все равно дает тот же результат). Я тестировал это, используя два Nexus 7 с Android 5.0.

Вам не нужно читать весь этот код, этот вопрос, вероятно, может быть решен, если вы знаете что-то, что я могу добавить к моему манифесту, что позволит NFC при наложении экрана.


AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.androidnfc" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="16" 
     android:targetSdkVersion="19" /> 
    <uses-permission android:name="android.permission.NFC"/> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name="com.example.androidnfc.MainActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 

      <intent-filter> 
       <action android:name="android.nfc.action.NDEF_DISCOVERED" /> 
       <category android:name="android.intent.category.DEFAULT" /> 
       <data android:mimeType="text/plain" /> 
      </intent-filter> 
     </activity> 
    </application> 
</manifest> 

MainActivity.java

public class MainActivity extends Activity implements CreateNdefMessageCallback, OnNdefPushCompleteCallback 
{ 
    TextView textInfo; 
    EditText textOut; 
    NfcAdapter nfcAdapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     textInfo = (TextView)findViewById(R.id.info); 
     textOut = (EditText)findViewById(R.id.textout); 

     nfcAdapter = NfcAdapter.getDefaultAdapter(this); 
     nfcAdapter.setNdefPushMessageCallback(this, this); 
     nfcAdapter.setOnNdefPushCompleteCallback(this, this); 
    } 

    @Override 
    protected void onResume() 
    { 
     super.onResume(); 
     Intent intent = getIntent(); 
     String action = intent.getAction(); 

     if(action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) 
     { 
     Parcelable[] parcelables = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); 
     NdefMessage inNdefMessage = (NdefMessage)parcelables[0]; 
     NdefRecord[] inNdefRecords = inNdefMessage.getRecords(); 
     NdefRecord NdefRecord_0 = inNdefRecords[0]; 
     String inMsg = new String(NdefRecord_0.getPayload()); 
     textInfo.setText(inMsg); 
     } 
    } 

    @Override 
    protected void onNewIntent(Intent intent) { 
    setIntent(intent); 
    } 

    @Override 
    public void onNdefPushComplete(NfcEvent event) { 
     final String eventString = "onNdefPushComplete\n" + event.toString(); 
     runOnUiThread(new Runnable() { 

     @Override 
     public void run() { 
      Toast.makeText(getApplicationContext(), eventString, Toast.LENGTH_LONG).show(); 
     } 
     }); 
    } 

    @Override 
    public NdefMessage createNdefMessage(NfcEvent event) { 
     String stringOut = textOut.getText().toString(); 
     byte[] bytesOut = stringOut.getBytes(); 

     NdefRecord ndefRecordOut = new NdefRecord(
     NdefRecord.TNF_MIME_MEDIA, 
     "text/plain".getBytes(), 
       new byte[] {}, 
       bytesOut); 

     NdefMessage ndefMessageout = new NdefMessage(ndefRecordOut); 
     return ndefMessageout; 
    } 
} 

макет

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    android:orientation="vertical" 
    tools:context="com.example.androidnfc.MainActivity" > 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_horizontal" 
     android:textStyle="bold" /> 

    <EditText 
     android:id="@+id/textout" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 

    <TextView 
     android:id="@+id/info" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 
</LinearLayout> 
+0

Пытались ли вы свой пример?Какую версию и устройство Android вы проверили? Я только что протестировал приложение Nexus 4 под управлением Android 5.0.1 (LRX22C), и ваш пример отлично работает, даже когда экран закреплен. –

+0

Я попробовал его с двумя Nexus 7s, работающими под управлением Android 5. Оба устройства должны иметь экран, на котором можно запускать проблемы. –

+0

На Android 5.0.1 в вашем примере все еще вид работ: на приемном устройстве экран автоматически * отключен * и запускается новый экземпляр активности. Может ли это быть связано с ручным закреплением и не делать это через программный код? –

ответ

4

Я не уверен, действительно ли это отвечает на ваш вопрос, но я хотел бы обобщить мои выводы:

При попытке вашего примера на Android 5.0.1 (LRX22C на Nexus 4) принимающая сторона автоматически отключает экран после приема сообщения NDEF и (повторного) запуска активности. Таким образом, кажется, что фильтр намерения, который зарегистрирован в манифесте, получает приоритет над (ручным?) Привязкой экрана.

Я знаю, что это не совсем соответствует опыту, описанному в вопросе. Мне интересно, связано ли это с другой версией Android (5.0 по сравнению с 5.0.1) или из-за использования ручного экранного пиннинга вместо программного привязки экрана ...

В моей тестовой настройке я был способный решить проблему (т. е. предотвратить автоматическое отключение активности), используя систему диспетчеризации переднего плана для регистрации активности для получения своего сообщения NDEF:

В вашем методе onResume() создайте ожидающее этого намерения и включите отправку переднего плана:

PendingIntent pi = this.createPendingResult(0x00A, new Intent(), 0); 
nfcAdapter.enableForegroundDispatch(this, pi, null, null); 

После этого вы получите намерения нет tifying вам об обнаруженных тегов через onActivityResult() метода активность в:

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    switch (requestCode) { 
     case 0x00A: 
      onNewIntent(data); 
     break; 
    } 
} 

Кроме того, вы должны отключить передний план отправки в методе onPause():

nfcAdapter.disableForegroundDispatch(this);