I am developing an application that sends over a webservice information about the last dialed number, call status, and duration of the call.
The application works perfectly fine, but when the device closes the application the android service does restart but the activity does not.
The way I am sure about that is that I have Toasts when the service is started: "Servicio TRUCKA iniciado" and "Servicio TRUCKA creado" tell me that the service has been created and started.
And when the information is sent to the webservice I have toasts saying: "Enviando información..." and "Información enviada."
But when the application is closed (via the android task manager that automatically closes apps) the messages from the service "Servicio TRUCKA iniciado" and "Servicio TRUCKA creado" do appear, but the toasts from the information sent part do not.
I hope someone can help me and tell what am I doing wrong? :)
This is my Activity:
package com.trucka.llamadasdrivers;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import com.trucka.llamadasdrivers.R;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.CallLog;
import android.widget.TextView;
import android.widget.Toast;
import android.telephony.*;
import android.util.Log;
import java.text.SimpleDateFormat;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
public class ActividadLlamadasDrivers extends Activity {
TextView txtInformacion = null;
TextView txtDetalles = null;
TextView tv = null;
// Comunicación con el webservice.
private final String NAMESPACE = "http://truckanet.com/MensajeOperador";
// private final String URL =
// "http://192.168.10.94/MensajeOperador/MensajeOperador.asmx";
private final String URL = "http://200.76.187.148/MensajeOperador/MensajeOperador.asmx";
private final String SOAP_ACTION = "http://truckanet.com/MensajeOperador/ActualizarFede";
private final String METHOD_NAME = "ActualizarFede";
private String TAG = "TRUCKA_DRIVERS";
private String resultado;
String phNumber = null;
String callType = null;
String callDate = null;
DateFormat shortFecha = null;
DateFormat shortDF = null;
Date callDayTime = null;
Date fin = null;
String fechaLlamada1 = null;
String fechaLlamada2 = null;
String callDuration = null;
String dir = null;
public String tolo = null;
String imei = null;
String comentario = null;
String fechaRegistro = null;
String insercion = null;
String fechaInicio = null;
String fechaFin = null;
String estadoLlamada = null;
int reinicios = 0;
#Override
public void onBackPressed() {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_actividad_llamadas_drivers);
if (!ServicioLlamadas.isRunning()) {
reinicios ++;
Toast.makeText(getApplicationContext(), Integer.toString(reinicios) , Toast.LENGTH_LONG).show();
Intent in = new Intent(ActividadLlamadasDrivers.this,
ServicioLlamadas.class);
ActividadLlamadasDrivers.this.startService(in);
TelephonyManager TelephonyMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
TelephonyMgr.listen(new TeleListener(),
PhoneStateListener.LISTEN_CALL_STATE);
tv = (TextView) findViewById(R.id.txvEstadoServicio);
txtInformacion = (TextView) findViewById(R.id.textview_call);
txtDetalles = (TextView) findViewById(R.id.textview_call2);
}
}
class TeleListener extends PhoneStateListener {
private boolean telefonoLlamando = false;
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if (TelephonyManager.CALL_STATE_RINGING == state) {
// phone ringing
}
if (TelephonyManager.CALL_STATE_OFFHOOK == state) {
// active
//getCallDetails();
telefonoLlamando = true;
Toast.makeText(getApplicationContext(),
"Enviando información...", Toast.LENGTH_SHORT).show();
}
if (TelephonyManager.CALL_STATE_IDLE == state) {
// run when class initial and phone call ended,
// need detect flag from CALL_STATE_OFFHOOK
Toast.makeText(getApplicationContext(),
"Información enviada.", Toast.LENGTH_SHORT).show();
if (telefonoLlamando) {
// restart app
getCallDetails();
telefonoLlamando = false;
}
}
}
}
// Obtener la fecha actual del teléfono.
public long getTodayTimestamp() {
Calendar c1 = Calendar.getInstance();
c1.setTime(new Date());
Calendar c2 = Calendar.getInstance();
c2.set(Calendar.YEAR, c1.get(Calendar.YEAR));
c2.set(Calendar.MONTH, c1.get(Calendar.MONTH));
c2.set(Calendar.DAY_OF_MONTH, c1.get(Calendar.DAY_OF_MONTH));
c2.set(Calendar.HOUR_OF_DAY, 0);
c2.set(Calendar.MINUTE, 0);
c2.set(Calendar.SECOND, 0);
return c2.getTimeInMillis();
}
// Obtener el detalle de las llamadas con la fecha actual.
#SuppressLint("SimpleDateFormat")
private void getCallDetails() {
String timestamp = String.valueOf(getTodayTimestamp());
StringBuffer sb = new StringBuffer();
#SuppressWarnings("deprecation")
Cursor managedCursor = managedQuery(CallLog.Calls.CONTENT_URI, null,
CallLog.Calls.DATE + ">= ?", new String[] { timestamp }, null);
int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
sb.append("Bitácora de llamadas :");
Integer contador = 0;
// while (managedCursor.moveToNext()) {
// managedCursor.moveToFirst();
managedCursor.moveToLast();
contador = contador + 1;
phNumber = managedCursor.getString(number);
callType = managedCursor.getString(type);
callDate = managedCursor.getString(date);
shortFecha = DateFormat.getDateInstance(DateFormat.SHORT);
shortDF = DateFormat.getTimeInstance(DateFormat.SHORT);
callDayTime = new Date(Long.valueOf(callDate));
fechaLlamada1 = shortDF.format(callDayTime);
fechaLlamada2 = shortFecha.format(callDayTime);
callDuration = managedCursor.getString(duration);
int dircode = Integer.parseInt(callType);
TelephonyManager mngr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
switch (dircode) {
case CallLog.Calls.OUTGOING_TYPE:
dir = "Saliente";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "Entrante";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "Perdida";
break;
}
imei = mngr.getDeviceId();
comentario = dir;
fechaRegistro = fechaLlamada2;
DateFormat df = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
String ahorita = df.format(callDayTime);
fechaInicio = ahorita.toString();
// fechaFin =
// df.format(callDayTime.setSeconds(callDayTime.getSeconds()+5));
insercion = "DECLARE #claveDriver INT, #nombreDriver VARCHAR(max), #evento VARCHAR(max), #duracion int, #inicial varchar(max) "
+ "SET #claveDriver = (SELECT cve_tra FROM SISTEMA.dbo.TELEFONOS WHERE IMEI_SIM = '"
+ mngr.getDeviceId()
+ "') "
+ "SET #nombreDriver = (SELECT nombre FROM SISTEMA.dbo.TELEFONOS WHERE IMEI_SIM = '"
+ mngr.getDeviceId()
+ "') "
+ "SET #duracion = "
+ managedCursor.getString(duration)
+ "SET #evento = '(LOG) Llamada "
+ dir
+ ". Duración ' + CONVERT(varchar, #duracion, 103) + ' segundos al número: "
+ managedCursor.getString(number)
+ "' "
// + "SET #duracion = " + callDuration
+ " SET #inicial = '"
+ fechaInicio
+ "'"
+ "INSERT INTO bitacora.dbo.registroDellamadasOperadores (fechacreacion,fecha_fin,fecha_inicio,idMobil,Tractor,Nom_tra,Cve_tra,FechaRegistro,Evento) "
+ " VALUES('"
+ fechaInicio
+ "', DATEADD(SECOND,#duracion,#inicial),'"
+ fechaInicio
+ "','"
+ mngr.getDeviceId()
+ "','',#nombreDriver,#claveDriver,current_timestamp,#evento)";
AsyncCallWS tareaEnviarABD = new AsyncCallWS();
tareaEnviarABD.execute();
sb.append("\nNúmero de teléfono:--- " + phNumber
+ " \nTipo de llamada:--- " + dir + " \nFecha de llamada:--- "
+ fechaLlamada2 + " " + fechaLlamada1
+ " \nDuración en segundos:--- " + callDuration
+ " \nDispositivo actual:--" + mngr.getDeviceId());
sb.append("\n----------------------------------");
// }
txtDetalles.setText(sb);
}
private class AsyncCallWS extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... params) {
Log.i(TAG, "doInBackground");
InsertarLlamada(insercion);
return null;
}
#Override
protected void onPostExecute(Void result) {
Log.i(TAG, "onPostExecute");
txtInformacion.setText("Información enviada");
}
#Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
txtInformacion.setText("Enviando información...");
}
#Override
protected void onProgressUpdate(Void... values) {
Log.i(TAG, "onProgressUpdate");
}
public void InsertarLlamada(String insercion) {
// Creamos la solicitud
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
// Propiedades que contienen los valores
PropertyInfo propiedades = new PropertyInfo();
propiedades.setName("insercion");
propiedades.setValue(insercion);
propiedades.setType(String.class);
// Agregamos las propiedades
request.addProperty(propiedades);
// Creamos el envelope
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.dotNet = true;
// ponemos la salida SOAP
envelope.setOutputSoapObject(request);
// Creamos la llamada HTTP
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
// Invocamos el servicio
androidHttpTransport.call(SOAP_ACTION, envelope);
// Obtenemos la respuesta
Object response = envelope.getResponse();
// Asignamos el resultado de la consulta
resultado = response.toString();
} catch (Exception e) {
resultado = e.getMessage();
}
}
}
}
BootReceiver class:
package com.trucka.llamadasdrivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context, ActividadLlamadasDrivers.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
}
}
Llamadas service:
package com.trucka.llamadasdrivers;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.IBinder;
import android.widget.Toast;
public class ServicioLlamadas extends Service {
private static ServicioLlamadas instance = null;
public static boolean isRunning() {
return instance != null;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(getApplicationContext(), "Servicio TRUCKA creado",
Toast.LENGTH_SHORT).show();
instance = this;
}
#Override
public void onDestroy() {
Toast.makeText(getApplicationContext(), "Servicio TRUCKA destruído",
Toast.LENGTH_SHORT).show();
instance = null;
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(getApplicationContext(), "Servicio TRUCKA iniciado",
Toast.LENGTH_SHORT).show();
lanzarNotificacion();
}
#SuppressWarnings("deprecation")
void lanzarNotificacion() {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager notManager = (NotificationManager) getSystemService(ns);
// Configuramos la notificacion
Notification notif = new Notification(
android.R.drawable.ic_menu_agenda, "Servicio TRUCKA",
System.currentTimeMillis());
// Configuramos el Intent
Context contexto = ServicioLlamadas.this;
CharSequence titulo = "Notificación Servicio TRUCKA";
CharSequence descripcion = "Registro habilitado.";
// Intent que se abrira al clickear la notificacion
PendingIntent contIntent = PendingIntent.getActivity(contexto, 0, null,
0);
notif.setLatestEventInfo(contexto, titulo, descripcion, contIntent);
notif.flags |= Notification.FLAG_AUTO_CANCEL;
notif.defaults |= Notification.DEFAULT_VIBRATE;
notManager.notify(1, notif);
}
}
And manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.trucka.llamadasdrivers"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.trucka.llamadasdrivers.ActividadLlamadasDrivers"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.trucka.llamadasdrivers.ServicioLlamadas"
android:enabled="true"
android:icon="#drawable/ic_launcher" >
</service>
<receiver android:name=".BootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
Human stupidity has no limits.
My actines where not in the service
Related
so I've created an app which sets an alarm 25 mins before your departure time, based on the estimated time taken to travel from your place of departure to your destination.
I am able to build the app, but the app keeps crashing whenever I press the search button. I am guessing it has something to do with the integration of the placeautocomplete fragment, but not sure what about it.
Main Activity
package com.example.mobileassignment2.buildingblocks;
import android.app.AlarmManager;
import android.app.DialogFragment;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.ui.PlaceAutocompleteFragment;
import com.google.android.gms.location.places.ui.PlaceSelectionListener;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.Calendar;
public class MainActivity extends AppCompatActivity implements TimePickerDialog .OnTimeSetListener{
String DistanceResult;
String DurationResult;
String LeaveByHour;
String LeaveByMin;
String AlarmTimeHour;
String AlarmTimeMin;
int ArriveHour;
int ArriveMin;
int AlarmHour;
int AlarmMin;
Calendar alarmCalendar;
#Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
TextView textViewArriveByTime = (TextView)findViewById(R.id.textViewArriveByTime);
textViewArriveByTime.setText("Hour: "+ hourOfDay +"\n"+ "Minute: "+minute);
ArriveHour = hourOfDay;
ArriveMin = minute;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activitiy_main);
Button button = (Button) findViewById(R.id.ArriveByBtn);
button.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
DialogFragment timePicker = new TimePickerFragment();
timePicker.show(getFragmentManager(), "time picker");
}
});
Reset();
}
public void Reset(){
DistanceResult = "";
DurationResult = "";
TextView Distance_Output = (TextView) findViewById(R.id.DistanceResult);
TextView Duration_Output = (TextView) findViewById(R.id.DurationResult);
Distance_Output.setText("Distance: " + DistanceResult);
Duration_Output.setText("Duration: " + DurationResult);
LeaveByMin = "";
AlarmTimeMin = "";
TextView LeaveBy_Calculated = (TextView) findViewById(R.id.LeaveBy);
LeaveBy_Calculated.setText("Leave By: " + LeaveByMin);
TextView AlarmTime_Calculated = (TextView) findViewById(R.id.AlarmTime);
AlarmTime_Calculated.setText("Alarm Time: " + AlarmTimeMin);
TextView textViewArriveByTime = (TextView)findViewById(R.id.textViewArriveByTime);
textViewArriveByTime.setText("Hour: "+"\n"+ "Minute: ");
}
private static final String TAG = "MainActivity";
public void SearchDistanceCommand(View view) {
PlaceAutocompleteFragment Start_Location = (PlaceAutocompleteFragment)
getFragmentManager().findFragmentById(R.id.StartLocation);
Start_Location.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
Log.i(TAG, "Place: " + place.getName());
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
Log.i(TAG, "An error occurred: " + status);
}
});
PlaceAutocompleteFragment Goal_Location = (PlaceAutocompleteFragment)
getFragmentManager().findFragmentById(R.id.GoalLocation);
Goal_Location.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
Log.i(TAG, "Place: " + place.getName());
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
Log.i(TAG, "An error occurred: " + status);
}
});
Reset();
if(Start_Location.toString().isEmpty()|| Goal_Location.toString().isEmpty()){
Toast MissingTextErrorHandle = Toast.makeText(getApplicationContext(), "You need to input data into both fields!", Toast.LENGTH_SHORT);
MissingTextErrorHandle.show();
}
else
{
new AsyncTaskParseJson().execute();
}
}
public class AsyncTaskParseJson extends AsyncTask<String, String, String> {
EditText Start_Location = (EditText) findViewById(R.id.StartLocation);
EditText Goal_Location = (EditText) findViewById(R.id.GoalLocation);
//To convert to UTC, how to use time picker
// EditText Arrive_By = (EditText) findViewById(R.id.ArriveBy);
String FormattedStartLocation = Start_Location.getText().toString().replaceAll(" ", "+");
String FormattedGoalLocation = Goal_Location.getText().toString().replaceAll(" ", "+");
String yourServiceUrl = "https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins=" + FormattedStartLocation + "&destinations=" + FormattedGoalLocation
/* + "&arrival_time=" + Arrive_By*/
+ "&key=___MY___SECRET___KEY___";
#Override
protected void onPreExecute() {
ProgressBar spinner;
spinner = (ProgressBar) findViewById(R.id.progressBar1);
spinner.setVisibility(View.VISIBLE);
}
#Override
protected String doInBackground(String... arg0) {
try {
httpConnect jParser = new httpConnect();
String json = jParser.getJSONFromUrl(yourServiceUrl);
JSONObject object = new JSONObject(json);
//contains ALL routes
JSONArray array = object.getJSONArray("rows");
// Get the first route
JSONObject route = array.getJSONObject(0);
// Take all elements
JSONArray elements = route.getJSONArray("elements");
//Take First Element
JSONObject element = elements.getJSONObject(0);
// Get Duration
JSONObject durationObject = element.getJSONObject("duration");
String duration = durationObject.getString("text");
DurationResult = duration;
// Get Distance
JSONObject distanceObject = element.getJSONObject("distance");
String distance = distanceObject.getString("text");
DistanceResult = distance;
//Get Leave By Time (ATTENTION!!: Need to edit for when duration > 1hr)
String sDMin = DurationResult;
//Nic: Remove Characters, Convert duration str to int, !!Assume duration is <1 Hr
sDMin = sDMin.replaceAll( " mins", "" );
int dMin = Integer.parseInt(sDMin);
int remMin = dMin % 60;
int remHour = dMin / 60;
int leaveHour = ArriveHour - remHour;
if (leaveHour < 0){
leaveHour = 23;
}
int leaveMin = ArriveMin - remMin -5;
if (leaveMin < 0){
leaveHour -= 1;
leaveMin += 60;
if (leaveHour < 0){
leaveHour = 23;
}
}
//Convert int to str for printing
String sLeaveHour = Integer.toString(leaveHour);
String sLeaveMin = Integer.toString(leaveMin);
LeaveByHour = sLeaveHour;
LeaveByMin = sLeaveMin;
//Get Alarm Time (int value), alarmManager later
//String sATMin = DurationResult;
//Nic: Remove Characters, Convert duration str to int, !!Assume duration is <1 Hr
//sATMin = sATMin.replaceAll( " mins", "" );
//int atMin = Integer.parseInt(sATMin);
/*int remAlarmMin = (atMin % 60) - 30;
int remAlarmHour = atMin / 60;
int alarmHour = ArriveHour - remAlarmHour;
int alarmMin = ArriveMin - remAlarmMin;
if (alarmMin < 0){
alarmHour -= 1;
alarmMin += 60;*/
int alarmHour = leaveHour;
if(alarmHour < 0){
alarmHour = 23;
}
int alarmMin = leaveMin - 30;
if (alarmMin < 0){
alarmHour -= 1;
alarmMin += 60;
if(alarmHour < 0){
alarmHour = 23;
}
}
//Set Global Variable to set calendar to set Alarm time
AlarmHour = alarmHour;
AlarmMin = alarmMin;
//Convert int to str for printing
String sAlarmHour = Integer.toString(alarmHour);
String sAlarmMin = Integer.toString(alarmMin);
AlarmTimeHour = sAlarmHour;
AlarmTimeMin = sAlarmMin;
Calendar calendar = Calendar.getInstance();
calendar.set(
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH),
AlarmHour,
AlarmMin,
0);
alarmCalendar = calendar;
setAlarm(alarmCalendar.getTimeInMillis());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String strFromDoInBg) {
if(DistanceResult == null || DurationResult == null){
Toast ResultErrorHandle = Toast.makeText(getApplicationContext(), "We could not find any results! Sorry!", Toast.LENGTH_SHORT);
ResultErrorHandle.show();
}
ProgressBar spinner;
spinner = (ProgressBar) findViewById(R.id.progressBar1);
spinner.setVisibility(View.INVISIBLE);
TextView Distance_Output = (TextView) findViewById(R.id.DistanceResult);
Distance_Output.setText("Distance: " + DistanceResult);
TextView Duration_Output = (TextView) findViewById(R.id.DurationResult);
Duration_Output.setText("Duration: " + DurationResult);
TextView LeaveBy_Calculated = (TextView) findViewById(R.id.LeaveBy);
LeaveBy_Calculated.setText("Leave By| Hour: " + LeaveByHour + " Min: " + LeaveByMin);
TextView AlarmTime_Calculated = (TextView) findViewById(R.id.AlarmTime);
AlarmTime_Calculated.setText("Alarm Time| Hour " + AlarmTimeHour + " Min: " + AlarmTimeMin);
}
}
public void CancelAlarmCommand(){
cancelAlarm();
}
public void setAlarm(long timeInMillis) {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,intent,0);
AlarmManager.AlarmClockInfo ac= new AlarmManager.AlarmClockInfo(timeInMillis, pendingIntent.getBroadcast(this,0,intent,0));
alarmManager.setAlarmClock(ac,pendingIntent);
Toast.makeText(this, "Alarm set!", Toast.LENGTH_SHORT).show();
}
private void cancelAlarm(){
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,intent,0);
alarmManager.cancel(pendingIntent);
}
}
Gradle App
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion '27.0.3'
defaultConfig {
applicationId "com.example.mobileassignment2.buildingblocks"
minSdkVersion 21
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
//noinspection GradleCompatible
implementation 'com.android.support:appcompat-v7:25.3.1'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
implementation 'com.google.android.gms:play-services-places:15.0.1'
implementation 'com.google.android.gms:play-services-location:15.0.1'
}
Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".AlarmReceiver"
android:enabled="true"
android:exported="true" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyC0UU_6yNvnroXuHBWPd2_SPfBP9Y29bp4"/>
</application>
logcat
09-05 00:04:22.519 1530-9975/? I/AudioFlinger: AudioFlinger's thread 0xe57037c0 tid=9975 ready to run 09-05 00:04:22.546 1530-1603/?
E/AudioFlinger: not enough memory for AudioTrack size=131296 09-05
00:04:22.548 1530-1603/? E/AudioFlinger: createRecordTrack_l()
initCheck failed -12; no control block? 09-05 00:04:22.554
2336-9720/com.google.android.googlequicksearchbox:search
E/AudioRecord: AudioFlinger could not create record track, status: -12
09-05 00:04:22.575
2336-9720/com.google.android.googlequicksearchbox:search
E/AudioRecord-JNI: Error creating AudioRecord instance: initialization
check failed with status -12. 09-05 00:04:22.578
2336-9720/com.google.android.googlequicksearchbox:search
E/android.media.AudioRecord: Error code -20 when initializing native
AudioRecord object.
Device is registering but problem in getting notification, I tried in many ways but not succeeded. please anyone help me on this.
Below is my GCMIntentService.java
/*
* Copyright 2012 Google Inc.
*
* 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.
*/
package in.oneindia.android.clickin;
import static in.oneindia.android.clickin.utils.CommonUtilities.displayMessage;
import in.oneindia.android.clickin.LeftAndRightActivity;
import in.oneindia.android.clickin.MailActivity;
import in.oneindia.android.clickin.R;
import in.oneindia.android.clickin.HomeActivity;
import in.oneindia.android.clickin.SplashScreenActivity;
import in.oneindia.android.clickin.utils.CommonUtilities;
import in.oneindia.android.clickin.utils.ServerUtilities;
import in.oneindia.android.clickin.utils.SharedPrefUtils;
import in.oneindia.android.clickin.utils.Util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Random;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;
import com.google.android.gcm.GCMBaseIntentService;
import com.google.android.gcm.GCMRegistrar;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.WindowManager;
import android.view.View.MeasureSpec;
import android.widget.LinearLayout;
import android.widget.RemoteViews;
import android.widget.TextView;
import android.widget.Toast;
/**
* IntentService responsible for handling GCM messages.
*/
public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = "GCMIntentService";
public GCMIntentService()
{
super(CommonUtilities.SENDER_ID);
}
#Override
protected void onRegistered(Context context, String registrationId) {
Util.logv(TAG, "Device registered: regId = " + registrationId);
displayMessage(context, getString(R.string.gcm_registered));
ServerUtilities.register(context, registrationId);
String strId = registrationId;
//Log.v("","CHECKING GCM WORKING OR NOT:::::::"+strId);
if (strId != null) {
SharedPrefUtils.setPushID(context, strId);
//this.saveRegistrationIdAndSendToServer(strId);
}
}
public String saveRegistrationIdAndSendToServer(String registrationId)
{
String strRegistrationId=null;
Util.logv("C2DM", "Sending registration ID to my application server");
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://rss.oneindia.in/apps/registerId.php?action="+registrationId);
try
{
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null)
{
strRegistrationId= line;
}
}
catch (IOException e)
{
e.printStackTrace();
}
return strRegistrationId;
}
#Override
protected void onUnregistered(Context context, String registrationId) {
Util.logv(TAG, "Device unregistered");
displayMessage(context, getString(R.string.gcm_unregistered));
if (GCMRegistrar.isRegisteredOnServer(context)) {
ServerUtilities.unregister(context, registrationId);
} else {
// This callback results from the call to unregister made on
// ServerUtilities when the registration to the server failed.
Util.logv(TAG, "Ignoring unregister callback");
}
}
#Override
protected void onMessage(Context context, Intent intent) {
Util.logv(TAG, "Received message");
String action = intent.getAction();
if ("com.google.android.c2dm.intent.RECEIVE".equals(action)) {
String myTitle = intent.getStringExtra("classifiedTitle");
String myPostID = intent.getStringExtra("postID");
String myImage = intent.getStringExtra("classifiedImage");
//String csFlashNews = intent.getStringExtra("flash_news");
//String csShowAd = intent.getStringExtra("show_ad");
//String csFlashContent = intent.getStringExtra("flash_content");
Util.logv(TAG, "TITLE : "+myTitle);
Util.logv("MyPOSTID", "POST ID : "+myPostID);
String s=myTitle.toString();
parse_json_add(s);
displayMessage(context, myTitle);
// notifies user
generateNotification(context, myTitle, myPostID, myImage);
}
}
private void parse_json_add(String text) {
if (text!= null)
{
try {
JSONObject temp=new JSONObject(text);
String value=temp.get("state").toString();
Log.v(TAG, value);
} catch (Exception e) {
// TODO: handle exception
}
}
}
#Override
protected void onDeletedMessages(Context context, int total) {
Util.logv(TAG, "Received deleted messages notification");
String message = getString(R.string.gcm_deleted, total);
displayMessage(context, message);
String entryID = null;
String URL = null;
/*String flashNews = null;
String showAd = null;
String flashContent = null;*/
// notifies user
generateNotification(context, message, entryID, URL);
}
#Override
public void onError(Context context, String errorId) {
Util.logv(TAG, "Received error: " + errorId);
displayMessage(context, getString(R.string.gcm_error, errorId));
}
#Override
protected boolean onRecoverableError(Context context, String errorId) {
// log message
Util.logv(TAG, "Received recoverable error: " + errorId);
displayMessage(context, getString(R.string.gcm_recoverable_error,
errorId));
return super.onRecoverableError(context, errorId);
}
/**
* Issues a notification to inform the user that server has sent a message.
*/
public static void generateNotification(Context context, String message, String EntryID, String src) {
//String title = context.getString(R.string.app_name);
String title = "Click.in";
//String URL = "http://tamil.oneindia.in/img/2014/05/25-kejriwal113434-600.jpg";
Bitmap largeIcon = getBitmapFromUrl(src);
if(largeIcon == null)
{
largeIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.clickinicon512x512);
}
try
{
double ArticleEntryID = 0;
int csbooleanFlashNews = 0;
int csbooleanShowAd = 0;
if(EntryID != null && !EntryID.equals(""))
{
ArticleEntryID = Double.parseDouble(EntryID);
}
/*if(strBooleanFlashNews != null && !strBooleanFlashNews.equals(""))
{
csbooleanFlashNews = Integer.parseInt(strBooleanFlashNews);
}
if(strBooleanShowAd != null && !strBooleanShowAd.equals(""))
{
csbooleanShowAd = Integer.parseInt(strBooleanShowAd);
}*/
Intent notificationIntent;
if(ArticleEntryID == 0)
{
notificationIntent = new Intent(context, HomeActivity.class);
notificationIntent.putExtra("checkingpush", "PUSH");
/*notificationIntent.putExtra("showad", csbooleanShowAd);
notificationIntent.putExtra("flashnews", csbooleanFlashNews);
notificationIntent.putExtra("flashnewscontent", csFlashContent);
notificationIntent.putExtra("selectedposition", 0);
notificationIntent.putExtra("channelid", 0);*/
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
else
{
notificationIntent = new Intent(context, LeftAndRightActivity.class);
notificationIntent.putExtra("pushdata", EntryID);
notificationIntent.putExtra("title", csbooleanShowAd);
//notificationIntent.putExtra("flashnews", csbooleanFlashNews);
notificationIntent.putExtra("checkingpush", "PUSH");
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
/*// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);*/
PendingIntent intent =
PendingIntent.getActivity(context, new Random(System.currentTimeMillis()).nextInt(), notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
int id = sp.getInt("notifid", -1);
id++;
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN)
{
// Using RemoteViews to bind custom layouts into Notification
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.notification_layout_normal);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.clickinicon512x512)
.setTicker(message)
.setAutoCancel(true)
.setContentIntent(intent)
.setContent(remoteViews);
//remoteViews.setImageViewBitmap(R.id.notification_imageview, largeIcon);
//remoteViews.setTextViewText(R.id.notification_text_title, message);
//remoteViews.setImageViewBitmap(R.id.notification_title_imageview, buildUpdate(context, message, SharedPrefUtils.getLanguage(context)));
Notification n = builder.build();
n.contentView = remoteViews;
n.defaults = Notification.DEFAULT_SOUND;
NotificationManager notificationmanager = (NotificationManager)context.getSystemService(NOTIFICATION_SERVICE);
notificationmanager.notify(id, n);
}else
{
NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
android.support.v4.app.NotificationCompat.Builder builder = new android.support.v4.app.NotificationCompat.Builder(context);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
in.oneindia.android.clickin.R.layout.notification_layout_expandable);
remoteViews.setImageViewBitmap(R.id.notification_imageview, largeIcon);
remoteViews.setTextViewText(R.id.notification_text_title, message);
remoteViews.setTextViewText(R.id.notification_text_appname, title);
builder.setContentIntent(intent)
.setTicker(message)
.setWhen(System.currentTimeMillis())
.setContentTitle(title)
.setLargeIcon(Bitmap.createScaledBitmap(largeIcon, 100, 100, false))
.setContentText(message)
.setSmallIcon(R.drawable.clickinicon512x512);
//.setAutoCancel(true);
Notification n = builder.build();
/*if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
{
n.bigContentView = remoteViews;
}*/
n.flags = Notification.FLAG_AUTO_CANCEL;
n.defaults = Notification.DEFAULT_SOUND;
nm.notify(id, n);
}
if ( id > 10){ // Overwrite notification 10 notification is very long list
sp.edit().remove("notifid").commit(); //async
} else {
sp.edit().putInt("notifid",id).commit();
}
}catch(Exception e)
{
}
}
public static Bitmap getBitmapFromUrl(String src)
{
URL url = null;
InputStream input = null;
HttpURLConnection connection = null;
try {
url = new URL(src);
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
input = connection.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
}
public static Bitmap buildUpdate(Context context, String txt, String lang)
{
int bmapwidth = 320;
int bmapheight = 60;
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
int csWidth = dm.widthPixels;
float density = context.getResources().getDisplayMetrics().density;
float txtsize = 14;
float csLineSpaceAdd = 1f;
float csLineSpaceMul = 1f;
if(csWidth <=240)
{
bmapwidth = 220;
bmapheight = 55;
}else if(csWidth > 240 && csWidth <= 320)
{
bmapwidth = 280;
bmapheight = 60;
}else if(csWidth > 320 && csWidth <= 600)
{
bmapwidth = 350;
}else if (csWidth > 600) {
bmapwidth = 400;
}
String language = lang;
if (language.equals("6"))
{
if(density <= 0.75)
{
txtsize = 20;
}
else if(density > 0.75 && density <= 1)
{
txtsize = 17;
}
else if(density > 1 && density < 2)
{
txtsize=14;
}
else if(density >= 2)
{
txtsize=13;
}
}else if (language.equals("7"))
{
if(density <= 0.75)
{
txtsize = 18;
}
else if(density > 0.75 && density < 2)
{
txtsize=15;
}
else if(density >= 2)
{
txtsize=13;
}
}
else {
if(density <= 0.75)
{
txtsize = 17;
}
else if(density > 0.75 && density < 2)
{
txtsize=14;
}
else if(density >= 2)
{
txtsize=13;
}
}
String title_txt = txt;
Typeface langFont = null;
Bitmap myBitmap = Bitmap.createBitmap(bmapwidth, bmapheight, Bitmap.Config.ARGB_8888);
//Bitmap myBitmap = null;
Canvas myCanvas = new Canvas(myBitmap);
Paint paint = new Paint();
Log.v("languageSelected : ", language);
Log.v("Title : ", ""+txt);
if (language.equals("2")) {
langFont = Typeface.createFromAsset(context.getAssets(),"fonts/hindi.ttf");
csLineSpaceAdd = -1.8f;
csLineSpaceMul = 0.8f;
}else if (language.equals("3")) {
langFont = Typeface.createFromAsset(context.getAssets(),"fonts/kannada.ttf");
csLineSpaceAdd = -0.8f;
}else if (language.equals("4")) {
langFont = Typeface.createFromAsset(context.getAssets(),"fonts/telugu.ttf");
csLineSpaceAdd = -0.8f;
}else if (language.equals("5")) {
langFont = Typeface.createFromAsset(context.getAssets(),"fonts/malayalam.ttf");
csLineSpaceAdd = -0.7f;
}else if (language.equals("6")) {
//title_txt = TamilUtil.convertToTamil(TamilUtil.BAMINI, txt, context);
langFont = Typeface.createFromAsset(context.getAssets(),"fonts/Bamini.ttf");
}else if (language.equals("7")) {
langFont = Typeface.createFromAsset(context.getAssets(),"fonts/lohit_gu.ttf");
csLineSpaceAdd = 0.5f;
}
//Log.v("typeface : ", ""+langFont);
paint.setAntiAlias(true);
paint.setSubpixelText(true);
paint.setTypeface(langFont);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
TextView csText=new TextView(context);
csText.setTextColor(context.getResources().getColor(R.color.white));
csText.setTypeface(langFont);
csText.setGravity(Gravity.CENTER_VERTICAL);
csText.setText(title_txt);
csText.setTextSize(txtsize);
csText.setEllipsize(TextUtils.TruncateAt.END);
csText.setLines(2);
csText.setLineSpacing(csLineSpaceAdd, csLineSpaceMul);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(bmapwidth, bmapheight);
csText.setLayoutParams(lp);
csText.setDrawingCacheEnabled(true);
csText.measure(MeasureSpec.makeMeasureSpec(myCanvas.getWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(myCanvas.getHeight(), MeasureSpec.EXACTLY));
csText.layout(0, 0, csText.getMeasuredWidth(), csText.getMeasuredHeight());
myCanvas.drawBitmap(csText.getDrawingCache(), 0, 0, paint);
csText.setDrawingCacheEnabled(false);
return myBitmap;
}
public static void cancelAllNotification(Context context) {
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
}
}
Below are permissions which I gave in Manifest.xml. Please help me on this
<permission
android:name="in.oneindia.android.clickin.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="in.oneindia.android.clickin.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<service android:name="in.oneindia.android.clickin.GCMIntentService" />
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
enter code here
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="in.oneindia.android.clickin" />
</intent-filter>
</receiver>
How to get cell tower strength before outgoing call, if there is no signal or not enough strength it should prompt user with text No Signal.
See this signalStrength..this should do the trick
hi please use the following code hope it will solve yours problem
HomeActivity .java
// Android Packages
import android.app.Activity;
import android.os.Bundle;
import android.os.Build;
import android.os.AsyncTask;
import android.view.View;
import android.view.View.OnClickListener;
import android.content.Context;
import android.content.Intent;
import android.widget.TextView;
import android.widget.Button;
import android.telephony.SignalStrength;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.telephony.CellLocation;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import android.widget.Toast;
import android.util.Log;
public final class HomeActivity extends Activity
{
public static final String TAG = HomeActivity.class.getSimpleName();
public static final String EMAIL = "tbarrasso#sevenplusandroid.org";
private CellLocation mCellLocation;
private SignalStrength mSignalStrength;
private boolean mDone = false;
private TextView mText = null;
private String mTextStr;
private Button mSubmit, mCancel;
private TelephonyManager mManager;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
mText = (TextView) findViewById(R.id.text);
mSubmit = (Button) findViewById(R.id.submit);
mCancel = (Button) findViewById(R.id.cancel);
// Prevent button press.
mSubmit.setEnabled(false);
// Handle click events.
mSubmit.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View mView)
{
sendResults();
finish();
}
});
mCancel.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View mView)
{
finish();
}
});
// Register the listener with the telephony manager
mManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS |
PhoneStateListener.LISTEN_CELL_LOCATION);
}
// Listener for signal strength.
final PhoneStateListener mListener = new PhoneStateListener()
{
#Override
public void onCellLocationChanged(CellLocation mLocation)
{
if (mDone) return;
Log.d(TAG, "Cell location obtained.");
mCellLocation = mLocation;
update();
}
#Override
public void onSignalStrengthsChanged(SignalStrength sStrength)
{
if (mDone) return;
Log.d(TAG, "Signal strength obtained.");
mSignalStrength = sStrength;
update();
}
};
// AsyncTask to avoid an ANR.
private class ReflectionTask extends AsyncTask<Void, Void, Void>
{
protected Void doInBackground(Void... mVoid)
{
mTextStr =
("DEVICE INFO\n\n" + "SDK: `" + Build.VERSION.SDK_INT + "`\nCODENAME: `" +
Build.VERSION.CODENAME + "`\nRELEASE: `" + Build.VERSION.RELEASE +
"`\nDevice: `" + Build.DEVICE + "`\nHARDWARE: `" + Build.HARDWARE +
"`\nMANUFACTURER: `" + Build.MANUFACTURER + "`\nMODEL: `" + Build.MODEL +
"`\nPRODUCT: `" + Build.PRODUCT + ((getRadio() == null) ? "" : ("`\nRADIO: `" + getRadio())) +
"`\nBRAND: `" + Build.BRAND + ((Build.VERSION.SDK_INT >= 8) ? ("`\nBOOTLOADER: `" + Build.BOOTLOADER) : "") +
"`\nBOARD: `" + Build.BOARD + "`\nID: `"+ Build.ID + "`\n\n" +
ReflectionUtils.dumpClass(SignalStrength.class, mSignalStrength) + "\n" +
ReflectionUtils.dumpClass(mCellLocation.getClass(), mCellLocation) + "\n" + getWimaxDump() +
ReflectionUtils.dumpClass(TelephonyManager.class, mManager) +
ReflectionUtils.dumpStaticFields(Context.class, getApplicationContext()));
return null;
}
protected void onProgressUpdate(Void... progress)
{
// Do nothing...
}
protected void onPostExecute(Void result)
{
complete();
}
}
private final void complete()
{
mDone = true;
try
{
mText.setText(mTextStr);
// Stop listening.
mManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
Toast.makeText(getApplicationContext(), R.string.done, Toast.LENGTH_SHORT).show();
mSubmit.setEnabled(true);
}
catch (Exception e)
{
Log.e(TAG, "ERROR!!!", e);
}
}
private final void update()
{
if (mSignalStrength == null || mCellLocation == null) return;
final ReflectionTask mTask = new ReflectionTask();
mTask.execute();
}
/**
* #return The Radio of the {#link Build} if available.
*/
public static final String getRadio()
{
if (Build.VERSION.SDK_INT >= 8 && Build.VERSION.SDK_INT < 14)
return Build.RADIO;
else if (Build.VERSION.SDK_INT >= 14)
return Build.getRadioVersion();
else
return null;
}
private static final String[] mServices =
{
"WiMax", "wimax", "wimax", "WIMAX", "WiMAX"
};
/**
* #return A String containing a dump of any/ all WiMax
* classes/ services loaded via {#link Context}.
*/
public final String getWimaxDump()
{
String mStr = "";
for (final String mService : mServices)
{
final Object mServiceObj = getApplicationContext()
.getSystemService(mService);
if (mServiceObj != null)
{
mStr += "getSystemService(" + mService + ")\n\n";
mStr += ReflectionUtils.dumpClass(mServiceObj.getClass(), mServiceObj);
}
}
return mStr;
}
/**
* Start an {#link Intent} chooser for the user to submit the results.
*/
public final void sendResults()
{
final Intent mIntent = new Intent(Intent.ACTION_SEND);
mIntent.setType("plain/text");
mIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { EMAIL });
mIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.results));
mIntent.putExtra(Intent.EXTRA_TEXT, mTextStr);
HomeActivity.this.startActivity(Intent.createChooser(mIntent, "Send results."));
}
}
ReflectionUtils.java
import java.lang.reflect.*;
import android.util.Log;
public final class ReflectionUtils
{
public static final String TAG = ReflectionUtils.class.getSimpleName();
/**
* Dumps a {#link Class}'s {#link Method}s and {#link Field}s
* as a String.
*/
public static final String dumpClass(Class<?> mClass, Object mInstance)
{
if (mClass == null || mInstance == null) return null;
String mStr = mClass.getSimpleName() + "\n\n";
mStr += "FIELDS\n\n";
final Field[] mFields = mClass.getDeclaredFields();
for (final Field mField : mFields)
{
mField.setAccessible(true);
mStr += mField.getName() + " (" + mField.getType() + ") = ";
try
{
mStr += mField.get(mInstance).toString();
}
catch (Exception e)
{
mStr += "null";
Log.e(TAG, "Could not get Field `" + mField.getName() + "`.", e);
}
mStr += "\n";
}
mStr += "METHODS\\nn";
// Dump all methods.
final Method[] mMethods = mClass.getMethods();
for (final Method mMethod : mMethods)
{
mMethod.setAccessible(true);
mStr += mMethod.getReturnType() + " " + mMethod.getName() + "() = ";
try
{
final Object mRet = mMethod.invoke(mInstance);
mStr += (mRet == null) ? "null" : mMethod.invoke(mInstance).toString();
}
catch (Exception e)
{
mStr += "null";
Log.e(TAG, "Could not get Method `" + mMethod.getName() + "`.", e);
}
mStr += "\n";
}
return mStr;
}
/**
* #return A string containing the values of all static {#link Field}s.
*/
public static final String dumpStaticFields(Class<?> mClass, Object mInstance)
{
if (mClass == null || mInstance == null) return null;
String mStr = mClass.getSimpleName() + "\n\n";
mStr += "STATIC FIELDS\n\n";
final Field[] mFields = mClass.getDeclaredFields();
for (final Field mField : mFields)
{
if (ReflectionUtils.isStatic(mField))
{
mField.setAccessible(true);
mStr += mField.getName() + " (" + mField.getType() + ") = ";
try
{
mStr += mField.get(mInstance).toString();
}
catch (Exception e)
{
mStr += "null";
Log.e(TAG, "Could not get Field `" + mField.getName() + "`.", e);
}
mStr += "\n";
}
}
return mStr;
}
/**
* #return True if the {#link Field} is static.
*/
public final static boolean isStatic(Field field)
{
final int modifiers = field.getModifiers();
return (Modifier.isStatic(modifiers));
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#android:color/black"
android:padding="8dp"
android:id="#+id/root">
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="56dp"
android:fillViewport="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/text"
android:textColor="#android:color/white" />
</LinearLayout>
</ScrollView>
<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:stretchColumns="0,1">
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/cancel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/cancel"
android:textColor="#android:color/white"/>
<Button
android:id="#+id/submit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/submit"
android:textColor="#android:color/white"/>
</TableRow>
</TableLayout>
</RelativeLayout>
do not forget to use following features and permissions
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
<uses-feature android:name="android.hardware.location" android:required="false" />
<uses-feature android:name="android.hardware.location.network" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-feature android:name="android.hardware.telephony" android:required="false" />
<uses-permission android:name="android.permission.ACCESS_WIMAX_STATE" android:required="false" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" android:required="false" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:required="false" />
Okay, I read a lot and thought I had this worked out but apparently not. What I'm trying to do is check to see if a file exists (in this case heapFile.csv) and if it doesn't to create it and then write a string to it. If the file does exist, then I want to append the string to the file. I get no errors when I run this though I do get a warning saying that it can't create the file although it actually does do so. However it's not writing the string to the file in either case. I'm probably just not using the right syntax or something but after staring at this for weeks I can't see the forest for the trees and find the problem. Aside from this one issue my program is working fine and if I can just get this working I can FINALLY finish this. Any help is incredibly appreciated.
Here's the java file. I think it's clear where the file creation/writing bit is.
package com.loch.meaptracker;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import com.google.ads.*;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TimePicker;
public class MainActivity extends Activity implements OnSeekBarChangeListener {
private SeekBar happyBar, energyBar, anxietyBar, painBar;
private EditText noteField;
private DatePicker dPick;
private TimePicker tPick;
#SuppressWarnings("unused")
private Button enterButton;
private int happyValue = 4, energyValue = 4, anxietyValue = 4,
painValue = 4;
private static final String TAG = "heapApp";
private String Mood = "Blah";
private AdView adView;
final Context context = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create the adView
adView = new AdView (this, AdSize.BANNER, "a15138b1a7adad2");
// Lookup your RelativeLayout assuming it's been given the attribute android:id="#+id/AdRelativeLayout
RelativeLayout layout = (RelativeLayout)findViewById(R.id.AdRelativeLayout);
// Add the AdView to it
layout.addView(adView);
// Initiate a generic request to load it with an ad
adView.loadAd(new AdRequest());
// bars
happyBar = (SeekBar) findViewById(R.id.happinessBarID);
happyBar.setOnSeekBarChangeListener(this);
energyBar = (SeekBar) findViewById(R.id.energyBarID);
energyBar.setOnSeekBarChangeListener(this);
anxietyBar = (SeekBar) findViewById(R.id.anxietyBarID);
anxietyBar.setOnSeekBarChangeListener(this);
painBar = (SeekBar) findViewById(R.id.painBarID);
painBar.setOnSeekBarChangeListener(this);
// end bars
dPick = (DatePicker) findViewById(R.id.datePicker1);
tPick = (TimePicker) findViewById(R.id.timePicker1);
noteField = (EditText) findViewById(R.id.noteTextFieldID);
enterButton = (Button) findViewById(R.id.enterButtonID);
} catch (Exception onCreateException) {
Log.e(TAG, "Exception received", onCreateException);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
// Bar listener methods
#Override
public void onProgressChanged(SeekBar arg0, int barValue, boolean hFromUser) {
try {
switch (arg0.getId()) {
case R.id.happinessBarID:
happyValue = barValue + 1;
break;
case R.id.energyBarID:
energyValue = barValue + 1;
break;
case R.id.anxietyBarID:
anxietyValue = barValue + 1;
break;
case R.id.painBarID:
painValue = barValue + 1;
break;
}
String debugBarValue = "Happy is " + happyValue + ", Energy is "
+ energyValue + ", Anxiety is " + anxietyValue
+ ", Pain is " + painValue + ".";
System.out.println(debugBarValue);
} catch (Exception BarValueException) {
Log.e(TAG, "Exception received", BarValueException);
}
}
#Override
public void onStartTrackingTouch(SeekBar happyBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar happyBar) {
// TODO Auto-generated method stub
}
// end Bar listener methods
// Enter Button listener Method
public void dialogPop(View v) {
try {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
context);
// set Title
alertDialogBuilder.setTitle("title");
// set dialog message
alertDialogBuilder.setMessage("You entered: " + getMood())
.setCancelable(false).setPositiveButton("Okay",
// When Okay button clicked the write mood string to file
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
try {
// This is the string that should be
// written to file
String data = getMood();
// This is the file that should be
// written to
File heapFile = new File(Environment.getExternalStorageDirectory(), "heapFile.csv");
// if file doesn't exists, then create
// it
if (!heapFile.exists()) {
heapFile.createNewFile();
FileWriter heapFileWritter = new FileWriter(
heapFile.getName(), true);
BufferedWriter heapBufferWritter = new BufferedWriter(
heapFileWritter);
heapBufferWritter.write(data);
heapBufferWritter.close();
System.out.println("Done");
}
// true = append file
FileWriter heapFileWritter = new FileWriter(
heapFile.getName(), true);
BufferedWriter heapBufferWritter = new BufferedWriter(
heapFileWritter);
heapBufferWritter.write(data);
heapBufferWritter.close();
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
}
}
})
// If they press either the cancel button or the back button
// on their device (Same thing) then close the dialog and
// give the user a chance to change what they've entered
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int id) {
// TODO Auto-generated method stub
dialog.cancel();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
} catch (Exception buttonListenerException) {
Log.e(TAG, "Exception received", buttonListenerException);
}
return;
}
public String getMood() {
try {
int month = dPick.getMonth();
int day = dPick.getDayOfMonth();
int year = dPick.getYear();
int minute = tPick.getCurrentMinute();
String moodAntePost = "AM";
boolean hourType = tPick.is24HourView();
int moodHour = tPick.getCurrentHour();
if (hourType == false && moodHour > 12) {
moodHour = (moodHour - 12);
moodAntePost = "PM";
} else if (hourType == false && moodHour <= 0) {
moodHour = 12;
} else {
}
String noteText = noteField.getText().toString();
Mood = "Happiness," + happyValue + ",Energy," + energyValue
+ ",Anxiety," + anxietyValue + ",Pain," + painValue
+ ",Date," + month + "/" + day + "/" + year + ",Time,"
+ moodHour + ":" + minute + "," + moodAntePost + ",Note,"
+ noteText;
System.out.println(Mood);
} catch (Exception getMoodException) {
Log.e(TAG, "Exception received", getMoodException);
}
return Mood;
}
}
Edited my question to include the manifest so you can see the permissions I've got. I think it's right but I'm not certain...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.loch.meaptracker"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.loch.meaptracker.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>
<activity android:name="com.google.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
</application>
</manifest>
use this:
String file = heapFile.getAbsolutePath();
FileWriter heapFileWritter = new FileWriter(file, true);
getName() would give you just the name of the file. But you need to provide absolutepath for FileWriter.
First off I wanted to thank everyone for the help I've gotten on my last few questions. I've searched and done my best to figure out my latest problem but I've had no luck even after searching here. I'm trying to check to see if "heapFile.csv" exists and if it doesn't, to create the file and then write a string to it. If it does then I just want to append a string to it instead. I think what I have will do that but I keep getting an IOException along with it saying the file system is Read Only. I do have the manifest file changed to include accessing the sdcard and even used the android too to make a virtual sdcard in case that was the problem.
First here's the main activity java...
package com.loch.meaptracker;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TimePicker;
public class MainActivity extends Activity implements OnSeekBarChangeListener {
private SeekBar happyBar, energyBar, anxietyBar, painBar;
private EditText noteField;
private DatePicker dPick;
private TimePicker tPick;
#SuppressWarnings("unused")
private Button enterButton;
private int happyValue = 4, energyValue = 4, anxietyValue = 4,
painValue = 4;
private static final String TAG = "heapApp";
private String Mood = "Blah";
final Context context = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// bars
happyBar = (SeekBar) findViewById(R.id.happinessBarID);
happyBar.setOnSeekBarChangeListener(this);
energyBar = (SeekBar) findViewById(R.id.energyBarID);
energyBar.setOnSeekBarChangeListener(this);
anxietyBar = (SeekBar) findViewById(R.id.anxietyBarID);
anxietyBar.setOnSeekBarChangeListener(this);
painBar = (SeekBar) findViewById(R.id.painBarID);
painBar.setOnSeekBarChangeListener(this);
// end bars
dPick = (DatePicker) findViewById(R.id.datePicker1);
tPick = (TimePicker) findViewById(R.id.timePicker1);
noteField = (EditText) findViewById(R.id.noteTextFieldID);
enterButton = (Button) findViewById(R.id.enterButtonID);
} catch (Exception onCreateException) {
Log.e(TAG, "Exception received", onCreateException);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
// Bar listener methods
#Override
public void onProgressChanged(SeekBar arg0, int barValue, boolean hFromUser) {
try {
switch (arg0.getId()) {
case R.id.happinessBarID:
happyValue = barValue + 1;
break;
case R.id.energyBarID:
energyValue = barValue + 1;
break;
case R.id.anxietyBarID:
anxietyValue = barValue + 1;
break;
case R.id.painBarID:
painValue = barValue + 1;
break;
}
String debugBarValue = "Happy is " + happyValue + ", Energy is "
+ energyValue + ", Anxiety is " + anxietyValue
+ ", Pain is " + painValue + ".";
System.out.println(debugBarValue);
} catch (Exception BarValueException) {
Log.e(TAG, "Exception received", BarValueException);
}
}
#Override
public void onStartTrackingTouch(SeekBar happyBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar happyBar) {
// TODO Auto-generated method stub
}
// end Bar listener methods
// Enter Button listener Method
public void dialogPop(View v) {
try {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
context);
// set Title
alertDialogBuilder.setTitle("title");
// set dialog message
alertDialogBuilder.setMessage("You entered: " + getMood())
.setCancelable(false).setPositiveButton("Okay",
// When Okay button clicked the write mood string to file
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
try {
// This is the string that should be
// written to file
String data = getMood();
// This is the file that should be
// written to
File heapFile = new File(Environment.getExternalStorageDirectory(), "/heapFile.csv");
// if file doesn't exists, then create
// it
if (!heapFile.exists()) {
heapFile.createNewFile();
}
// true = append file
FileWriter heapFileWritter = new FileWriter(
heapFile.getName(), true);
BufferedWriter heapBufferWritter = new BufferedWriter(
heapFileWritter);
heapBufferWritter.write(data);
heapBufferWritter.close();
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
}
}
})
// If they press either the cancel button or the back button
// on their device (Same thing) then close the dialog and
// give the user a chance to change what they've entered
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int id) {
// TODO Auto-generated method stub
dialog.cancel();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
} catch (Exception buttonListenerException) {
Log.e(TAG, "Exception received", buttonListenerException);
}
return;
}
public String getMood() {
try {
int month = dPick.getMonth();
int day = dPick.getDayOfMonth();
int year = dPick.getYear();
int minute = tPick.getCurrentMinute();
String moodAntePost = "AM";
boolean hourType = tPick.is24HourView();
int moodHour = tPick.getCurrentHour();
if (hourType == false && moodHour > 12) {
moodHour = (moodHour - 12);
moodAntePost = "PM";
} else if (hourType == false && moodHour <= 0) {
moodHour = 12;
} else {
}
String noteText = noteField.getText().toString();
Mood = "Happiness," + happyValue + ",Energy," + energyValue
+ ",Anxiety," + anxietyValue + ",Pain," + painValue
+ ",Date," + month + "/" + day + "/" + year + ",Time,"
+ moodHour + ":" + minute + "," + moodAntePost + ",Note,"
+ noteText;
System.out.println(Mood);
} catch (Exception getMoodException) {
Log.e(TAG, "Exception received", getMoodException);
}
return Mood;
}
}
And the Manifest...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.loch.meaptracker"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<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.loch.meaptracker.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>
I think problem is in this line:
FileWriter heapFileWritter = new FileWriter(
heapFile.getName(), true);
instead try this:
FileWriter heapFileWritter = new FileWriter(
heapFile, true);
explanation:
heapFile.getName() refers to your file name so lets say heapFile.txt.
so when you ask FileWriter to write to this file. It doesn't know which file you are referring to. So it try to create the file. But wait! where it will create the file, as it has only the file name, not the complete path.
So even I am sure where it would think of creating the file, my guess is Root( I am not sure). Which is read-only hence the error.
public FileWriter(String fileName,
boolean append)
throws IOException
IOException - if the named file exists but is a directory rather than
a regular file, does not exist but cannot be created, or cannot be
opened for any other reason