I am very new into the android development.
In this project, I am trying to create a JSON objects and then want to write that JSON object into a file in SD card but I am getting the following exception:
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/avinash1.json: open failed: EACCES (Permission denied)
Though I have even added the user-permission in the manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.raviteja.youexample">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<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">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
package com.example.raviteja.youexample;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
JSONObject obj = new JSONObject();
try {
obj.put("age", new Integer(100));
obj.put("name", "Ravi");
} catch (JSONException e) {
e.printStackTrace();
}
JSONArray list1 = new JSONArray();
JSONObject pnObj = new JSONObject();
try {
pnObj.put("num", "99009900");
pnObj.put("type", "mhgchmc");
list1.put(pnObj);
obj.put("phoneNumber", list1);
} catch (JSONException e) {
e.printStackTrace();
}
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File (root.getAbsolutePath());
dir.mkdirs();
File file = new File(dir, "avinash1.json");
try {
FileOutputStream f = new FileOutputStream(file);
PrintWriter pw = new PrintWriter(f);
pw.println(obj.toString());
pw.flush();
pw.close();
f.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
You should maybe try to get the public directory with the command: getExternalStoragePublicDirectory(): android.os.Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
Although if you want to keep that info to yourself and not let any other apps touch it you should save it in your apps InteralStorage. Quick tutorial here: http://www.tutorialspoint.com/android/android_internal_storage.htm
Updating my Answer
use this method , it should work :
private void saveJson() {
File root = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
if(!root.exists())
{
root.mkdirs();
}
File file = new File(root, "avinash1.json");
try {
if (file.exists()) {file.delete ();}
FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(json.toString());
bw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
but be careful , whenever you call this , your file will be overwritten with new value , for escaping that , you should make unique name for your file , like including current date and time to your file name ...
Related
Below is my MainActivity and Manifest file. I am trying to implement a screenshot in my app which then gives the option to open the screenshot using other applications. When I click the button in the main activity nothing is happening. It keeps throwing java.io.FileNotFoundException like so
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/ScreenShooter/2021-02-19_07:45:59.jpg: open failed: ENOENT (No such file or directory)
Is there a way to solve this?
package com.levirs.example.screenshooter;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
screenshoot();
}
});
}
private void screenshoot() {
Date date = new Date();
CharSequence now = android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", date);
String filename = Environment.getExternalStorageDirectory() + "/ScreenShooter/" + now + ".jpg";
View root = getWindow().getDecorView();
root.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(root.getDrawingCache());
root.setDrawingCacheEnabled(false);
File file = new File(filename);
file.getParentFile().mkdirs();
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
Uri uri = Uri.fromFile(file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "image/*");
startActivity(intent);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.levirs.example.screenshooter">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_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>
</application>
</manifest>
its seems like you are access the directory which not exist make sure its exist if you are using default screenshots folder then replace this line
Environment.getExternalStorageDirectory() + "/ScreenShooter/" + now + ".jpg";
to
Environment.getExternalStorageDirectory() + "/Pictures/Screenshots/" + now + ".jpg";
but this getExternalStorageDirectory is depricated now so use this one
getFilesDir()+ "/Pictures/Screenshots/" + now + ".jpg";
You're trying to instance a file on a path only via string which represents path+fileName.
Instead you should instance a new File with path separated from the fileName.
A similar problem
I am trying to write an app for android but am not able to connect to the website. the website is
here. I am able to connect to the website in Firefox and chrome. I wrote a simple program in java SE and it is able to connect to the website. here is the code.
import java.net.*;
import java.io.*;
public class urltest {
public static void main( String[] args ) throws Exception {
URL url = new URL ( "https://alerts.weather.gov/cap/mn.php?x=0" );
BufferedReader reader = new BufferedReader( new InputStreamReader( url.openStream() ) );
String line;
while ( ( line = reader.readLine() ) != null )
System.out.println( line );
reader.close();
}
}
This program does work and does connect to the website. the android app however does not. here is the manifest file.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ledorianindustries.rss2">
<uses-permission android:name="android.permission.INTERNET"/>
<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/Theme.Rss2">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
and here is the MainActivity.
package com.ledorianindustries.rss2;
import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new rss().execute();
}
public class rss extends AsyncTask<Integer, Void, Exception> {
#Override
protected Exception doInBackground(Integer... integers) {
try {
URL url = new URL("https://alerts.weather.gov/cap/mn.php?x=0");
BufferedReader reader = new BufferedReader( new InputStreamReader( url.openStream() ) );
String line;
while ((line = reader.readLine()) != null) {
Log.e("info", line);
}
reader.close();
} catch (IOException e) {
Log.e("info", e.toString());
}
return null;
}
}
}
for reasons that I cannot identify I am presented with the error:
2021-02-16 12:19:59.363 13978-14006/com.ledorianindustries.rss2 E/info: java.io.FileNotFoundException: https://alerts.weather.gov/cap/mn.php?x=0
I have checked to see if google is using their own implementation of the networking stack and as far as I can tell they have not. So then why does it work in java SE but not in android? I would appreciate some help on this matter.
***edit 1
the code for URLConnection will follow.
URL url = new URL("https://alerts.weather.gov/cap/mn.php?x=0");
//BufferedReader reader = new BufferedReader( new InputStreamReader( url.openStream() ) );
URLConnection uc = url.openConnection();
BufferedReader reader = new BufferedReader( new InputStreamReader( uc.getInputStream() ) );
String line;
while ((line = reader.readLine()) != null) {
Log.e("info", line);
}
reader.close();
the error code is:
2021-02-16 14:12:28.132 14638-14698/com.ledorianindustries.rss2 E/info: java.io.FileNotFoundException: https://alerts.weather.gov/cap/mn.php?x=0
***edit2
I have tried a few other urls:
URL url1 = new URL("https://alerts.weather.gov/cap/mn.php?x=0");
URL url2 = new URL("https://www.rediff.com/rss/moviesreviewsrss.xml");
URL url3 = new URL("https://www.cinemablend.com/rss_review.php");
url1 is the original url. url2 and url3 work. I am starting to think the "?x=0" may be the problem? I don't know much about php but is that maybe the issue? can php be rewritten? I tried to remove that part in my browser, it was very unhappy.
I am building a mobile app for my project on which I have to retrieve data sent to Thingspeak on it.
When I tap on an image button, it should open a new activity which will show its last value retrieved from Thingspeak.
The issue I am getting is that the app stops working when I click on an image button which is supposed to bring me to another activity. It does open a new activity showing that navigation to another activity is working but then it shows "Smart Agriculture has unfortunately stopped working". I think the problem is in the xml files of the activities or the TextView I have used in some TempHumidity.java file but I don't really know how to resolve them being an absolute beginner in Android Studio. I have 5 files namely activity_main.xml, MainActivity.java, TempHumidity.java, AndroidManifest.xml, imgbtnmenu.xml
TempHumidity.java class(it contains the HttpURLConnection codes)
public class TempHumidity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.imgbtnmenu);
new GetMethodDemo().execute("https://thingspeak.com/channels/357670/field/1/last");
}
public class GetMethodDemo extends AsyncTask<String , Void ,String> {
String server_response;
private TextView aTextView;
#Override
protected String doInBackground(String... strings) {
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(strings[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int responseCode = urlConnection.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK){
server_response = readStream(urlConnection.getInputStream());
Log.v("CatalogClient", server_response);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.e("Response", "" + server_response);
aTextView.setText(s);
}
}
// Converting InputStream to String
private String readStream(InputStream in) {
BufferedReader reader = null;
StringBuffer response = new StringBuffer();
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
response.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return response.toString();
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.teerna.smartagriculture">
<uses-permission android:name="android.permission.INTERNET" />
<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"
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=".TempHumidity"> // you need to add these 3 lines inside application tag.
</activity>
</application>
</manifest>
imgbtnmenu.xml for the new activity menu(the menu that opens when Humidity and Temperature image button is tapped)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
The messages on Logcat are as follows:
Most of the logcat is only warning, you can see the W/ character. The The app crashes because you're receiving a java.lang.VerifyError which is Could not find class 'android.graphics.drawable.RippleDrawable. This error will only happen on pre-lolipop device (Android 5.0)
Try add these line to build.gradle:
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
If it still not working, change app:srcCompat inside every ImageView to android:src
I have an application that I want to export the current SQLite database to the Internal storage Downloads folder of the device. I am getting the below error.
java.io.FileNotFoundException:
/storage/emulated/0/Download/Pipe_Tally: open failed: EACCES
(Permission denied)
I have what I think are the correct permissions included in the AndroidManifest.xml file for reading and writing to storage.
Here is the AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.bigdaddy.pipelinepipetally">
<uses-feature android:name="android.hardware.camera2"
android:required="true"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
<application
android:allowBackup="true"
android:debuggable="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme"
tools:ignore="HardcodedDebugMode">
<activity
android:name=".MainActivity"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".TallyActivity2"
android:windowSoftInputMode="adjustResize">
</activity>
<activity
android:name=".JobAndDbActivity"
android:windowSoftInputMode="adjustResize">
</activity>
<activity
android:name=".ExistingTallyActivity"
android:windowSoftInputMode="adjustResize">
</activity>
<activity android:name=".ImageToFullscreen"
android:windowSoftInputMode="adjustResize">
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.bigdaddy.pipelinepipetally.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths">
</meta-data>
</provider>
</application>
</manifest>
Here is the method I am trying to use to create the file for the /Downloads/ folder within the internal device storage:
public void backUpDatabase() {
/* Open your local db as the input stream */
DBHelper anotherDbHelper = null;
try {
try {
anotherDbHelper = new DBHelper(ExistingTallyActivity.this);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String path = null;
if (anotherDbHelper != null) {
path = String.valueOf(getApplicationContext().getDatabasePath(anotherDbHelper.getDatabaseName()));
Log.i(TAG, "backUpDatabase: 1" +path);
}
File dbFile = null;
if (path != null) {
dbFile = new File(path);
Log.i(TAG, "backUpDatabase: 2" + String.valueOf(dbFile));
}
FileInputStream fis = null;
try {
if (dbFile != null) {
fis = new FileInputStream(dbFile);
Log.i(TAG, "backUpDatabase: 3" + String.valueOf(dbFile));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String outFileName = (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()+ "/Pipe_Tally/");
Log.i(TAG, "backUpDatabase: 4"+ outFileName);
// Open the empty db as the output stream
OutputStream outputStream = null;
//FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(outFileName);
Log.i(TAG, "backUpDatabase: 5"+ outFileName);
Log.i(TAG, "backUpDatabase: 6"+ String.valueOf(outputStream));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// Transfer bytes from the input-file to the output-file
byte[] buffer = new byte[1024];
int length;
try {
if (fis != null) {
while ((length = fis.read(buffer)) > 0) {
try {
if (outputStream != null) {
outputStream.write(buffer, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
//Close the streams
try {
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Here is the method I am using to check for the correct permissions at Runtime:
private boolean checkSdCardPermissions() {
/* Checking here if we already have permissions*/
if (ActivityCompat.checkSelfPermission(ExistingTallyActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(ExistingTallyActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { /* Added this for Write External Storage permissions */
/* Checking to see if we are equal to or at a higher version than Marshmallow */
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
/* System default popup box here to ask for permissions. */
ActivityCompat.requestPermissions(ExistingTallyActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSION_READ_EXTERNAL_STORAGE);
/* Added this today for trying to prompt for writing external storage*/
ActivityCompat.requestPermissions(ExistingTallyActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSION_WRITE_EXTERNAL_STORAGE);
}
return true;
} else {
return false;
}
}
This is the onOptionsItemSelected() method that has the switch in it to handle the menu and what is selected. The case:R.id.menu_save_and_export:
is where I am checking if checkSdCardPermissions() method is true, then calling the backUpDatabase() method.
#Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
/*
When Tally New Pipe is selected from the Menu, it sends the user to the TallyActivity
page, all encapsulated in a runnable and passed to thread below.
*/
case R.id.menu_new_pipe:
class ToTallyActivityManager implements Runnable {
#Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
Intent intentToTallyActivity =
new Intent(ExistingTallyActivity.this, TallyActivity2.class);
startActivity(intentToTallyActivity); /* Heading to TallyActivity.*/
} /* run method ends here. */
} /* Runnable ends here. */
/* This thread takes care of the call to go to TallyActivity page from here.*/
mThreadToTallyActivity = new Thread(new ToTallyActivityManager());
mThreadToTallyActivity.start();
break;
/* When selected, sends the user to the MainActivity page. */
case R.id.menu_to_main:
Intent intentToMainActivity =
new Intent(ExistingTallyActivity.this, MainActivity.class);
startActivity(intentToMainActivity); // Heading to MainActivity
break;
/* When chosen allows the option to save and export the current DB.*/
case R.id.menu_save_and_export:
if (checkSdCardPermissions()) {
try {
backUpDatabase();
} catch (/*IOException*/ SQLException e) {
e.printStackTrace();
}
}
break;
/* When chosen from the menu, this kills the app completely. Has popup embedded.*/
default:
AlertHelperDialog.displayExitAlertDialog(ExistingTallyActivity.this);
} /* switch/case ends here */
return super.onOptionsItemSelected(menuItem);
} /* onOptionsItemSelected method ends here. */
I really appreciate any help or advice with fixing this issue. Thank you.
You have a android:maxSdkVersion="18" set on the WRITE_EXTERNAL_STORAGE permission. If you are running on a phone with SDK > 18 the app will not have permission to WRITE_EXTERNAL_STORAGE. So I suggest you remove the android:maxSdkVersion attribute. Read the documentation.
android:maxSdkVersion : The highest API level at which this permission should be granted to your app. Setting this attribute is useful if the permission your app requires is no longer needed beginning at a certain API level.
Change it as follows,
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I run my service (write logcat to file) on any emulators and real devices from 2.3.3 to 4.1. All OK.
On this devices generated right log:
--------- beginning of /dev/log/main
--------- beginning of /dev/log/system
I/ActivityManager( 3386): START {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000000 cmp=com.android.launcher/com.androWAcivtMaae( 36:IvldakgNme W/ActivityManager( 3386): Duplcaefns eus orcitRod45c6 o.vnotsolet.tiiyilg
I/ActivityManager( 3386): Displayed com.android.calculator2/.Calculator: +9s374ms<br>
.....
.....
But when I run service on 4.1.2 (samsung (google) Nexus S (soju, crespo), SDK 16, flash 485486, build JZO54K) or 2.3.6, my service stoped after one line in logs.
On this devices generated wrong log:
--------- beginning of /dev/log/main
Only print one line and nothing.... Service stay in memory, but not work right...
This is my code
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.my.logcatt"
android:versionCode="1"
android:versionName="0.5">
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_LOGS" />
<application android:theme="#android:style/Theme.NoTitleBar">
<activity android:name=".ActivityMain" android:label="logcatt">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".BroadcastBoot" android:enabled="true" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name=".ServiceMain" android:enabled="true" />
</application>
</manifest>
Activity
package com.my.logcatt;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class ActivityMain extends Activity
{
#Override
public void onCreate( Bundle savedInstanceState)
{
super.onCreate( savedInstanceState);
setContentView( R.layout.main);
try { startService( new Intent( getApplicationContext(), ServiceMain.class)); } catch( Exception e) {}
}
}
Service
package com.my.logcatt;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.InputStreamReader;
import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.IBinder;
public class ServiceMain extends Service
{
public static Process procLogcatClean = null;
public static Process procLogcatAM = null;
public static BufferedReader readerLogcat = null;
public static void fLog( String sLogMessage)
{
FileWriter fileLog = null;
BufferedWriter bufferLog = null;
try
{
fileLog = new FileWriter( Environment.getExternalStorageDirectory().getAbsolutePath() + "/123.log", true);
if( fileLog != null)
{
bufferLog = new BufferedWriter( fileLog);
bufferLog.write( sLogMessage + "\r\n");
bufferLog.flush();
}
}
catch( Exception e) {}
finally
{
if( bufferLog != null) { try { bufferLog.close(); } catch( Exception e) {} }
if( fileLog != null) { try { fileLog.close(); } catch( Exception e) {} }
}
}
#Override
public void onCreate()
{
super.onCreate();
startService();
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public void onDestroy()
{
super.onDestroy();
}
public void startService()
{
final Thread thread = new Thread()
{
public void run()
{
try
{
Runtime localRuntimeClear = Runtime.getRuntime();
String[] sLogcatClear = new String[ 2];
sLogcatClear[ 0] = "logcat";
sLogcatClear[ 1] = "-c";
procLogcatClean = localRuntimeClear.exec( sLogcatClear);
procLogcatClean.waitFor();
Runtime localRuntimeAM = Runtime.getRuntime();
String[] sLogcatAM = new String[ 2];
sLogcatAM[ 0] = "logcat";
sLogcatAM[ 1] = "ActivityManager:I *:S";
procLogcatAM = localRuntimeAM.exec( sLogcatAM);
readerLogcat = new BufferedReader( new InputStreamReader( procLogcatAM.getInputStream()), 1024);
String str = "";
while( true)
{
str = "";
try
{
if( readerLogcat != null)
{
str = readerLogcat.readLine();
fLog( str);
}
}
catch( Exception e) {}
if( str.compareTo( "") == 0) continue;
}
}
catch( Exception e) {}
finally {}
}
};
thread.setPriority( Thread.MAX_PRIORITY);
thread.start();
}
}
What is wrong?
On 4.1.2., Only rooted and system applications can access logcat. If rooted, you could use "su logcat".
https://groups.google.com/forum/?fromgroups=#!topic/android-developers/6U4A5irWang
I suspect that you will find that this line throws an exception which you do not handle (bad practice btw - if you had a proper catch, you would have found this I think).
procLogcatAM = localRuntimeAM.exec( sLogcatAM);
Otherwise, check for the Android version and do something different or check for the permission refusal. Or, restrict your app to < 4.1.