Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added res/drawable-hdpi/ic_qs_nfc_off.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added res/drawable-hdpi/ic_qs_nfc_on.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added res/drawable-mdpi/ic_qs_nfc_off.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added res/drawable-mdpi/ic_qs_nfc_on.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added res/drawable-xhdpi/ic_qs_nfc_off.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added res/drawable-xhdpi/ic_qs_nfc_on.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions res/layout/quick_settings_tile_nfc.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 The Android Open Source Project
Copyright (C) 2013 Peter Gregus for GravityBox Project (C3C076@xda)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/TextAppearance.QuickSettings.TileView"
android:id="@+id/nfc_tileview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center" />
4 changes: 4 additions & 0 deletions res/values/arrays.xml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
<item>@string/qs_tile_bluetooth</item>
<item>@string/qs_tile_gps</item>
<item>@string/qs_tile_gps_alt</item>
<item>@string/qs_tile_nfc</item>
<item>@string/qs_tile_mobile_data</item>
<item>@string/qs_tile_network_mode</item>
<item>@string/qs_tile_data_usage</item>
Expand Down Expand Up @@ -113,6 +114,7 @@
<item>bluetooth_textview</item>
<item>gps_textview</item>
<item>gps_tileview</item>
<item>nfc_tileview</item>
<item>data_conn_textview</item>
<item>network_mode_tileview</item>
<item>rssi_textview</item>
Expand Down Expand Up @@ -145,6 +147,7 @@
<item>@string/qs_tile_airplane_mode</item>
<item>@string/qs_tile_bluetooth</item>
<item>@string/qs_tile_gps</item>
<item>@string/qs_tile_nfc</item>
<item>@string/qs_tile_ringer_mode</item>
<item>@string/qs_tile_volume</item>
<item>@string/qs_tile_network_mode</item>
Expand All @@ -171,6 +174,7 @@
<item>airplane_mode_textview</item>
<item>bluetooth_textview</item>
<item>gps_tileview</item>
<item>nfc_tileview</item>
<item>ringer_mode_tileview</item>
<item>volume_tileview</item>
<item>network_mode_tileview</item>
Expand Down
3 changes: 3 additions & 0 deletions res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@
<string name="quick_settings_wifi_off">Wi-Fi off</string>
<string name="quick_settings_wifi_not_connected">Not connected</string>
<string name="quick_settings_wifi_turning_on">Turning on&#8230;</string>
<string name="quick_settings_nfc">NFC</string>
<string name="quick_settings_nfc_off">NFC off</string>

<!-- QuickSettings settings -->
<string name="quick_settings_title">Statusbar QuickSettings tiles</string>
Expand Down Expand Up @@ -129,6 +131,7 @@
<string name="qs_tile_expanded_desktop">Expanded desktop</string>
<string name="qs_tile_stay_awake">Stay awake</string>
<string name="qs_tile_screenshot">Screenshot</string>
<string name="qs_tile_nfc">NFC</string>

<!-- Color Picker -->
<string name="dialog_color_picker">Color Picker</string>
Expand Down
10 changes: 9 additions & 1 deletion src/com/ceco/gm2/gravitybox/ModQuickSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.ceco.gm2.gravitybox.quicksettings.ExpandedDesktopTile;
import com.ceco.gm2.gravitybox.quicksettings.GpsTile;
import com.ceco.gm2.gravitybox.quicksettings.NetworkModeTile;
import com.ceco.gm2.gravitybox.quicksettings.NfcTile;
import com.ceco.gm2.gravitybox.quicksettings.QuickAppTile;
import com.ceco.gm2.gravitybox.quicksettings.QuickRecordTile;
import com.ceco.gm2.gravitybox.quicksettings.RingerModeTile;
Expand Down Expand Up @@ -152,7 +153,8 @@ public class ModQuickSettings {
R.id.stay_awake_tileview,
R.id.screenshot_tileview,
R.id.gps_tileview,
R.id.ringer_mode_tileview
R.id.ringer_mode_tileview,
R.id.nfc_tileview
));
if (Utils.isMtkDevice()) {
mCustomGbTileKeys.add(R.id.wifi_tileview);
Expand Down Expand Up @@ -594,6 +596,12 @@ protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
gpsTile.setupQuickSettingsTile(mContainerView, inflater, mPrefs);
mTiles.add(gpsTile);
}

if (Utils.hasNFC(mContext)) {
NfcTile nfcTile = new NfcTile(mContext, mGbContext, mStatusBar, mPanelBar);
nfcTile.setupQuickSettingsTile(mContainerView, inflater);
mTiles.add(nfcTile);
}

RingerModeTile rmTile = new RingerModeTile(mContext, mGbContext, mStatusBar, mPanelBar);
rmTile.setupQuickSettingsTile(mContainerView, inflater, mPrefs);
Expand Down
15 changes: 15 additions & 0 deletions src/com/ceco/gm2/gravitybox/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public class Utils {
private static Boolean mHasVibrator = null;
private static Boolean mHasFlash = null;
private static Boolean mHasGPS = null;
private static Boolean mHasNFC = null;

// Supported MTK devices
private static final Set<String> MTK_DEVICES = new HashSet<String>(Arrays.asList(
Expand Down Expand Up @@ -214,6 +215,20 @@ public static boolean hasGPS(Context con) {
}
}

public static boolean hasNFC(Context con) {
if (mHasNFC != null) return mHasNFC;
PackageManager pm = con.getPackageManager();
if (pm == null) {
if (DEBUG) log("Cannot get package manager, assuming no NFC feature");
mHasNFC = null;
return false;
}

mHasNFC = pm.hasSystemFeature(PackageManager.FEATURE_NFC);

return mHasNFC;
}

public static String getDeviceCharacteristics() {
if (mDeviceCharacteristics != null) return mDeviceCharacteristics;

Expand Down
160 changes: 160 additions & 0 deletions src/com/ceco/gm2/gravitybox/quicksettings/NfcTile.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package com.ceco.gm2.gravitybox.quicksettings;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NfcAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

import com.ceco.gm2.gravitybox.R;

import de.robv.android.xposed.XposedHelpers;

public class NfcTile extends AQuickSettingsTile {

private static final String INTENT_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED";
private static final String INTENT_NFC_SETTINGS = "android.settings.NFC_SETTINGS";

private static final int STATE_TURNING_ON = XposedHelpers.getStaticIntField(NfcAdapter.class, "STATE_TURNING_ON");
private static final int STATE_ON = XposedHelpers.getStaticIntField(NfcAdapter.class, "STATE_ON");
@SuppressWarnings("unused")
private static final int STATE_TURNING_OFF = XposedHelpers.getStaticIntField(NfcAdapter.class, "STATE_TURNING_OFF");
private static final int STATE_OFF = XposedHelpers.getStaticIntField(NfcAdapter.class, "STATE_OFF");
private static final int NFC_ADAPTER_UNKNOWN = -100;

@SuppressWarnings("unused")
private static final String TAG = "GB:NfcTile";

private static NfcAdapter mNfcAdapter = null;

private BroadcastReceiver mNfcStateChangedReceiver = new BroadcastReceiver() {

@Override
public void onReceive(Context context, Intent intent) {
if (INTENT_ADAPTER_STATE_CHANGED.equals(intent.getAction())) {
if (mNfcAdapter == null)
getNfcAdapter(true);
updateTile(getNfcState());
}
}
};

private TextView mTextView;

public NfcTile(Context context, Context gbContext, Object statusBar, Object panelBar) {
super(context, gbContext, statusBar, panelBar);

mOnClick = new View.OnClickListener() {

@Override
public void onClick(View v) {
toggleState();
}
};

mOnLongClick = new View.OnLongClickListener() {

@Override
public boolean onLongClick(View v) {
Intent intent = new Intent(INTENT_NFC_SETTINGS);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
return true;
}
};
}

private void toggleState() {
int state = getNfcState();
/* For some reason, a switch-case way of handling this didn't work */

if (mNfcAdapter == null)
getNfcAdapter(true);

if (mNfcAdapter == null) {
return;
}

if (state == STATE_TURNING_ON || state == STATE_ON)
XposedHelpers.callMethod(mNfcAdapter, "disable");
else
XposedHelpers.callMethod(mNfcAdapter, "enable");

updateTile();
}

@Override
protected void onTileCreate() {
LayoutInflater inflater = LayoutInflater.from(mGbContext);
inflater.inflate(R.layout.quick_settings_tile_nfc, mTile);
mTextView = (TextView) mTile.findViewById(R.id.nfc_tileview);

mTextView.setText(mLabel);
mTextView.setCompoundDrawablesWithIntrinsicBounds(0, mDrawableId, 0, 0);
}

@Override
protected void updateTile() {
updateTile(getNfcState());
}

private void updateTile(int state) {
if (state == STATE_TURNING_ON || state == STATE_ON) {
mDrawableId = R.drawable.ic_qs_nfc_on;
mLabel = mGbContext.getString(R.string.quick_settings_nfc);
} else {
mDrawableId = R.drawable.ic_qs_nfc_off;
mLabel = mGbContext.getString(R.string.quick_settings_nfc_off);
}

if (mTextView != null) {
mTextView.setText(mLabel);
mTextView.setCompoundDrawablesWithIntrinsicBounds(0, mDrawableId, 0, 0);
}
}

private int getNfcState() {
int state = STATE_OFF;
try {
getNfcAdapter(false);
} catch (UnsupportedOperationException e) {
state = NFC_ADAPTER_UNKNOWN;
}

if (mNfcAdapter != null)
state = (Integer) XposedHelpers.callMethod(mNfcAdapter, "getAdapterState");

return state;
}

@Override
protected void onTilePostCreate() {
mContext.registerReceiver(mNfcStateChangedReceiver,
new IntentFilter(INTENT_ADAPTER_STATE_CHANGED));

super.onTilePostCreate();
}

private void getNfcAdapter(boolean suppressThrow) throws UnsupportedOperationException {
Class<?> ServiceManager;
try {
ServiceManager = Class.forName("android.os.ServiceManager");
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
return;
}

if (mNfcAdapter == null && XposedHelpers.callStaticMethod(ServiceManager, "getService", "nfc") != null) {
try {
mNfcAdapter = NfcAdapter.getDefaultAdapter(mContext);
} catch (UnsupportedOperationException e) {
if (!suppressThrow)
throw e;
}
}
}
}