I'm developing SIP client for Android and a have a problem. The problem is that I don't have audio while two clients are connected. The server that I'm using is www.minisipserver.com. The method onCallEstablished from the SipAudioCall.Listener is called every time.
This is the class which extends BroadcastReceiver, which is listening for the call.
`
package uk.co.tbw.sip.calling;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.sip.SipAudioCall;
import android.net.sip.SipException;
import android.net.sip.SipProfile;
import uk.co.tbw.utils.TBWLogger;
public class IncomingCallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
SipAudioCall incomingCall = null;
try {
Call callActivity = (Call) context;
SipAudioCall.Listener listener = new myListener(context);
incomingCall = callActivity.mManager.takeAudioCall(intent, listener);
incomingCall.startAudio();
callActivity.mAudioCall = incomingCall;
callActivity.updateStatus(incomingCall);
} catch (SipException e) {
if (incomingCall != null) {
incomingCall.close();
e.printStackTrace();
}
}
}
class myListener extends SipAudioCall.Listener {
private Context context;
public myListener(Context context) {
this.context = context;
}
#Override
public void onRinging(SipAudioCall call, SipProfile caller) {
try {
call.answerCall(30);
} catch (SipException e) {
e.printStackTrace();
}
}
#Override
public void onReadyToCall(SipAudioCall call) {
TBWLogger.d("IncomingCallReceiver.java onReadyToCall : " + call.toString());
}
#Override
public void onCalling(SipAudioCall call) {
TBWLogger.d("IncomingCallReceiver.java onCalling : " + call.toString());
}
#Override
public void onRingingBack(SipAudioCall call) {
TBWLogger.d("IncomingCallReceiver.java onRingingBack : " + call.toString());
}
#Override
public void onCallEstablished(SipAudioCall call) {
TBWLogger.d("IncomingCallReceiver.java onCallEstablished : " + call.toString());
if (call.isInCall()) {
TBWLogger.d("IncomingCallReceiver.java isInCall : " + call.toString());
}
if (call.isOnHold()) {
TBWLogger.d("IncomingCallReceiver.java isOnHold : " + call.toString());
}
if (call.isMuted()) {
TBWLogger.d("IncomingCallReceiver.java isMuted : " + call.toString());
}
call.startAudio();
}
#Override
public void onCallEnded(SipAudioCall call) {
TBWLogger.d("IncomingCallReceiver.java onCallEnded : " + call.toString());
}
#Override
public void onCallBusy(SipAudioCall call) {
TBWLogger.d("IncomingCallReceiver.java onCallBusy : " + call.toString());
}
#Override
public void onCallHeld(SipAudioCall call) {
TBWLogger.d("IncomingCallReceiver.java onCallHeld : " + call.toString());
}
#Override
public void onError(SipAudioCall call, int errorCode, String errorMessage) {
TBWLogger.d("IncomingCallReceiver.java IncomingCallReceiver.java onError : " + call.toString() + "; errorCode: " + errorCode + "; errorMessage: " + errorMessage);
}
#Override
public void onChanged(SipAudioCall call) {
TBWLogger.d("IncomingCallReceiver.java onReadyToCall : " + call.toString());
}
}
}
`
Call.java Activity
package uk.co.tbw.sip.calling;
import android.app.Dialog;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.sip.SipAudioCall;
import android.net.sip.SipException;
import android.net.sip.SipManager;
import android.net.sip.SipProfile;
import android.net.sip.SipRegistrationListener;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.c77.androidstreamingclient.lib.rtp.RtpMediaDecoder;
import java.text.ParseException;
import uk.co.tbw.R;
import uk.co.tbw.utils.TBWLogger;
public class Call extends AppCompatActivity {
public static final int REQUEST_PERMISSION_CODE = 1567;
public String mSipAddress = null;
public SipManager mManager = null;
public SipProfile mProfile = null;
public SipAudioCall mAudioCall = null;
public IncomingCallReceiver mCallReceiver;
private static final int CALL_ADDRESS = 1;
private static final int SET_AUTH_INFO = 2;
private static final int UPDATE_SETTINGS_DIALOG = 3;
private static final int HANG_UP = 4;
private RtpMediaDecoder rtpMediaDecoder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_call);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Button callBtn = (Button) findViewById(R.id.answer_btn);
Button closeBtn = (Button) findViewById(R.id.close_btn);
SurfaceView view = new SurfaceView(this);
rtpMediaDecoder = new RtpMediaDecoder(view);
rtpMediaDecoder.start();
callBtn.setOnClickListener(v -> {
EditText textField = (EditText) findViewById(R.id.userToCallEditText);
mSipAddress = textField.getText().toString();
initiateCall();
});
closeBtn.setOnClickListener(v -> {
if (mAudioCall != null) {
try {
mAudioCall.endCall();
TBWLogger.d("Call.java endCall");
} catch (SipException e) {
Log.d("WalkieTalkieActivity/onOptionsItemSelected",
"Error ending call.", e);
}
mAudioCall.close();
}
});
IntentFilter filter = new IntentFilter();
filter.addAction("android.SipDemo.INCOMING_CALL");
mCallReceiver = new IncomingCallReceiver();
this.registerReceiver(mCallReceiver, filter);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show();
}
#Override
protected void onStart() {
super.onStart();
initializeManager();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mAudioCall != null) {
mAudioCall.close();
}
closeLocalProfile();
if (mCallReceiver != null) {
this.unregisterReceiver(mCallReceiver);
}
rtpMediaDecoder.release();
}
#Override
protected void onStop() {
rtpMediaDecoder.release();
super.onStop();
}
private void closeLocalProfile() {
if (mManager == null) {
return;
}
try {
if (mProfile != null) {
mManager.close(mProfile.getUriString());
}
} catch (SipException e) {
Log.d("CallActivity/onDestroy", "Failed to close local profile.", e);
}
}
private void initializeManager() {
TBWLogger.d("initializeManager()");
if (mManager == null) {
mManager = SipManager.newInstance(this);
}
initializeLocalProfile();
}
private void initializeLocalProfile() {
TBWLogger.d("initializeLocalProfile");
if (mManager == null) {
return;
}
if (mProfile != null) {
closeLocalProfile();
}
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
String username = preferences.getString("namePref", "");
String domain = preferences.getString("domainPref", "");
String password = preferences.getString("passPref", "");
if (username.length() == 0 || domain.length() == 0 || password.length() == 0) { //|| password.length() == 0
showDialog(UPDATE_SETTINGS_DIALOG);
return;
}
try {
TBWLogger.d("Building new sipProfile");
SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
mProfile = builder.build();
Intent intent = new Intent();
intent.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA);
mManager.open(mProfile, pendingIntent, new SipRegistrationListener() {
#Override
public void onRegistering(String localProfileUri) {
TBWLogger.d("onRegistering");
updateStatus("Registering with SIP Server...");
}
#Override
public void onRegistrationDone(String localProfileUri, long expiryTime) {
TBWLogger.d("onRegistrationDone");
updateStatus("Ready");
}
#Override
public void onRegistrationFailed(String localProfileUri, int errorCode, String errorMessage) {
TBWLogger.d("onRegistrationFailed:" + " errorMessage:" + errorMessage + " errorCode:" + errorCode
+ " localProfile:" + localProfileUri);
updateStatus("Registration failed. Please check settings.");
}
});
} catch (ParseException e) {
updateStatus("Connection Error.");
e.printStackTrace();
} catch (SipException e) {
updateStatus("Connection Error.");
e.printStackTrace();
}
}
public void initiateCall() {
updateStatus(mSipAddress);
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
#Override
public void onReadyToCall(SipAudioCall call) {
TBWLogger.d("Call.java onReadyToCall: " + call);
}
#Override
public void onRingingBack(SipAudioCall call) {
TBWLogger.d("Call.java onRingingBack: " + call);
}
#Override
public void onCallBusy(SipAudioCall call) {
TBWLogger.d("Call.java onCallBusy: " + call);
}
#Override
public void onCallHeld(SipAudioCall call) {
TBWLogger.d("Call.java onCallHeld: " + call);
}
#Override
public void onChanged(SipAudioCall call) {
TBWLogger.d("Call.java onChanged: " + call);
}
#Override
public void onCallEstablished(SipAudioCall call) {
// AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
// audio.setMode(AudioManager.MODE_IN_COMMUNICATION);
// AudioGroup audioGroup = new AudioGroup();
// audioGroup.setMode(AudioGroup.MODE_NORMAL);
// AudioStream audioStream = null;
// try {
// audioStream = new AudioStream(InetAddress.getByAddress(IncomingCallReceiver.getLocalIPAddress()));
// } catch (SocketException e) {
// e.printStackTrace();
// } catch (UnknownHostException e) {
// e.printStackTrace();
// }
// audioStream.setCodec(AudioCodec.PCMU);
// audioStream.setMode(RtpStream.MODE_NORMAL);
// //set receiver(vlc player) machine ip address(please update with your machine ip)
// try {
// audioStream.associate(InetAddress.getByAddress(new byte[] {(byte)192, (byte)168, (byte)1, (byte)19 }), 22222);
// } catch (UnknownHostException e) {
// e.printStackTrace();
// }
// audioStream.join(audioGroup);
//call.setSpeakerMode(true);
call.startAudio();
// if (call.isMuted()) {
// call.toggleMute();
// }
updateStatus(call);
mAudioCall.startAudio();
//mAudioCall.setSpeakerMode(true);
TBWLogger.d("Call.java onCallEstablished(): ");
}
#Override
public void onRinging(SipAudioCall call, SipProfile caller) {
Toast.makeText(Call.this, "Calling", Toast.LENGTH_LONG).show();
try {
call.answerCall(30);
} catch (SipException e) {
e.printStackTrace();
}
TBWLogger.d("Call.java onRinging(): ");
}
#Override
public void onCalling(SipAudioCall call) {
Toast.makeText(Call.this, "Calling", Toast.LENGTH_LONG).show();
TBWLogger.d("Call.java onRinging(): ");
}
#Override
public void onCallEnded(SipAudioCall call) {
updateStatus("Ready");
TBWLogger.d("Call.java onCallEnded(): ");
}
#Override
public void onError(SipAudioCall call, int errorCode, String errorMessage) {
TBWLogger.d("Call.java onError: errorCode: " + errorCode + "; errorMessage: " + errorMessage);
updateStatus("Call.java onError: errorCode: " + errorCode + "; errorMessage: " + errorMessage);
}
};
mAudioCall = mManager.makeAudioCall(mProfile.getUriString(), mSipAddress, listener, 30);
} catch (SipException e) {
Log.i("InitiateCall", "Error when trying to close manager", e);
if (mProfile != null) {
try {
mManager.close(mProfile.getUriString());
} catch (SipException e1) {
Log.i("InitiateCall", "Error when trying to close manager", e1);
e1.printStackTrace();
}
}
if (mAudioCall != null) {
mAudioCall.close();
}
}
}
public void updateStatus(String s) {
this.runOnUiThread(() -> {
TextView label = (TextView) findViewById(R.id.label);
label.setText(s);
});
}
public void updateStatus(SipAudioCall s) {
String userName = s.getPeerProfile().getDisplayName();
if (userName == null) {
userName = s.getPeerProfile().getUserName();
}
updateStatus(userName + "#" + s.getPeerProfile().getSipDomain());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, SET_AUTH_INFO, 0, "Edit your SIP Info");
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case SET_AUTH_INFO:
updatePreferences();
break;
}
return true;
}
//TODO: check the break statements
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case CALL_ADDRESS:
LayoutInflater factory = LayoutInflater.from(this);
final View textBoxView = factory.inflate(R.layout.call_address_dialog, null);
return new AlertDialog.Builder(this)
.setTitle("Call Someone")
.setView(textBoxView)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
EditText textField = (EditText) (textBoxView.findViewById(R.id.call_address_edit));
mSipAddress = textField.getText().toString();
initiateCall();
}
})
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
}).create();
case UPDATE_SETTINGS_DIALOG:
return new AlertDialog.Builder(this)
.setMessage("Please update your SIP Account Settings.")
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
updatePreferences();
}
})
.setNegativeButton(
android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Noop.
}
})
.create();
}
return null;
}
private void updatePreferences() {
Intent settingsActivity = new Intent(getBaseContext(), SipSetting.class);
startActivity(settingsActivity);
}
}
`
Manifest`
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.USE_SIP" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CONFIGURE_SIP" />
<uses-permission android:name="android.software.sip" android:required="true" />
<uses-permission android:name="android.software.sip.voip" android:required="true" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CONFIGURE_SIP" />
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.hardware.wifi" android:required="true"/>
<uses-permission android:name="android.software.sip.voip" android:required="true" />
<uses-permission android:name="android.hardware.microphone" android:required="true"/>
<uses-permission android:name="android.hardware.sip.voip" android:required="true" />
<uses-permission android:name="android.hardware.telephony" android:required="false" />
<application ...
<receiver android:name=".sip.calling.IncomingCallReceiver" android:label="Call Receiver"/>
<activity
android:name=".sip.calling.Call"
android:configChanges="orientation|keyboardHidden"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="uk.co.tbw.MainActivity"/>
</activity>
</application>
`
What library are you using for the SIP signaling?
In some libraries you have to assign the Microphone and the Speaker to the call when it is estabilished.
Related
I have this code of main activity, I'm trying to make FTP server app but the problem which I'm getting is that when I click on Change directory button it shows internal storage path and I want both, internal and SD card storage. So please somebody help me solve this issue.
This is the code of main activity:
package com.project.shrey.ftptrial;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;
import net.rdrei.android.dirchooser.DirectoryChooserActivity;
import net.rdrei.android.dirchooser.DirectoryChooserConfig;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.FtpReply;
import org.apache.ftpserver.ftplet.FtpRequest;
import org.apache.ftpserver.ftplet.FtpSession;
import org.apache.ftpserver.ftplet.Ftplet;
import org.apache.ftpserver.ftplet.FtpletContext;
import org.apache.ftpserver.ftplet.FtpletResult;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.apache.ftpserver.usermanager.SaltedPasswordEncryptor;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.ftpserver.usermanager.impl.WritePermission;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
Window window ;
TextView mAddrReg, mAddriOS, mPrompt, mPasswdDisp, mUserDisp, mDirAddress;
EditText mUser, mPasswd;
Switch mTogglePass;
LinearLayout mAddr1, mAddr2;
TextInputLayout mUserParent, mPasswdParent;
Button mDirChooser;
static String pass;
final int MY_PERMISSIONS_REQUEST = 2203;
final int REQUEST_DIRECTORY = 2108;
FtpServerFactory serverFactory = new FtpServerFactory();
ListenerFactory factory = new ListenerFactory();
PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
FtpServer finalServer;
Toolbar toolbar;
boolean justStarted = true;
#SuppressLint("AuthLeak")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(Build.VERSION.SDK_INT>=21){
window =this.getWindow();
window.setStatusBarColor(this.getResources().getColor(R.color.colordarkblue));
}
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.dialog_message).setTitle(R.string.dialog_title);
builder.setPositiveButton("OK", (dialog, id) -> {
dialog.dismiss();
justStarted = false;
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST);
});
builder.show();
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST);
}
}
mTogglePass = findViewById(R.id.togglePass);
mTogglePass.setEnabled(false);
mTogglePass.setChecked(false);
mUserParent = findViewById(R.id.userParent);
mUser = findViewById(R.id.user);
mUserDisp = findViewById(R.id.userDisp);
mPasswd = findViewById(R.id.passwd);
mPasswdDisp = findViewById(R.id.passwdDisp);
mPasswdParent = findViewById(R.id.passwdParent);
mPrompt = findViewById(R.id.prompt);
mAddrReg = findViewById(R.id.addrReg);
mAddr2 = findViewById(R.id.addr2);
mAddrReg.setText(String.format("ftp://%s:2121", wifiIpAddress(this)));
mAddriOS = findViewById(R.id.addriOS);
mAddr1 = findViewById(R.id.addr1);
mAddriOS.setText(String.format("ftp://ftp:ftp#%s:2121", wifiIpAddress(this)));
mDirAddress = findViewById(R.id.dirAddress);
mDirChooser= findViewById(R.id.dirChooser);
mDirChooser.setOnClickListener(view -> {
final Intent chooserIntent = new Intent(this, DirectoryChooserActivity.class);
final DirectoryChooserConfig config = DirectoryChooserConfig.builder()
.newDirectoryName("New Folder")
.allowNewDirectoryNameModification(true)
.build();
chooserIntent.putExtra(DirectoryChooserActivity.EXTRA_CONFIG, config);
startActivityForResult(chooserIntent, REQUEST_DIRECTORY);
});
finalServer = serverFactory.createServer();
toolbar.setOnClickListener(view -> {
try {
if (checkWifiOnAndConnected(this) || wifiHotspotEnabled(this)) {
MainActivity.this.serverControl();
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.dialog_wifi_message).setTitle(R.string.dialog_wifi_title);
builder.setPositiveButton("OK", (dialog, id) -> dialog.dismiss());
builder.show();
}
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
});
mTogglePass.setOnCheckedChangeListener((compoundButton, b) -> {
if (b) {
mPasswdDisp.setText(String.format("Password: %s", pass));
} else {
StringBuilder strB = new StringBuilder("Password: ");
for (int i=0; i < pass.length(); i++) {
strB.append('*');
}
mPasswdDisp.setText(strB.toString());
}
});
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST: {
if (grantResults.length <= 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.dialog_message_exit).setTitle(R.string.dialog_title);
builder.setPositiveButton("OK", (dialog, id) -> {
dialog.dismiss();
finish();
});
builder.show();
}
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_DIRECTORY) {
if (resultCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) {
mDirAddress.setText(data.getStringExtra(DirectoryChooserActivity.RESULT_SELECTED_DIR));
}
}
}
#Override
protected void onDestroy() {
try {
finalServer.stop();
} catch (Exception e) {
Log.e("Server Close Error", e.getCause().toString());
}
super.onDestroy();
}
private void setupStart(String username, String password, String subLoc) throws FileNotFoundException {
factory.setPort(2121);
serverFactory.addListener("default", factory.createListener());
File files = new File(Environment.getExternalStorageDirectory().getPath() + "/users.properties");
if (!files.exists()) {
try {
files.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
userManagerFactory.setFile(files);
userManagerFactory.setPasswordEncryptor(new SaltedPasswordEncryptor());
UserManager um = userManagerFactory.createUserManager();
BaseUser user = new BaseUser();
user.setName(username);
user.setPassword(password);
String home = Environment.getExternalStorageDirectory().getPath() + "/" + subLoc;
user.setHomeDirectory(home);
List<Authority> auths = new ArrayList<>();
Authority auth = new WritePermission();
auths.add(auth);
user.setAuthorities(auths);
try {
um.save(user);
} catch (FtpException e1) {
e1.printStackTrace();
}
serverFactory.setUserManager(um);
Map<String, Ftplet> m = new HashMap<>();
m.put("miaFtplet", new Ftplet()
{
#Override
public void init(FtpletContext ftpletContext) throws FtpException {
}
#Override
public void destroy() {
}
#Override
public FtpletResult beforeCommand(FtpSession session, FtpRequest request) throws FtpException, IOException
{
return FtpletResult.DEFAULT;
}
#Override
public FtpletResult afterCommand(FtpSession session, FtpRequest request, FtpReply reply) throws FtpException, IOException
{
return FtpletResult.DEFAULT;
}
#Override
public FtpletResult onConnect(FtpSession session) throws FtpException, IOException
{
return FtpletResult.DEFAULT;
}
#Override
public FtpletResult onDisconnect(FtpSession session) throws FtpException, IOException
{
return FtpletResult.DEFAULT;
}
});
serverFactory.setFtplets(m);
}
private String wifiIpAddress(Context context) {
try {
if (wifiHotspotEnabled(context)) {
return "192.168.43.1";
}
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return Utils.getIPAddress(true);
}
private boolean wifiHotspotEnabled(Context context) throws InvocationTargetException, IllegalAccessException {
WifiManager manager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
Method method = null;
try {
method = manager.getClass().getDeclaredMethod("isWifiApEnabled");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
method.setAccessible(true); //in the case of visibility change in future APIs
return (Boolean) method.invoke(manager);
}
private boolean checkWifiOnAndConnected(Context context) {
WifiManager wifiMgr = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
assert wifiMgr != null;
if (wifiMgr.isWifiEnabled()) { // Wi-Fi adapter is ON
WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
return wifiInfo.getNetworkId() != -1;
}
else {
return false; // Wi-Fi adapter is OFF
}
}
#Override
public void onBackPressed() {
finalServer.stop();
findViewById(R.id.toolbar).setEnabled(false);
toolbar.setBackgroundColor(ResourcesCompat.getColor(getResources(), R.color.colorbluelight, null));
super.onBackPressed();
}
void serverControl() {
if (finalServer.isStopped()) {
mUser.setEnabled(false);
mPasswd.setEnabled(false);
mDirChooser.setEnabled(false);
String user = mUser.getText().toString();
String passwd = mPasswd.getText().toString();
if (user.isEmpty()) {
user = "ftp";
}
if (passwd.isEmpty()) {
passwd = "ftp";
}
String subLoc = mDirAddress.getText().toString().substring(20);
pass = passwd;
StringBuilder strB = new StringBuilder("Password: ");
for (int i=0; i < pass.length(); i++) {
strB.append('*');
}
mPasswdDisp.setText(strB.toString());
mUserDisp.setText(String.format("Username: %s", user));
mUserDisp.setVisibility(View.VISIBLE);
mUserParent.setVisibility(View.INVISIBLE);
mPasswdParent.setVisibility(View.INVISIBLE);
mPasswdDisp.setVisibility(View.VISIBLE);
try {
setupStart(user, passwd, subLoc);
} catch (FileNotFoundException fnfe) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.dialog_message_error).setTitle(R.string.dialog_title);
builder.setPositiveButton("OK", (dialog, id) -> {
dialog.dismiss();
justStarted = false;
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST);
});
builder.show();
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST);
}
}
try {
finalServer.start();
mAddrReg.setText(String.format("ftp://%s:2121", wifiIpAddress(this)));
mAddriOS.setText(String.format("ftp://%s:%s#%s:2121", user, passwd, wifiIpAddress(this)));
} catch (FtpException e) {
e.printStackTrace();
}
toolbar.setBackgroundColor(ResourcesCompat.getColor(getResources(), R.color.colordarkblue, null));
mPrompt.setVisibility(View.VISIBLE);
mAddr1.setVisibility(View.VISIBLE);
mAddr2.setVisibility(View.VISIBLE);
mTogglePass.setEnabled(true);
} else if (finalServer.isSuspended()) {
finalServer.resume();
toolbar.setBackgroundColor(ResourcesCompat.getColor(getResources(), R.color.colordarkblue, null));
mPrompt.setVisibility(View.VISIBLE);
mAddr1.setVisibility(View.VISIBLE);
mAddr2.setVisibility(View.VISIBLE);
} else {
finalServer.suspend();
toolbar.setBackgroundColor(ResourcesCompat.getColor(getResources(), R.color.colorbluelight, null));
mPrompt.setVisibility(View.INVISIBLE);
mAddr1.setVisibility(View.INVISIBLE);
mAddr2.setVisibility(View.INVISIBLE);
}
}
}
I'm using react native v0.49 and installed react-native-nfc-manager .
when I try to use nfc I get the error
Attempt to get length of null array
so I checked on the nfc folder and I find the issue into the plugin installation
#ReactMethod
public void start(Callback callback) {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
if (nfcAdapter != null) {
Log.d(LOG_TAG, "start");
callback.invoke(null);
} else {
Log.d(LOG_TAG, "not support in this device");
callback.invoke("no nfc support");
}
}
as you can see when the nfcAdapter is not null it
callback.invoke(null)
so here is the problem, so I tried to change it to
callback.invoke(LOG_TAG)
and it's not show the error but I don't get any nfc tag, is show me undefined but not error.
what can i do?
here is all the NfcManager.java file
package community.revteltech.nfc;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Base64;
import android.util.Log;
import android.provider.Settings;
import com.facebook.react.bridge.*;
import com.facebook.react.modules.core.RCTNativeAppEventEmitter;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.net.Uri;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcEvent;
import android.nfc.Tag;
import android.nfc.TagLostException;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.os.Parcelable;
import org.json.JSONObject;
import org.json.JSONException;
import java.util.*;
import static android.app.Activity.RESULT_OK;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread;
class NfcManager extends ReactContextBaseJavaModule implements ActivityEventListener, LifecycleEventListener {
private static final String LOG_TAG = "NfcManager";
private final List<IntentFilter> intentFilters = new ArrayList<IntentFilter>();
private final ArrayList<String[]> techLists = new ArrayList<String[]>();
private Context context;
private ReactApplicationContext reactContext;
private Boolean isForegroundEnabled = false;
private Boolean isResumed = false;
public NfcManager(ReactApplicationContext reactContext) {
super(reactContext);
context = reactContext;
this.reactContext = reactContext;
reactContext.addActivityEventListener(this);
reactContext.addLifecycleEventListener(this);
Log.d(LOG_TAG, "NfcManager created");
}
#Override
public String getName() {
return "NfcManager";
}
#ReactMethod
public void start(Callback callback) {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
if (nfcAdapter != null) {
Log.d(LOG_TAG, "start");
callback.invoke(null);
} else {
Log.d(LOG_TAG, "not support in this device");
callback.invoke("no nfc support");
}
}
#ReactMethod
public void isEnabled(Callback callback) {
Log.d(LOG_TAG, "isEnabled");
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
if (nfcAdapter != null) {
callback.invoke(null, nfcAdapter.isEnabled());
} else {
callback.invoke(null, false);
}
}
#ReactMethod
public void goToNfcSetting(Callback callback) {
Log.d(LOG_TAG, "goToNfcSetting");
Activity currentActivity = getCurrentActivity();
currentActivity.startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
callback.invoke();
}
#ReactMethod
public void getLaunchTagEvent(Callback callback) {
Activity currentActivity = getCurrentActivity();
Intent launchIntent = currentActivity.getIntent();
WritableMap nfcTag = parseNfcIntent(launchIntent);
callback.invoke(null, nfcTag);
}
#ReactMethod
private void registerTagEvent(Callback callback) {
Log.d(LOG_TAG, "registerTag");
isForegroundEnabled = true;
// capture all mime-based dispatch NDEF
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
ndef.addDataType("*/*");
} catch (MalformedMimeTypeException e) {
throw new RuntimeException("fail", e);
}
intentFilters.add(ndef);
// capture all rest NDEF, such as uri-based
intentFilters.add(new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED));
techLists.add(new String[]{Ndef.class.getName()});
// for those without NDEF, get them as tags
intentFilters.add(new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED));
if (isResumed) {
enableDisableForegroundDispatch(true);
}
callback.invoke();
}
#ReactMethod
private void unregisterTagEvent(Callback callback) {
Log.d(LOG_TAG, "registerTag");
isForegroundEnabled = false;
intentFilters.clear();
if (isResumed) {
enableDisableForegroundDispatch(false);
}
callback.invoke();
}
#Override
public void onHostResume() {
Log.d(LOG_TAG, "onResume");
isResumed = true;
if (isForegroundEnabled) {
enableDisableForegroundDispatch(true);
}
}
#Override
public void onHostPause() {
Log.d(LOG_TAG, "onPause");
isResumed = false;
enableDisableForegroundDispatch(false);
}
#Override
public void onHostDestroy() {
Log.d(LOG_TAG, "onDestroy");
}
private void enableDisableForegroundDispatch(boolean enable) {
Log.i(LOG_TAG, "enableForegroundDispatch, enable = " + enable);
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
Activity currentActivity = getCurrentActivity();
if (nfcAdapter != null && !currentActivity.isFinishing()) {
try {
if (enable) {
nfcAdapter.enableForegroundDispatch(currentActivity, getPendingIntent(), getIntentFilters(), getTechLists());
} else {
nfcAdapter.disableForegroundDispatch(currentActivity);
}
} catch (IllegalStateException e) {
Log.w(LOG_TAG, "Illegal State Exception starting NFC. Assuming application is terminating.");
}
}
}
private PendingIntent getPendingIntent() {
Activity activity = getCurrentActivity();
Intent intent = new Intent(activity, activity.getClass());
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
return PendingIntent.getActivity(activity, 0, intent, 0);
}
private IntentFilter[] getIntentFilters() {
return intentFilters.toArray(new IntentFilter[intentFilters.size()]);
}
private String[][] getTechLists() {
return techLists.toArray(new String[0][0]);
}
private void sendEvent(String eventName,
#Nullable WritableMap params) {
getReactApplicationContext()
.getJSModule(RCTNativeAppEventEmitter.class)
.emit(eventName, params);
}
private void sendEventWithJson(String eventName,
JSONObject json) {
try {
WritableMap map = JsonConvert.jsonToReact(json);
sendEvent(eventName, map);
} catch (JSONException ex) {
Log.d(LOG_TAG, "fireNdefEvent fail: " + ex);
}
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(LOG_TAG, "onReceive " + intent);
}
};
#Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
Log.d(LOG_TAG, "onActivityResult");
}
#Override
public void onNewIntent(Intent intent) {
Log.d(LOG_TAG, "onNewIntent " + intent);
WritableMap nfcTag = parseNfcIntent(intent);
if (nfcTag != null) {
sendEvent("NfcManagerDiscoverTag", nfcTag);
}
}
private WritableMap parseNfcIntent(Intent intent) {
Log.d(LOG_TAG, "parseIntent " + intent);
String action = intent.getAction();
Log.d(LOG_TAG, "action " + action);
if (action == null) {
return null;
}
WritableMap parsed = null;
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
// Parcelable[] messages = intent.getParcelableArrayExtra((NfcAdapter.EXTRA_NDEF_MESSAGES));
if (action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) {
Ndef ndef = Ndef.get(tag);
Parcelable[] messages = intent.getParcelableArrayExtra((NfcAdapter.EXTRA_NDEF_MESSAGES));
parsed = ndef2React(ndef, messages);
} else if (action.equals(NfcAdapter.ACTION_TECH_DISCOVERED)) {
for (String tagTech : tag.getTechList()) {
Log.d(LOG_TAG, tagTech);
if (tagTech.equals(NdefFormatable.class.getName())) {
// fireNdefFormatableEvent(tag);
} else if (tagTech.equals(Ndef.class.getName())) { //
Ndef ndef = Ndef.get(tag);
parsed = ndef2React(ndef, new NdefMessage[] { ndef.getCachedNdefMessage() });
}
}
} else if (action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
parsed = tag2React(tag);
}
return parsed;
}
private WritableMap tag2React(Tag tag) {
try {
JSONObject json = Util.tagToJSON(tag);
return JsonConvert.jsonToReact(json);
} catch (JSONException ex) {
return null;
}
}
private WritableMap ndef2React(Ndef ndef, Parcelable[] messages) {
try {
JSONObject json = buildNdefJSON(ndef, messages);
return JsonConvert.jsonToReact(json);
} catch (JSONException ex) {
return null;
}
}
JSONObject buildNdefJSON(Ndef ndef, Parcelable[] messages) {
JSONObject json = Util.ndefToJSON(ndef);
// ndef is null for peer-to-peer
// ndef and messages are null for ndef format-able
if (ndef == null && messages != null) {
try {
if (messages.length > 0) {
NdefMessage message = (NdefMessage) messages[0];
json.put("ndefMessage", Util.messageToJSON(message));
// guessing type, would prefer a more definitive way to determine type
json.put("type", "NDEF Push Protocol");
}
if (messages.length > 1) {
Log.d(LOG_TAG, "Expected one ndefMessage but found " + messages.length);
}
} catch (JSONException e) {
// shouldn't happen
Log.e(Util.TAG, "Failed to convert ndefMessage into json", e);
}
}
return json;
}
}
my nfc component
import React, { Component } from 'react';
import {
View,
Text,
Button,
Platform,
TouchableOpacity,
Linking
} from 'react-native';
import NfcManager, {NdefParser} from 'react-native-nfc-manager';
class NFC extends Component {
constructor(props) {
super(props);
this.state = {
supported: true,
enabled: false,
tag: {},
}
}
componentDidMount() {
NfcManager.start({
onSessionClosedIOS: () => {
console.log('ios session closed');
}
})
.then(result => {
console.log('start OK', result);
})
.catch(error => {
console.warn('start fail', error);
this.setState({supported: false});
})
if (Platform.OS === 'android') {
NfcManager.getLaunchTagEvent()
.then(tag => {
console.log('launch tag', tag);
if (tag) {
this.setState({ tag });
}
})
.catch(err => {
console.log(err);
})
NfcManager.isEnabled()
.then(enabled => {
this.setState({ enabled });
})
.catch(err => {
console.log(err);
})
}
}
render() {
let { supported, enabled, tag } = this.state;
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>{`Is NFC supported ? ${supported}`}</Text>
<Text>{`Is NFC enabled (Android only)? ${enabled}`}</Text>
<TouchableOpacity style={{ marginTop: 20 }} onPress={this._startDetection}>
<Text style={{ color: 'blue' }}>Start Tag Detection</Text>
</TouchableOpacity>
<TouchableOpacity style={{ marginTop: 20 }} onPress={this._stopDetection}>
<Text style={{ color: 'red' }}>Stop Tag Detection</Text>
</TouchableOpacity>
<TouchableOpacity style={{ marginTop: 20 }} onPress={this._clearMessages}>
<Text>Clear</Text>
</TouchableOpacity>
<TouchableOpacity style={{ marginTop: 20 }} onPress={this._goToNfcSetting}>
<Text >Go to NFC setting</Text>
</TouchableOpacity>
<Text style={{ marginTop: 20 }}>{`Current tag JSON: ${JSON.stringify(tag)}`}</Text>
</View>
)
}
_onTagDiscovered = tag => {
console.log('Tag Discovered', tag);
this.setState({ tag });
let url = this._parseUri(tag);
if (url) {
Linking.openURL(url)
.catch(err => {
console.warn(err);
})
}
}
_startDetection = () => {
NfcManager.registerTagEvent(this._onTagDiscovered)
.then(result => {
console.log('registerTagEvent OK', result)
})
.catch(error => {
console.warn('registerTagEvent fail', error)
})
}
_stopDetection = () => {
NfcManager.unregisterTagEvent()
.then(result => {
console.log('unregisterTagEvent OK', result)
})
.catch(error => {
console.warn('unregisterTagEvent fail', error)
})
}
_clearMessages = () => {
this.setState({tag: null});
}
_goToNfcSetting = () => {
if (Platform.OS === 'android') {
NfcManager.goToNfcSetting()
.then(result => {
console.log('goToNfcSetting OK', result)
})
.catch(error => {
console.warn('goToNfcSetting fail', error)
})
}
}
_parseUri = (tag) => {
let result = NdefParser.parseUri(tag.ndefMessage[0]),
uri = result && result.uri;
if (uri) {
console.log('parseUri: ' + uri);
return uri;
}
return null;
}
}
export default NFC;
Be careful, NFC could not be available in all devices, so you have to check first:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null){
Toast.makeText(this, "NFC not available", Toast.LENGTH_SHORT).show();
return;
}else{
Toast.makeText(this, "NFC is avalable", Toast.LENGTH_SHORT).show();
}
....
....
}
If NFC is not present that will be the reason to get the error message:
Attempt to get length of null array on NfcManager.start()
I have write some code for receiving data from Bluetooth module (HC-05), I want to read string '#900~' from Arduino, but I get nothing in response. I have made a connection with module, but nothing more. I need only reading on Android. It is probably easy task but I cannot get across :/. What am I doing wrong? it Below is my code:
package nichten.pneumobil;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
public class MainApplication extends AppCompatActivity {
boolean doubleBackToExitPressedOnce = false;
private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
static BluetoothSocket mmSocket;
static BluetoothDevice mmDevice;
static OutputStream mmOutputStream;
static InputStream mmInputStream;
private static final UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
private String BTdevice = "POJAZD1";
private boolean polaczenie = false;
Handler bluetoothIn;
final int handlerState = 0;
private ConnectedThread mConnectedThread;
private StringBuilder recDataString = new StringBuilder();
private Button btnModuleConnect;
private TextView txtModuleConnect;
private TextView txtTest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_application);
btnModuleConnect = (Button) findViewById(R.id.btnModuleConnect);
txtModuleConnect = (TextView) findViewById(R.id.txtModuleConnect);
txtTest = (TextView) findViewById(R.id.txtTest);
if (!mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.enable();
}
btnModuleConnect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
if (connectWithModule())
txtModuleConnect.setText("Connection status: Connected");
else
txtModuleConnect.setText("Connection status: Module not found");
} catch(IOException e){
e.printStackTrace();
}
}
});
bluetoothIn = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == handlerState) {
String readMessage = (String) msg.obj;
recDataString.append(readMessage);
int endOfLineIndex = recDataString.indexOf("~");
if (endOfLineIndex > 0) {
String dataInPrint = recDataString.substring(0, endOfLineIndex);
int dataLength = dataInPrint.length();
if (recDataString.charAt(0) == '#')
{
txtTest.setText(recDataString);
}
recDataString.delete(0, recDataString.length());
dataInPrint = " ";
}
}
}
};
}
#Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
disconnectWithModule();
mBluetoothAdapter.disable();
finish();
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
}
public boolean connectWithModule() throws IOException {
if(polaczenie){
try {
mmSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
mmDevice = null;
mmSocket = null;
mBluetoothAdapter = null;
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
if(device.getName().equals(BTdevice)){
mmDevice = device;
break;
}
}
}
if (mmDevice != null) {
try {
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
Toast.makeText(getApplicationContext(), "Połączono!", Toast.LENGTH_SHORT).show();
polaczenie = true;
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
return true;
} catch (Exception e2) {
Toast.makeText(getApplicationContext(),"Nie udało się połaczyć.", Toast.LENGTH_SHORT).show();
mmDevice = null;
try {
mmSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
mmSocket = null;
}
}
else if (mmDevice == null){
Toast.makeText(getApplicationContext(), "Nie ma sparowanych urządzeń.", Toast.LENGTH_SHORT).show();
polaczenie = false;
}
return false;
}
public void disconnectWithModule(){
if (polaczenie) {
try {
mmSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class ConnectedThread extends Thread{
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[256];
int bytes;
while (true) {
try {
bytes = mmInStream.read(buffer);
String readMessage = new String(buffer, 0, bytes);
bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
break;
}
}
}
//write method
public void write(String input) {
byte[] msgBuffer = input.getBytes();
try {
mmOutStream.write(msgBuffer);
} catch (IOException e) {
Toast.makeText(getBaseContext(), "Connection Failure", Toast.LENGTH_LONG).show();
finish();
}
}
}
}
I am a beginner in Android (only 2 days with it :P), but I have no idea what to do. I also include my AndroidManifest, my other Activity, maybe it would help to find out what is wrong:
package nichten.pneumobil;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnNextScreen = (Button) findViewById(R.id.btnNextScreen);
btnNextScreen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent nextScreen = new Intent(getApplicationContext(), MainApplication.class);
startActivity(nextScreen);
}
});
}
}
And manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="nichten.pneumobil">
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainApplication"
android:screenOrientation="landscape">
</activity>
</application>
</manifest>
I am using csipsimple code and customised it to show brandname by getting json value from webservice . I am using SharedPreferences to store value .
Once the application is force closed , or device restart SharedPreferences are lost . I am using commit and clear but still the values are null .
BasePrefsWizard is the class responsible for pulling web data and DialerFragment is the other class i am calling the BrandName ( it is SavedBrand/ brand in code)
package com.mydial.wizards;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.preference.EditTextPreference;
import android.util.Base64;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.mydial.api.SipManager;
import com.mydial.api.SipProfile;
import com.mydial.db.DBProvider;
import com.mydial.models.Filter;
import com.mydial.ui.SipHome;
import com.mydial.ui.dialpad.DialerFragment;
import com.mydial.ui.filters.AccountFilters;
import com.mydial.ui.prefs.GenericPrefs;
import com.mydial.utils.AccountListUtils;
import com.mydial.utils.Log;
import com.mydial.utils.PreferencesProviderWrapper;
import com.mydial.utils.PreferencesWrapper;
import com.mydial.utils.AccountListUtils.AccountStatusDisplay;
import com.mydial.utils.animation.ActivitySwitcher;
import com.mydial.wizards.WizardUtils.WizardInfo;
import com.mydial.wizards.impl.Advanced;
import com.worldfone.R;
#SuppressLint("NewApi") public class BasePrefsWizard extends GenericPrefs {
public static final int SAVE_MENU = Menu.FIRST + 1;
public static final int TRANSFORM_MENU = Menu.FIRST + 2;
public static final int FILTERS_MENU = Menu.FIRST + 3;
public static final int DELETE_MENU = Menu.FIRST + 4;
private PreferencesProviderWrapper prefProviderWrapper;
private static final String THIS_FILE = "Base Prefs wizard";
protected SipProfile account = null;
private Button saveButton,cancel;
private String wizardId = "";
private WizardIface wizard = null;
private BroadcastReceiver mReceiver;
IntentFilter intentFilter;
public static final String myData = "mySharedPreferences";
public static String bal = null;
public static String sip = null;
public static String header = null;
public static String date = null;
public static String savedBal="";
public static String savedSip="";
public static String savedBrand="";
public static String webArray[] =new String[6];
#Override
protected void onCreate(Bundle savedInstanceState)
{
// Get back the concerned account and if any set the current (if not a
// new account is created)
Intent intent = getIntent();
long accountId = 1;
//intent.getLongExtra(SipProfile.FIELD_ID, SipProfile.INVALID_ID);
// TODO : ensure this is not null...
// setWizardId(intent.getStringExtra(SipProfile.FIELD_WIZARD));
setWizardId();
account = SipProfile.getProfileFromDbId(this, accountId, DBProvider.ACCOUNT_FULL_PROJECTION);
super.onCreate(savedInstanceState);
prefProviderWrapper = new PreferencesProviderWrapper(this);
// Bind buttons to their actions
cancel = (Button) findViewById(R.id.cancel_bt);
//cancel.setEnabled(false);
cancel.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
isOnline();
//saveAndFinish();
}
});
saveButton = (Button) findViewById(R.id.save_bt);
//saveButton.setEnabled(false);
saveButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
//setResult(RESULT_CANCELED, getIntent());
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
finish();
System.exit(0);
}
});
wizard.fillLayout(account);
loadValue();
}
public void isOnline()
{
ConnectivityManager connMgr = (ConnectivityManager) this
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected())
{
try
{
String webAccessNumberLink="http://myweblink.info/test/code.php?user=1234";
new webAccessNumber().execute(webAccessNumberLink);
}
catch(Exception e)
{
// System.out.println("exception in basepreference "+e);
}
}
else
{
// display error
showNetworkAlert();
}
}
void showNetworkAlert()
{
new AlertDialog.Builder(this)
.setTitle("Alert")
.setMessage(
"Please make sure you have Network Enabled")
.setNeutralButton("OK", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
/*Intent siphome = new Intent(getApplicationContext(),SipHome.class);
startActivity(siphome);*/
}
}).show();
}
public void saveArray(String[] arrayOfweb)
{
int mode = Context.MODE_PRIVATE;
SharedPreferences mySharedPreferences =this.getSharedPreferences(myData,
mode);
SharedPreferences.Editor editor = mySharedPreferences.edit();
String f1 = arrayOfweb[0];
String f2 = arrayOfweb[1];
String f3 = arrayOfweb[2];
String f4 = arrayOfweb[3];
for(int i=0;i<arrayOfweb.length;i++)
{
}
//byMe added below to make preferences persistant
editor.clear();
editor.putString("balance",f1);
editor.putString("sipp",f2);
editor.putString("brand",f3);
editor.putString("prfx",f4);
editor.commit();
loadValue();
}
private void loadValue()
{
int mode = Context.MODE_PRIVATE;
SharedPreferences mySharedPreferences = this.getSharedPreferences(myData,
mode);
savedBal= mySharedPreferences.getString("balance", "");
savedSip = mySharedPreferences.getString("sipp", "");
savedBrand = mySharedPreferences.getString("barnd", "");
}
private boolean isResumed = false;
#Override
protected void onResume()
{
super.onResume();
isResumed = true;
updateDescriptions();
updateValidation();
//byMe
}
#Override
protected void onPause()
{
super.onPause();
isResumed = false;
//this.unregisterReceiver(this.mReceiver);
}
private boolean setWizardId()
{
try {
wizard=Advanced.class.newInstance();
// wizard = (WizardIface) wizardInfo.classObject.newInstance();
} catch (IllegalAccessException e) {
Log.e(THIS_FILE, "Can't access wizard class", e);
/*if (!wizardId.equals(WizardUtils.EXPERT_WIZARD_TAG)) {
return setWizardId(WizardUtils.EXPERT_WIZARD_TAG);
}*/
return false;
} catch (InstantiationException e) {
Log.e(THIS_FILE, "Can't access wizard class", e);
/* if (!wizardId.equals(WizardUtils.EXPERT_WIZARD_TAG)) {
return setWizardId(WizardUtils.EXPERT_WIZARD_TAG);
}
*/ return false;
}
//wizardId = wId;
wizard.setParent(this);
if(getSupportActionBar() != null) {
getSupportActionBar().setIcon(WizardUtils.getWizardIconRes(wizardId));
}
return true;
}
private boolean setWizardId(String wId) {
if (wizardId == null) {
return setWizardId(WizardUtils.EXPERT_WIZARD_TAG);
}
WizardInfo wizardInfo = WizardUtils.getWizardClass(wId);
if (wizardInfo == null) {
if (!wizardId.equals(WizardUtils.EXPERT_WIZARD_TAG)) {
return setWizardId(WizardUtils.EXPERT_WIZARD_TAG);
}
return false;
}
try {
wizard = (WizardIface) wizardInfo.classObject.newInstance();
} catch (IllegalAccessException e) {
Log.e(THIS_FILE, "Can't access wizard class", e);
if (!wizardId.equals(WizardUtils.EXPERT_WIZARD_TAG)) {
return setWizardId(WizardUtils.EXPERT_WIZARD_TAG);
}
return false;
} catch (InstantiationException e) {
Log.e(THIS_FILE, "Can't access wizard class", e);
if (!wizardId.equals(WizardUtils.EXPERT_WIZARD_TAG)) {
return setWizardId(WizardUtils.EXPERT_WIZARD_TAG);
}
return false;
}
wizardId = wId;
wizard.setParent(this);
if(getSupportActionBar() != null) {
getSupportActionBar().setIcon(WizardUtils.getWizardIconRes(wizardId));
}
return true;
}
#Override
protected void beforeBuildPrefs() {
// Use our custom wizard view
setContentView(R.layout.wizard_prefs_base);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(isResumed) {
updateDescriptions();
updateValidation();
}
}
private void resolveStatus()
{
AccountStatusDisplay accountStatusDisplay = AccountListUtils
.getAccountDisplay(this, 1);
//status.setTextColor(accountStatusDisplay.statusColor);
//status.setText(accountStatusDisplay.statusLabel);
}
/**
* Update validation state of the current activity.
* It will check if wizard can be saved and if so
* will enable button
*/
public void updateValidation()
{
cancel.setEnabled(wizard.canSave());
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onPrepareOptionsMenu(Menu menu)
{
// menu.findItem(SAVE_MENU).setVisible(wizard.canSave());
return super.onPrepareOptionsMenu(menu);
}
private static final int CHOOSE_WIZARD = 0;
private static final int MODIFY_FILTERS = CHOOSE_WIZARD + 1;
private static final int FINAL_ACTIVITY_CODE = MODIFY_FILTERS;
private int currentActivityCode = FINAL_ACTIVITY_CODE;
public int getFreeSubActivityCode()
{
currentActivityCode ++;
return currentActivityCode;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
return super.onOptionsItemSelected(item);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
}
/**
* Save account and end the activity
*/
public void saveAndFinish()
{
//this.registerReceiver(mReceiver, intentFilter);
saveAccount();
Intent intent = getIntent();
setResult(RESULT_OK, intent);
Intent it = new Intent(this,SipHome.class);
startActivity(it);
finish();
}
void updateStatus()
{
AccountStatusDisplay accountStatusDisplay = AccountListUtils
.getAccountDisplay(this, account.id);
}
/*
* Save the account with current wizard id
*/
private void saveAccount() {
saveAccount(wizardId);
}
#Override
protected void onDestroy() {
//byMe
super.onDestroy();
getSharedPreferences(WIZARD_PREF_NAME, MODE_PRIVATE).edit().clear().commit();
saveArray(webArray);
}
/**
* Save the account with given wizard id
* #param wizardId the wizard to use for account entry
*/
private void saveAccount(String wizardId) {
boolean needRestart = false;
PreferencesWrapper prefs = new PreferencesWrapper(getApplicationContext());
account = wizard.buildAccount(account);
account.wizard = wizardId;
if (account.id == SipProfile.INVALID_ID) {
// This account does not exists yet
prefs.startEditing();
wizard.setDefaultParams(prefs);
prefs.endEditing();
Uri uri = getContentResolver().insert(SipProfile.ACCOUNT_URI, account.getDbContentValues());
// After insert, add filters for this wizard
account.id = ContentUris.parseId(uri);
List<Filter> filters = wizard.getDefaultFilters(account);
if (filters != null) {
for (Filter filter : filters) {
// Ensure the correct id if not done by the wizard
filter.account = (int) account.id;
getContentResolver().insert(SipManager.FILTER_URI, filter.getDbContentValues());
}
}
// Check if we have to restart
needRestart = wizard.needRestart();
} else {
// TODO : should not be done there but if not we should add an
// option to re-apply default params
prefs.startEditing();
wizard.setDefaultParams(prefs);
prefs.endEditing();
getContentResolver().update(ContentUris.withAppendedId(SipProfile.ACCOUNT_ID_URI_BASE, account.id), account.getDbContentValues(), null, null);
}
// Mainly if global preferences were changed, we have to restart sip stack
if (needRestart) {
Intent intent = new Intent(SipManager.ACTION_SIP_REQUEST_RESTART);
sendBroadcast(intent);
}
}
#Override
protected int getXmlPreferences() {
return wizard.getBasePreferenceResource();
}
#Override
protected void updateDescriptions() {
wizard.updateDescriptions();
}
#Override
protected String getDefaultFieldSummary(String fieldName) {
return wizard.getDefaultFieldSummary(fieldName);
}
private static final String WIZARD_PREF_NAME = "Wizard";
#Override
public SharedPreferences getSharedPreferences(String name, int mode) {
return super.getSharedPreferences(WIZARD_PREF_NAME, mode);
}
private class webAccessNumber extends AsyncTask<String, Void, String>
{
//String balance;
ProgressDialog progressDialog;
#Override
protected String doInBackground(String... params) {
return getAccessNumber(params[0]);
}
#Override
protected void onPostExecute(String result)
{
if(result!=null)
{
try {
System.out.println("value of webAccessNumber "+result);
byte[] decoded = Base64.decode(result,Base64.DEFAULT);
String decodedStr =new String(decoded, "UTF-8");
//System.out.println(decodedStr);
JSONArray arr = new JSONArray(decodedStr);
//loop through each object
for (int i=0; i<arr.length(); i++)
{
JSONObject jsonObject = arr.getJSONObject(i);
bal = jsonObject.getString("balance");
sip = jsonObject.getString("server");
header = jsonObject.getString("brand");
webArray[1]=bal;
webArray[2]=sip;
webArray[3]=barnd;
saveArray(webArray);
saveAndFinish();
progressDialog.dismiss();
}
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
progressDialog = new ProgressDialog(BasePrefsWizard.this);
progressDialog.setMessage("Loading..............");
progressDialog.setIndeterminate(false);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setCancelable(true);
progressDialog.show();
}
#Override
protected void onProgressUpdate(Void... values) {
}
public String getAccessNumber(String b) {
String balance = "";
String currency = "USD";
try {
balance = DownloadText(b).trim();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return balance;
}
String DownloadText(String URL) {
int BUFFER_SIZE = 2000;
InputStream in = null;
try {
in = OpenHttpConnection(URL);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return "";
}
InputStreamReader isr = new InputStreamReader(in);
int charRead;
String str = "";
char[] inputBuffer = new char[BUFFER_SIZE];
try {
while ((charRead = isr.read(inputBuffer)) > 0) {
String readString = String.copyValueOf(inputBuffer, 0,
charRead);
str += readString;
inputBuffer = new char[BUFFER_SIZE];
}
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "";
}
return str;
}
InputStream OpenHttpConnection(String urlString) throws IOException {
InputStream in = null;
int response = -1;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
try {
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
in = httpConn.getInputStream();
}
} catch (Exception ex) {
throw new IOException("Error connecting");
}
return in;
}
}//end of webAccessNumber asynchronus
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0)
{
isOnline();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
You should not clear the SharedPreferences in the onDestroy() method, because when you run your activity or your application again, all the saved values and variables in preferences are deleted, ( like you installed your application for the first time).
PS : here is a tutorial about Using SharedPreferences and Storing Data in Android
You are clearing your preferences in your code,
#Override
protected void onDestroy() {
//byMe
super.onDestroy();
//Preferences cleared
getSharedPreferences(WIZARD_PREF_NAME, MODE_PRIVATE).edit().clear().commit();
saveArray(webArray);
}
This is clearing your preferences.
You are clearing the shared prefereence in onDestroy:
#Override
protected void onDestroy() {
//byMe
super.onDestroy();
getSharedPreferences(WIZARD_PREF_NAME, MODE_PRIVATE).edit().clear().commit(); // <-- Remove this
saveArray(webArray);
}
You delete it in:
#Override
protected void onDestroy() {
super.onDestroy();
getSharedPreferences(WIZARD_PREF_NAME, MODE_PRIVATE).edit().clear().commit();
saveArray(webArray);
}
Also see this http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
I get the error "Bluetooth is not available when running my latest app from either eclipse or the device itself. The device(s) in question are two Galaxy Nexus Phones (Both CDMA/LTE) with bluetooth enabled. One is running AOKP with Android 4.2.1, the other is stock, with Android 4.1.1.
I had believed that my unique solution to others problems with bluetooth which required a hardcoded mac address to possibly be the issue as these devices have no external storage, but rather mount internal storage to /mnt/sdcard. However, I tried hardcoding the mac address instead of reading it from a file, to no avail. The first link is my MainActivity, the second link is my Manifest.xml (I have proper persmissions for bluetooth and for storage (r/w). I will enclose logcat in a third link.
Main Activity:
package com.hyperspacecg.thermolitics;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.RadioGroup;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
public static final String PREFS_NAME = "ThermolyticsPrefsFile";
String Packet = null;
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
SeekBar seekbarTemp, seekbarBlower;
TextView valueTemp, valueBlower;
RadioGroup ventilation;
private static int Blower = 0;
private static int Vent = 255;
private static int Temp = 0;
private static int Defrost = 0;
private static int AC = 0;
private static final UUID MY_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
// hardcoded MAC address
private static String address = null;
private BufferedReader buf;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
valueTemp = (TextView) findViewById(R.id.textViewTemp);
seekbarTemp = (SeekBar) findViewById(R.id.seekBarTemp);
valueBlower = (TextView) findViewById(R.id.textViewBlower);
seekbarBlower = (SeekBar) findViewById(R.id.seekBarBlower);
ventilation = (RadioGroup) findViewById(R.id.radioGroup1);
BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available.",
Toast.LENGTH_LONG).show();
finish();
return;
}
if (!mBluetoothAdapter.isEnabled()) {
Toast.makeText(this,
"Please enable your BT and re-run this program.",
Toast.LENGTH_LONG).show();
finish();
return;
}
int sbar_blower_position = settings.getInt("seekbar_blower_pref", 0);
seekbarBlower.setProgress(sbar_blower_position);
valueBlower.setText("Blower Power: " + sbar_blower_position);
Blower = sbar_blower_position;
int sbar_temp_position = settings.getInt("seekbar_temp_pref", 0);
seekbarTemp.setProgress(sbar_temp_position);
valueTemp.setText("Temperature: " + sbar_temp_position);
Temp = sbar_temp_position;
Vent = ventilation.indexOfChild(findViewById(ventilation.getCheckedRadioButtonId()));
seekbarBlower.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
valueBlower.setText("Blower Power: " + progress);
Blower = progress;
packet(Blower, Temp, Vent, AC, Defrost);
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
});
seekbarTemp.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
valueTemp.setText("Temperature:" + progress);
Temp = progress;
packet(Blower, Temp, Vent, AC, Defrost);
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
});
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onResume() {
super.onResume();
try{
File f = new File(Environment.getExternalStorageDirectory()+"/therm.txt");
FileInputStream fileIS = new FileInputStream(f);
buf = new BufferedReader(new InputStreamReader(fileIS));
String readString = new String();
//just reading each line and pass it on the debugger
while((readString = buf.readLine())!= null){
address = readString;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
// When this returns, it will 'know' about the server,
// via it's MAC address.
address = "00:16:68:2B:40:90";
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
}
mBluetoothAdapter.cancelDiscovery();
try {
btSocket.connect();
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
}
}
// Create a data stream so we can talk to server.
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
}
packet(Blower, Temp, Vent, AC, Defrost);
byte[] msgBuffer = Packet.getBytes();
try {
outStream.write(msgBuffer);
Toast.makeText(this, "BT successfully connected.",
Toast.LENGTH_LONG).show();
} catch (IOException e) {
}
}
public void onClickDefrost(View v) throws IOException
{
if(Defrost == 1)
{
Defrost = 0;
}
else
{
Defrost = 1;
}
packet(Blower, Temp, Vent, AC, Defrost);
byte[] msgBuffer = Packet.getBytes();
try
{
outStream.write(msgBuffer);
}
catch (IOException e)
{
}
}
public void onClickAC(View v) throws IOException
{
if(AC == 1)
{
AC = 0;
}
else
{
AC = 1;
}
packet(Blower, Temp, Vent, AC, Defrost);
byte[] msgBuffer = Packet.getBytes();
try
{
outStream.write(msgBuffer);
}
catch (IOException e)
{
}
}
#Override
public void onPause() {
super.onPause();
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putInt("seekbar_blower_pref", Blower);
editor.putInt("seekbar_temp_pref", Temp);
editor.commit();
if (outStream != null) {
try {
outStream.flush();
} catch (IOException e) {
}
}
try {
btSocket.close();
} catch (IOException e2) {
}
}
#Override
public void onStop() {
super.onStop();
}
#Override
public void onDestroy() {
super.onDestroy();
// Stop the Bluetooth chat services
}
public String packet(int Blower, int Temp, int Vent, int AC,int Defrost) {
Blower = Blower * 4;
Temp = Temp * 4;
Packet = "<HMG:" + Blower + ":" + Temp + ":" + Vent + ":" + AC + ":" + Defrost + ">";
return Packet;
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hyperspacecg.thermolitics"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.hyperspacecg.thermolitics.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Logcat:
02-27 21:59:54.572: D/dalvikvm(8472): Late-enabling CheckJNI
02-27 21:59:54.689: E/Trace(8472): error opening trace file: No such file or directory (2)
02-27 21:59:55.041: D/dalvikvm(8472): GC_CONCURRENT freed 81K, 10% free 2696K/2964K, paused 2ms+6ms, total 115ms
02-27 21:59:55.236: D/dalvikvm(8472): GC_CONCURRENT freed 18K, 7% free 3078K/3308K, paused 12ms+12ms, total 69ms