NFC beam the repo in RepoDetailsActivity

This is the framework for easily swapping repos.  The idea is that a user
can send the URL with the fingerprint for trusted bootstrapping of the repo
on a new user's device.  This will be essential for p2p repos provided
by Bazaar/Kerplapp.

The required NFC APIs were introduced in android-14. So android-14 and below
skip the NFC stuff.
This commit is contained in:
Hans-Christoph Steiner 2014-01-31 21:49:13 -05:00
parent 220b3d1441
commit 4489037619
2 changed files with 100 additions and 5 deletions

View File

@ -20,12 +20,16 @@
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<uses-feature
android:name="android.hardware.nfc"
android:required="false" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.NFC" />
<application
android:name="FDroidApp"
@ -135,14 +139,36 @@
<data android:scheme="fdroidrepos" />
<data android:scheme="FDROIDREPOS" />
</intent-filter>
</activity>
<!-- Handle NFC tags detected from outside our application -->
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<!--
URIs that come in via NFC have scheme/host normalized to all lower case
https://developer.android.com/reference/android/nfc/NfcAdapter.html#ACTION_NDEF_DISCOVERED
-->
<data android:scheme="fdroidrepo" />
<data android:scheme="fdroidrepos" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/vnd.org.fdroid.fdroid.repo" />
</intent-filter>
</activity>
<activity
android:name=".NfcNotEnabledActivity"
android:noHistory="true" />
<activity
android:name=".views.RepoDetailsActivity"
android:label="@string/menu_manage"
android:parentActivityName=".ManageRepo"
android:windowSoftInputMode="stateHidden" />
<activity
android:name=".AppDetails"
android:label="@string/app_details"

View File

@ -1,12 +1,21 @@
package org.fdroid.fdroid.views;
import android.annotation.TargetApi;
import android.content.Intent;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.FragmentActivity;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.compat.ActionBarCompat;
@ -15,10 +24,13 @@ import org.fdroid.fdroid.data.RepoProvider;
import org.fdroid.fdroid.views.fragments.RepoDetailsFragment;
public class RepoDetailsActivity extends FragmentActivity {
public static final String TAG = "RepoDetailsActivity";
private WifiManager wifiManager;
private Repo repo;
static final String MIME_TYPE = "application/vnd.org.fdroid.fdroid.repo";
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -32,9 +44,9 @@ public class RepoDetailsActivity extends FragmentActivity {
RepoDetailsFragment fragment = new RepoDetailsFragment();
fragment.setArguments(getIntent().getExtras());
getSupportFragmentManager()
.beginTransaction()
.add(android.R.id.content, fragment)
.commit();
.beginTransaction()
.add(android.R.id.content, fragment)
.commit();
}
String[] projection = new String[] {
@ -48,6 +60,63 @@ public class RepoDetailsActivity extends FragmentActivity {
setTitle(repo.getName());
wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
// required NFC support starts in android-14
if (Build.VERSION.SDK_INT >= 14)
setNfc();
}
@TargetApi(14)
private void setNfc() {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
return;
}
nfcAdapter.setNdefPushMessage(new NdefMessage(new NdefRecord[] {
NdefRecord.createUri(getSharingUri()),
}), this);
findViewById(android.R.id.content).post(new Runnable() {
@Override
public void run() {
Log.i(TAG, "Runnable.run()");
onNewIntent(getIntent());
}
});
}
@Override
public void onResume() {
Log.i(TAG, "onResume");
super.onResume();
if (Build.VERSION.SDK_INT >= 9)
processIntent(getIntent());
}
@Override
public void onNewIntent(Intent i) {
Log.i(TAG, "onNewIntent");
Log.i(TAG, "action: " + i.getAction());
Log.i(TAG, "data: " + i.getData());
// onResume gets called after this to handle the intent
setIntent(i);
}
@TargetApi(9)
void processIntent(Intent i) {
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(i.getAction())) {
Log.i(TAG, "ACTION_NDEF_DISCOVERED");
Parcelable[] rawMsgs =
i.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage msg = (NdefMessage) rawMsgs[0];
String url = new String(msg.getRecords()[0].getPayload());
Log.i(TAG, "Got this URL: " + url);
Toast.makeText(this, "Got this URL: " + url, Toast.LENGTH_LONG).show();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
String packageName = getPackageName();
intent.setClassName(packageName, packageName + ".ManageRepo");
startActivity(intent);
finish();
}
}
protected Uri getSharingUri() {