Yesterday I was looking into a way to acquire the call log of an android device.
My idea was to acquire everything posible and then parse it and get only what I really needed.
Following the documentation See CallLog.Calls Documentation I saw the different fields there are but when trying to get them I got erros caused by differences in the documentation.
Finally I got it to work so I wanted to share the code in case anyone else needs it.
In the code I use JSON objects and save them in the Documents folder.
private void getCallLog(Context context) {
#SuppressLint("MissingPermission") Cursor cursor = getApplicationContext().getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null,
null, CallLog.Calls.DATE + " DESC");
if (cursor.getCount() > 0) {
try{
// Get the directory for the user's public pictures directory.
final File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
// Make sure the path directory exists.
if (!path.exists()) {
// Make it, if it doesn't exit
path.mkdirs();
}
final File file = new File(path, "call.txt");
file.createNewFile();
FileOutputStream fOut = new FileOutputStream(file);
OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
while (cursor.moveToNext()) {
try {
JSONObject object = new JSONObject();
object.put("ANSWERED_EXTERNALLY_TYPE", CallLog.Calls.ANSWERED_EXTERNALLY_TYPE);
object.put("BLOCKED_TYPE", CallLog.Calls.BLOCKED_TYPE);
object.put("CACHED_FORMATTED_NUMBER", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_FORMATTED_NUMBER)));
object.put("CACHED_LOOKUP_URI", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_LOOKUP_URI)));
object.put("CACHED_MATCHED_NUMBER", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_MATCHED_NUMBER)));
object.put("CACHED_NAME", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME)));
object.put("CACHED_NORMALIZED_NUMBER", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NORMALIZED_NUMBER)));
object.put("CACHED_NUMBER_LABEL", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NUMBER_LABEL)));
object.put("CACHED_NUMBER_TYPE", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NUMBER_TYPE)));
object.put("CACHED_PHOTO_ID", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_PHOTO_ID)));
object.put("CACHED_PHOTO_URI", CallLog.Calls.CACHED_PHOTO_URI); // Wrong docs
object.put("CONTENT_ITEM_TYPE", CallLog.Calls.CONTENT_ITEM_TYPE); // Wrong docs
object.put("CONTENT_TYPE", CallLog.Calls.CONTENT_TYPE); // Wrong docs
object.put("COUNTRY_ISO", cursor.getString(cursor.getColumnIndex(CallLog.Calls.COUNTRY_ISO)));
object.put("DATA_USAGE", cursor.getString(cursor.getColumnIndex(CallLog.Calls.DATA_USAGE)));
object.put("DATE", cursor.getString(cursor.getColumnIndex(CallLog.Calls.DATE)));
object.put("DEFAULT_SORT_ORDER", CallLog.Calls.DEFAULT_SORT_ORDER); // Wrong docs
object.put("DURATION", cursor.getString(cursor.getColumnIndex(CallLog.Calls.DURATION)));
object.put("EXTRA_CALL_TYPE_FILTER", CallLog.Calls.EXTRA_CALL_TYPE_FILTER); // Wrong docs
object.put("FEATURES", cursor.getString(cursor.getColumnIndex(CallLog.Calls.FEATURES)));
object.put("FEATURES_HD_CALL", CallLog.Calls.FEATURES_HD_CALL);
object.put("FEATURES_PULLED_EXTERNALLY", CallLog.Calls.FEATURES_PULLED_EXTERNALLY);
object.put("FEATURES_VIDEO", CallLog.Calls.FEATURES_VIDEO);
object.put("FEATURES_WIFI", CallLog.Calls.FEATURES_WIFI);
object.put("GEOCODED_LOCATION", cursor.getString(cursor.getColumnIndex(CallLog.Calls.GEOCODED_LOCATION)));
object.put("INCOMING_TYPE", CallLog.Calls.INCOMING_TYPE);
object.put("IS_READ", cursor.getString(cursor.getColumnIndex(CallLog.Calls.IS_READ)));
object.put("LAST_MODIFIED", CallLog.Calls.LAST_MODIFIED); // Wrong docs
object.put("LIMIT_PARAM_KEY", CallLog.Calls.LIMIT_PARAM_KEY); // Wrong docs
object.put("MISSED_TYPE", CallLog.Calls.MISSED_TYPE);
object.put("NEW", cursor.getString(cursor.getColumnIndex(CallLog.Calls.NEW)));
object.put("NUMBER", cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER)));
object.put("NUMBER_PRESENTATION", cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER_PRESENTATION)));
object.put("OFFSET_PARAM_KEY", CallLog.Calls.OFFSET_PARAM_KEY); // Wrong docs
object.put("OUTGOING_TYPE", CallLog.Calls.OUTGOING_TYPE);
object.put("PHONE_ACCOUNT_COMPONENT_NAME", cursor.getString(cursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_COMPONENT_NAME)));
object.put("PHONE_ACCOUNT_ID", cursor.getString(cursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID)));
object.put("POST_DIAL_DIGITS", CallLog.Calls.POST_DIAL_DIGITS); // Wrong docs
object.put("PRESENTATION_ALLOWED", CallLog.Calls.PRESENTATION_ALLOWED);
object.put("PRESENTATION_PAYPHONE", CallLog.Calls.PRESENTATION_PAYPHONE);
object.put("PRESENTATION_RESTRICTED", CallLog.Calls.PRESENTATION_RESTRICTED);
object.put("PRESENTATION_UNKNOWN", CallLog.Calls.PRESENTATION_UNKNOWN);
object.put("REJECTED_TYPE", CallLog.Calls.REJECTED_TYPE);
object.put("TRANSCRIPTION", cursor.getString(cursor.getColumnIndex(CallLog.Calls.TRANSCRIPTION)));
object.put("TYPE", cursor.getString(cursor.getColumnIndex(CallLog.Calls.TYPE)));
object.put("VIA_NUMBER", CallLog.Calls.VIA_NUMBER); // Wrong docs
object.put("VOICEMAIL_TYPE", CallLog.Calls.VOICEMAIL_TYPE); // Wrong docs
object.put("VOICEMAIL_URI", cursor.getString(cursor.getColumnIndex(CallLog.Calls.VOICEMAIL_URI)));
myOutWriter.append(object.toString());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
myOutWriter.close();
fOut.flush();
fOut.close();
} catch (Exception e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
}
Related
I'm working on an app which stores small amounts of data in /data/data/my_app/files using this code:
private void buildFileFromPreset(String fileName) {
fileName = fileName.toLowerCase();
StandardData data = StandardData.getInstance();
String[] list = data.getDataByName(fileName);
FileOutputStream fos = null;
try {
fos = openFileOutput(fileName, Context.MODE_PRIVATE);
PrintWriter writer = new PrintWriter(fos);
for (int i = 0; i < list.length; i++) {
writer.println(list[i]);
}
writer.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
All works fine when the app gets started, in the onCreate() function of the main activity, I want to check if the files that were created last time are still present:
private String getAppFilesDir() {
ContextWrapper c = new ContextWrapper(this);
return c.getFilesDir().toString();
}
which returns something like:
/data/user/0/my_app/files
I've read some older posts (2012) suggesting this method must work but it doesn't, probably since jellybean.
So my question:
How can I check if the files I created using FileOutputStream and PrintWriter in a previous session still exist?
I hope I provided enough info for you guys to answer (:
I still have not found a solution for this specific problem.
Instead I am now using SQLite so I don't have to worry about these kinds of things.
I've been working with Azure on the Android OS and I managed to upload my video file (.mp4) to a Container I had already prepared for it.
I did this by getting a Shared Access Signature (SAS) first, which provided me with:
a temporary key
the name of the container to where I want to send the files
the server URI
Then, I started an AsyncTask to send the file to the container using the "upload".
I checked the container, and the file gets uploaded perfectly, no problems on that end.
My question is regarding the progress of the upload. Is it possible to track it? I would like to have an upload bar to give a better UX.
P.S - I'm using the Azure Mobile SDK
Here's my code:
private void uploadFile(String filename){
mFileTransferInProgress = true;
try {
Log.d("Funky Stuff", "Blob Azure Config");
final String gFilename = filename;
File file = new File(filename); // File path
String blobUri = blobServerURL + sharedAccessSignature.replaceAll("\"", "");
StorageUri storage = new StorageUri(URI.create(blobUri));
CloudBlobClient blobCLient = new CloudBlobClient(storage);
//Container name here
CloudBlobContainer container = blobCLient.getContainerReference(blobContainer);
blob = container.getBlockBlobReference(file.getName());
//fileToByteConverter is a method to convert files to a byte[]
byte[] buffer = fileToByteConverter(file);
ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer);
if (blob != null) {
new UploadFileToAzure().execute(inputStream);
}
} catch (StorageException e) {
Log.d("Funky Stuff", "StorageException: " + e.toString());
e.printStackTrace();
} catch (IOException e) {
Log.d("Funky Stuff", "IOException: " + e.toString());
e.printStackTrace();
} catch (Exception e) {
Log.d("Funky Stuff", "Exception: " + e.toString());
e.printStackTrace();
}
mFileTransferInProgress = false;
//TODO: Missing ProgressChanged method from AWS
}
private class UploadFileToAzure extends
AsyncTask <ByteArrayInputStream, Void, Void>
{
#Override
protected Void doInBackground(ByteArrayInputStream... params) {
try {
Log.d("Funky Stuff", "Entered UploadFileToAzure Async" + uploadEvent.mFilename);
//Method to upload, takes an InputStream and a size
blob.upload(params[0], params[0].available());
params[0].close();
} catch (StorageException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Thanks!
You can split your file and send its part using Block, there is a good example of your case in this link but it used C# so you should find the corresponding function in the android library reference.
Basically instead of sending you file as one big file, you split it to multiple files (bytes) and send it to azure so you can track the progress on how many bytes that already sent to azure
In this portion of my app, I have a database which is absorbing data from my light sensor. It has a RowID associated with each row.
In the background I have an AsyncTaskRunner which is reading that table and writing each row to a CSV file. It should loop through the entire table as data is being written to it, looking for all rows for the current TID that have not been copied to CSV. THen it should write the row values to CSV and go back and mark the row as copied.
THe first loop should come in where no it goes back to the database cursor and looks for the next row which has not been copied to the CSV file. After each copy to CSV it should evaluate the size of that CSV file to make sure it is not full. If not Full then should go back to the Database cursor and look for the next row to write to the CSV file. If isfull then it should loop back to LoopMain and start over creating a new CSV file to write to.
While the full method is not complete yet, I am at the part where the row data is suposed to be written to the CSV file. At the moment, it does not write to it. Before I made this method a For Loop, it did, now it does not. I can not figure out what has changed. I have inserted all of these Log comments to follow the method as it passes values, receives values and then does an action to see where it is failing. THe method passes the section where it is to write to the CSV file and continues on, but the file is empty.
public void lightloop(){
//Loop Main
int loopcounter;
LoopMain: for(loopcounter = 0; loopcounter < 4; loopcounter++ ){
Log.d(CSV, "lightloop loopcounter = " + loopcounter);
String CSVFinalFileName=createlightcsv();
Log.w(CSV, "LightLoop, CSVFinalFileName = " + CSVFinalFileName);
//Loop 2
Loop2: for(int useless=1; useless > 0; useless++ ){
String flightRowId = evaluateLightTable(filenamePrefix); //returns the rowid of the first line not transmitted
Log.w(CSV, "LightLoop, flightRowId = " + flightRowId);
Log.d(CSV, "filefullBoolean " + useless);
if(flightRowId != null){
Log.w(CSV, "LightLoop flightRowId is NOT NULL");
//write row to csv
//Get all row values and put into a string
String lightRowValues=fetchLightRowData(flightRowId, filenamePrefix);
Log.w(CSV, "lightLoop, lightRowValues are " + lightRowValues);
//Append that data to the CSV file
Log.w(CSV, "Opening File Output Stream");
try {
FileOutputStream csvfos = mContext.openFileOutput(CSVFinalFileName, Context.MODE_PRIVATE);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
OutputStreamWriter sensorCSVWriter = new OutputStreamWriter(csvfos);
try {
sensorCSVWriter.append("LIGHT " + lightRowValues);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/** try {
sensorCSVWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} **/
//mark row as transmitted
SQLDatabase updatelightrow = new SQLDatabase(mContext);
updatelightrow.open();
SQLDatabase.updateLightRow(flightRowId);
updatelightrow.close();
}// end If rowid is not null
//evaluate size of csv
Boolean filefull = CsvStreamer.checkFileSize(CSVFinalFileName);
if(!filefull){
//return to cursor
Log.d(CSV, "lightloop, File is NOT full");
break Loop2;
}else{
Log.d(CSV, "lightloop, File IS full");
//file is full. close it,
//transmit it,
//open a new one
//goto CSV table and mark it transmitted
break LoopMain;
}
}//end Loop2
}//end LoopMain
}
Can anyone see why this is failing to write to the File?
The csvfos is not in the same scope. I assume the class has a property called csvfos also, hence the method is accessing the property and not the csvfos variable created in the try catch.
Try changing
try
{
FileOutputStream csvfos = mContext.openFileOutput(CSVFinalFileName, Context.MODE_PRIVATE);
}
catch (FileNotFoundException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
to
FileOutputStream csvfos = null;
try
{
csvfos = mContext.openFileOutput(CSVFinalFileName, Context.MODE_PRIVATE);
}
catch (FileNotFoundException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
I'm trying to write a json file using android like this:
String jsonString = broadcastDataArray.toString();
Writer output = null;
File fileAnnouncement = new File("announcement.json");
try {
output = new BufferedWriter(new FileWriter(fileAnnouncement));
output.write(jsonString);
output.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
and now i'm trying to load/read the file using phonegap. Using this method shown here, i am able to read a file that was included in my application source. But i want to read some file that was generated by the android code.
Is there anyway to do this? Is there any specific directory where the file could be accessed from Java android and Phonegap/Sencha ?
Any kind of help or pointer is appreciated. Thanks.
You can do this in following way.
Write this function in your Android activity to write data in text file.
public void WriteDataToFile(String sFileName, String sBody){
try
{
FileWriter f = new FileWriter("/sdcard/data.txt");
f.append(sBody);
f.flush();
f.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
And, now you can read that file from your Sencha/Phonegap app by calling this function.
var user_data = function(){
var request = new XMLHttpRequest();
request.open("GET", "/sdcard/data.txt");
request.onreadystatechange = function() {
if (request.readyState == 4) {
// alert("*" + request.responseText + "*");
data = request.responseText;
}
}
request.send();
}
I am trying to create a file ,if it doesnot exist and tried to write some data to it. The same program I did in java, it was running fine.But when I try to do the same thing in Android I am getting NullPointerException at the place where I am trying to write data to file. And also, I did not find any new file in the current directory .I will share the code here:
xmlpoc.java
public class xmlPoc extends Activity {
String s="<employee>"+
"<details>"+
"<pictag id="+
"\"#drawable/icon\"" +
"mystr"+
"="+
"\"Picture 1\"" +
"myint" +
" =" +
"\"33\"" +
"/>"+
" <name>SandeepKumarSuman</name>"+
"<designation>J2ME Programmer</designation>"+
"<city>Gorakhpur</city>"+
"<state>UP</state>"+
"<name>mohan</name>"+
"<designation>J2ME GAMEProgrammer</designation>"+
"<city>HYD</city>"+
"<state>AP</state>"+
"<name>hari</name>"+
"<designation>Fresher</designation>"+
"<city>GNT</city>"+
"<state>AP</state>"+
"</details>"+
"</employee>";
File f;
FileOutputStream fop;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
f=new File("./myfile1.txt");
try {
fop=new FileOutputStream(f);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(!f.exists()){
try {
f.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("New file myfile.txt has been created to the current directory");
}
try {
fop.write(s.getBytes());
fop.flush();
fop.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Can anyone help me in sorting out this issue.
Thanks in Advance,
}
Check out the android dev guide here, and if you want to write to the external storage you should add the permissions to your manifest and use "getExternalStorageDirectory()", or "getExternalFilesDir()" if you are using API 8 or higher. You can't just write everywhere, that's why you need to use androids "openFileOutput(" or just write to the external storage.
External storage permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Try f=new File("myfile1.txt");