[Q] Writing to your Apps data folder - Android Software Development

im trying to write a Serializable Object to the data folder of my app. I was using this code to specify the path to the file and write the Serializable Object
Code:
/**
* writeMissedCalls()
*
* @param context - the Context of the application
* @return if the missedCalls were written to file successfully
*/
public static boolean writeMissedCalls(Context context) {
String filename = context.getApplicationInfo().dataDir + "/" + MCWUtils.MCW_DATA_FILE;
FileOutputStream fos;
ObjectOutputStream out;
try {
fos = context.openFileOutput(filename, Context.MODE_PRIVATE);
out = new ObjectOutputStream(fos);
out.writeObject(MissedCallWidget.missedCalls);
out.close(); }
catch (FileNotFoundException e) { return false; }
catch (IOException e) { return false; }
return true;
}
when i try to write this Object in the onDisabled() of my AppWidgetProvider class i get an error of this sort
java.lang.RuntimeException: Unable to start receiver com.tsb.fistfulofneurons.missedcallwidget.MissedCallWidget: java.lang.IllegalArgumentException: File /data/data/com.tsb.fistfulofneurons.missedcallwidget/missed_calls.dat contains a path separator
do i not need to specify the path to my apps data folder? will the openFileOutput() specify the path to the data for me?
so instead of passing the path "/data/data/com.tsb.fistfulofneurons.missedcallwidget/missed_calls.dat" just pass "missed_calls.dat"?
thanks!

I've not tried to open a file in this manner, but I would guess that it defaults to the apps data directory. Why not give it a try and see?

Gene Poole said:
I've not tried to open a file in this manner, but I would guess that it defaults to the apps data directory. Why not give it a try and see?
Click to expand...
Click to collapse
yea it appears to default to the /data/data folder for your package. the documentation appears to be lacking. thanks

Related

How SEUS Flashing Works

OK, so been trying to figure out what happens when you use SEUS.
It checks for internet connection by loading this URL:
Code:
http://emma.extranet.sonyericsson.com/ns/no-cache
I've figured out quite a bit.
Sony Ericsson has implemented something called Tampered Device Service.
This checks if the devices has been tampered with.
This service works from this server:
Code:
tds.sonyericsson.com
Then for the actual firmware download.
This is done by downloading 2 *.ser.gz which tells SEUS what Software customization to get and is sessions specific.
The customization ser.gz file looks something like this:
Code:
CDA=1233-7027_NjKhzOzTUsfXvPg40lyh6aTl.ser.gz
And it's downloaded from:
Code:
emma.extranet.sonyericsson.com
It's done via some sort of search mechanism on the server.
That looks like this:
Code:
ns/usdoe1/2/script/search/TAC8=35941903/CDA=1233-7027_By5JACZqd1R7JOpLu6qvwK8N.ser.gz
After that it's downloading the actual firmware files.
They are downloaded in bin format which I haven't been able to unpack yet.
They are also downloaded from the emma server and is named something like:
Code:
277795427_k9ABo3YVh+8klYUKwllGLDcJ.bin - ~14.3 MB
277835617_ZpJseUr9e09U5h2Cz81+5vcT.bin ~149 MB
Then it does a netbios call which has some sort of HEX code.
And then check the Internet connection again:
Code:
http://emma.extranet.sonyericsson.com/ns/no-cache
Now it starts up a service called:
Code:
/fq/ServiceClientDbServlet
This service runs from this server:
Code:
ma3.extranet.sonyericsson.com
This last part is done twice in a row.
Inside one of the *ser.gz files is a *.ser file which contains some code and instructions. Some parts is encrypted but most of the code is not.
See the complete code in post #2
I don't quite know what to do with all this info yet.
But hopefully something useful will come of this.
Just wanted to share a bit of my knowledge, hope it's useful for some of you here.
Code:
import com.sonyericsson.cs.ma.tess.api.ServiceException;
import com.sonyericsson.cs.ma.tess.api.ServiceRuntimeException;
import com.sonyericsson.cs.ma.tess.api.TessFile;
import com.sonyericsson.cs.ma.tess.api.UI;
import com.sonyericsson.cs.ma.tess.api.device.IdentificationResult;
import com.sonyericsson.cs.ma.tess.api.inject.InjectConfigValue;
import com.sonyericsson.cs.ma.tess.api.inject.InjectRef;
import com.sonyericsson.cs.ma.tess.api.inject.IncludeFor;
import com.sonyericsson.cs.ma.tess.api.inject.ServiceMethod;
import com.sonyericsson.cs.ma.tess.api.logging.Logging;
import com.sonyericsson.cs.ma.tess.api.protocols.DataArea;
import com.sonyericsson.cs.ma.tess.api.protocols.ProtocolFactory;
import com.sonyericsson.cs.ma.tess.api.protocols.VersionResponse;
import com.sonyericsson.cs.ma.tess.api.protocols.s1.S1Protocol;
import com.sonyericsson.cs.ma.tess.api.protocols.s1.S1Protocol.ShutdownMode;
import com.sonyericsson.cs.ma.tess.api.secs.SECSUnitData;
import com.sonyericsson.cs.ma.tess.api.secs.SECSUtil;
import com.sonyericsson.cs.ma.tess.api.service.ServiceResult;
import com.sonyericsson.cs.ma.tess.api.service.ServiceResultType;
import com.sonyericsson.cs.ma.tess.api.service.ServiceType;
import com.sonyericsson.cs.ma.tess.api.statistics.DiagnosticsUtil;
import com.sonyericsson.cs.ma.tess.api.statistics.StatisticsUtil;
import com.sonyericsson.cs.ma.tess.api.statistics.StatisticsUtil.SoftwareComponent;
import com.sonyericsson.cs.ma.tess.api.ta.TAUnit;
import com.sonyericsson.cs.ma.tess.api.util.StringUtil;
import com.sonyericsson.cs.ma.tess.api.x10.MarlinCertificateUpdate;
import com.sonyericsson.cs.ma.tess.api.zip.ZipFileUtil;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.w3c.dom.Document;
/**
* S1 QSD8250 eSheep platform Main Services implementation.
*
* Services in this logic implemented for use in COMMERCIAL services!
*
*/
public class S1QSD8250eSheepMainServicesLIVE
{
@InjectRef
private ProtocolFactory aProtocolFactory;
@InjectRef
private UI aUI;
@InjectRef
private Logging aLogger;
@InjectRef
private IdentificationResult aIdentifiers;
@InjectRef
private ZipFileUtil aZipFileUtil;
@InjectRef
private static DiagnosticsUtil aDiagnostics;
@InjectRef
private StatisticsUtil aStatistics;
@InjectRef
private SECSUtil aSECS;
@InjectRef
private StringUtil aStringUtil;
@InjectRef
private ClientEnvironment aClientEnvironment;
@InjectRef
private MarlinCertificateUpdate marlinCertUpdate;
// File references
// Loader reference
@InjectConfigValue("cLOADER")
private TessFile aLoader;
// App-SW reference - Exclude from Activation
@IncludeFor([ServiceType.CUSTOMIZE, ServiceType.SOFTWARE_UPDATE,
ServiceType.SOFTWARE_UPDATE_CONTENT_REFRESH])
@InjectConfigValue("cAPP_SW")
private TessFile aAppSW;
// FSP Reference - Exclude from Activation
@IncludeFor([ServiceType.CUSTOMIZE, ServiceType.SOFTWARE_UPDATE,
ServiceType.SOFTWARE_UPDATE_CONTENT_REFRESH])
@InjectConfigValue("cFSP")
private TessFile aFSP;
// miscTA units
// Startup/Shutdown flag used for indicating successful flash.
@InjectConfigValue("cTA_FLASH_STARTUP_SHUTDOWN_RESULT")
private String aStrTaFlashStartShutdownResult;
// Startup/Shutdown flag used for indicating successful flash.
@InjectConfigValue("cTA_EDREAM_FLASH_IN_PROGRESS")
private String aStrTaEDreamFlashStartShutdownResult;
// SIMlock data unit
@InjectConfigValue("cTA_SIMLOCK_DATA")
private String aStrTaSimlockData;
// Loose temp data unit
@InjectConfigValue("cTA_LOOSE_TEMP")
private String aStrTaLooseTemp;
// TA_APPLICATION_BUFFER_DATA_ARRAY[2]
@InjectConfigValue("cTA_APPLICATION_BUFFER_DATA_ARRAY2")
private String aStrTaApplicationBufferDataArray2;
// TA_APPLICATION_BUFFER_DATA_ARRAY[3]
@InjectConfigValue("cTA_APPLICATION_BUFFER_DATA_ARRAY3")
private String aStrTaApplicationBufferDataArray3;
// TA_MARLIN_DRM_KEY_UPDATE_FLAG
@InjectConfigValue("cTA_MARLIN_DRM_KEY_UPDATE_FLAG")
private String aStrTaMarlinDRMKeyUpdateFlag;
// Parameter names
@InjectConfigValue("cTA_APPLICATION_BUFFER_DATA_ARRAY0_NAME")
private String aTaApplicationBufferDataArray0Name;
@InjectConfigValue("cTA_APPLICATION_BUFFER_DATA_ARRAY1_NAME")
private String aTaApplicationBufferDataArray1Name;
@InjectConfigValue("cTA_APPLICATION_BUFFER_DATA_ARRAY2_NAME")
private String aTaApplicationBufferDataArray2Name;
@InjectConfigValue("cTA_APPLICATION_BUFFER_DATA_ARRAY3_NAME")
private String aTaApplicationBufferDataArray3Name;
@InjectConfigValue("cTA_SIMLOCK_DATA_NAME")
private String aTaSimlockDataName;
@InjectConfigValue("cTA_LOOSE_TEMP_NAME")
private String aTaLooseTempName;
@InjectConfigValue("cVERSION_RESPONSE")
private String aVersionResponseName;
// miscTA unit values
// Startup/Shutdown flag, cTA_FLASH_STARTUP_SHUTDOWN_RESULT, values
@InjectConfigValue("cTA_FLASH_STARTUP_SHUTDOWN_RESULT_ONGOING_VALUE")
private String aTaFlashStartupShutdownResultOngoingValue;
@InjectConfigValue("cTA_FLASH_STARTUP_SHUTDOWN_RESULT_FINISHED_VALUE")
private String aTaFlashStartupShutdownResultFinishedValue;
// Startup/Shutdown flag, cTA_EDREAM_FLASH_STARTUP_SHUTDOWN_RESULT, values
@InjectConfigValue("cTA_EDREAM_FLASH_FLASH_IN_PROGRESS_ONGOING")
private String aTaEDreamFlashStartupShutdownResultOngoingValue;
@InjectConfigValue("cTA_EDREAM_FLASH_FLASH_IN_PROGRESS_COMPLETED")
private String aTaEDreamFlashStartupShutdownResultFinishedValue;
// Update.xml values
// File name
private static String UPDATE_XML_FILE_NAME = "update.xml";
// NOERASE tag value
private static String UPDATE_XML_NOERASE_TAG = "NOERASE";
// SIMLOCK tag value
private static String UPDATE_XML_SIMLOCK_TAG = "SIMLOCK";
// PRESERVECACHE tag value
private static String UPDATE_XML_PRESERVECACHE_TAG = "PRESERVECACHE";
// UI Progress texts
@InjectConfigValue("cSEND_DATA")
private String aSendDataText;
@InjectConfigValue("cSEND_DATA_DONE")
private String aSendDataDoneText;
@InjectConfigValue("cSERVICE_FINALIZING")
private String aServiceFinalizingText;
@InjectConfigValue("cSERVICE_FINALIZING_DONE")
private String aServiceFinalizingDoneText;
@InjectConfigValue("cSERVICE_INITIALIZATION")
private String aServiceInitializationText;
@InjectConfigValue("cSERVICE_INITIALIZATION_DONE")
private String aServiceInitializationDoneText;
/**
* ACTIVATION
*
*/
@ServiceMethod(ServiceType.ACTIVATION)
public ServiceResult activation() throws ServiceException
{
boolean vDoActivation = true;
showInitServiceText();
try
{
S1Protocol vS1 = aProtocolFactory.getProtocol(S1Protocol.class);
int vTaSimlockData = Integer.parseInt(aStrTaSimlockData);
int vTaLooseTemp = Integer.parseInt(aStrTaLooseTemp);
int vTaApplicationBufferDataArray2 =
Integer.parseInt(aStrTaApplicationBufferDataArray2);
int vTaApplicationBufferDataArray3 =
Integer.parseInt(aStrTaApplicationBufferDataArray3);
// Check if activation is needed?
// Send loader
vS1.sendFile(aLoader);
vS1.openDataArea(DataArea.MISC_TA);
// Read the SIMlock data from TA_SIMLOCK_DATA
byte[] vSIMlockData = vS1.readDataArea(vTaSimlockData);
if (vSIMlockData != null && vSIMlockData.length >= 20)
{
// Check 20 first bytes (if set to 0)
for (int vI = 0; vI < 20; vI++)
{
if (vSIMlockData[vI] != 0)
{
vDoActivation = false;
break;
}
}
}
else
{
aLogger
.error("Could not determine if activation is needed. Not possible to read enough data.");
throw new ServiceRuntimeException("Error when activating phone.");
}
// Do activation?
if (vDoActivation)
{
// Verify that the dongle is present
aSECS.ensureDongleReady();
String vIMEI = aIdentifiers.getIMEI();
SECSUnitData[] vInputData = getS1SIMLockSignatureInputData(vS1);
SECSUnitData[] vOutputData =
vS1.getS1SIMLockSignature(vInputData, vIMEI);
if (vOutputData != null && vOutputData.length > 6)
{
byte[] vEmpty = new byte[1];
vEmpty[0] = 0x00;
vS1.writeToDataArea(vTaApplicationBufferDataArray2, vEmpty);
vS1.writeToDataArea(
vTaApplicationBufferDataArray3,
vOutputData[3].getUnitData());
vS1
.writeToDataArea(vTaSimlockData, vOutputData[4]
.getUnitData());
vS1.writeToDataArea(vTaLooseTemp, vOutputData[5].getUnitData());
}
else
{
aLogger.error("Not enough data in response from SECS server.");
throw new ServiceRuntimeException(
"Error occured when communicating with server.");
}
}
else
{
aUI
.showText("ACTIVATION NOT NEEDED! This unit has been "
+ "activated already. The service is exiting without execution.");
}
showFinalizingText();
vS1.closeDataArea();
vS1.shutdownDevice(ShutdownMode.DISCONNECT);
}
catch (ServiceException pEx)
{
aLogger.error("Exception when executing ACTIVATION service.", pEx);
throw pEx;
}
return ServiceResult.SUCCESSFUL;
}
/**
* CUSTOMIZE
*
*/
@ServiceMethod(ServiceType.CUSTOMIZE)
public ServiceResult customize() throws ServiceException
{
showInitServiceText();
ServiceResult vServiceResult =
new ServiceResult(
ServiceResultType.SUCCESSFUL,
"Customize EXECUTED! ACTIVATION NEEDED!",
null);
try
{
S1Protocol vS1 = aProtocolFactory.getProtocol(S1Protocol.class);
int vTaSimlockData = Integer.parseInt(aStrTaSimlockData);
int vTaLooseTemp = Integer.parseInt(aStrTaLooseTemp);
showSendingDataText();
// Send loader
vS1.sendFile(aLoader);
vS1.openDataArea(DataArea.MISC_TA);
readDID(vS1);
updateMartinKey(vS1);
setFlashStartupShutdownFlagOngoing(vS1);
// Send App-SW
sendFile(vS1, aAppSW);
// Send FSP
if ("false".equalsIgnoreCase(aFSP.getProperty("SIMLockCustomized"))
&& "true".equalsIgnoreCase(aIdentifiers
.getIdentifier("SIMLockReusable")))
{
// quick-customize
String[] vExcludeTags = new String[1];
vExcludeTags[0] = UPDATE_XML_SIMLOCK_TAG;
String[] vFilesToExcludeFromFSP = parseFile(aFSP, vExcludeTags);
// Send FSP
sendZipFile(vS1, aFSP, vFilesToExcludeFromFSP);
vServiceResult =
new ServiceResult(
ServiceResultType.SUCCESSFUL,
"Quick Customize EXECUTED! NO ACTIVATION NEEDED!",
null);
}
else
{
// customize
// Tamper the simlock data
tamperSimlockData(vS1);
// Set the simlock data unit id to loose temp
aFSP.modifyData(vTaSimlockData, vTaLooseTemp);
sendFile(vS1, aFSP);
}
setFlashStartupShutdownFlagFinished(vS1);
showSendingDataTextDone();
showFinalizingText();
vS1.closeDataArea();
vS1.shutdownDevice(ShutdownMode.DISCONNECT);
storeSoftwareAfterStatistics();
}
catch (ServiceException pEx)
{
aLogger.error("Exception when executing CUSTOMIZE service.", pEx);
throw pEx;
}
return vServiceResult;
}
/**
* SOFTWARE UPDATE
*
*/
@ServiceMethod(ServiceType.SOFTWARE_UPDATE)
public ServiceResult softwareUpdate() throws ServiceException
{
showInitServiceText();
try
{
S1Protocol vS1 = aProtocolFactory.getProtocol(S1Protocol.class);
showSendingDataText();
// Send loader
vS1.sendFile(aLoader);
vS1.openDataArea(DataArea.MISC_TA);
readDID(vS1);
updateMartinKey(vS1);
// Search the APP-SW zip file for xml file and metadata. Exclude user
// data
String[] vExcludeTags = new String[1];
vExcludeTags[0] = UPDATE_XML_NOERASE_TAG;
String[] vFilesToExcludeFromAPPSW = parseFile(aAppSW, vExcludeTags);
// Search the FSP zip file for xml file and metadata. Exclude user data
// and simlock if existing
vExcludeTags = new String[2];
vExcludeTags[0] = UPDATE_XML_NOERASE_TAG;
vExcludeTags[1] = UPDATE_XML_SIMLOCK_TAG;
String[] vFilesToExcludeFromFSP = parseFile(aFSP, vExcludeTags);
setFlashStartupShutdownFlagOngoing(vS1);
// Send App-SW
// Anything to exclude?
if (vFilesToExcludeFromAPPSW != null
&& vFilesToExcludeFromAPPSW.length > 0)
{
sendZipFile(vS1, aAppSW, vFilesToExcludeFromAPPSW);
}
else
{
sendFile(vS1, aAppSW);
}
// Send FSP
sendZipFile(vS1, aFSP, vFilesToExcludeFromFSP);
setFlashStartupShutdownFlagFinished(vS1);
showSendingDataTextDone();
showFinalizingText();
vS1.closeDataArea();
vS1.shutdownDevice(ShutdownMode.DISCONNECT);
storeSoftwareAfterStatistics();
}
catch (ServiceException pEx)
{
aLogger
.error("Exception when executing SOFTWARE UPDATE service.", pEx);
throw pEx;
}
return ServiceResult.SUCCESSFUL;
}
/**
* SOFTWARE UPDATE CONTENT REFRESH
*
*/
@ServiceMethod(ServiceType.SOFTWARE_UPDATE_CONTENT_REFRESH)
public ServiceResult softwareUpdateContentRefresh() throws ServiceException
{
showInitServiceText();
try
{
S1Protocol vS1 = aProtocolFactory.getProtocol(S1Protocol.class);
showSendingDataText();
// Send loader
vS1.sendFile(aLoader);
vS1.openDataArea(DataArea.MISC_TA);
readDID(vS1);
updateMartinKey(vS1);
// Search the FSP zip file for xml file and metadata. Exclude
// simlock if existing
String[] vExcludeTags = new String[0];
aLogger.debug("isSwapEnabled is: "
+ aClientEnvironment.isSwapEnabled());
// Check the client environment.
if (!aClientEnvironment.isSwapEnabled())
{
aLogger.debug("Cache partition will be preserved.");
vExcludeTags = new String[1];
vExcludeTags[0] = UPDATE_XML_PRESERVECACHE_TAG;
}
// Temporarily catch the exception
String[] vFilesToExcludeFromAPPSW = parseFile(aAppSW, vExcludeTags);
vExcludeTags = new String[1];
vExcludeTags[0] = UPDATE_XML_SIMLOCK_TAG;
String[] vFilesToExcludeFromFSP = parseFile(aFSP, vExcludeTags);
setFlashStartupShutdownFlagOngoing(vS1);
// Anything to exclude?
if (vFilesToExcludeFromAPPSW != null
&& vFilesToExcludeFromAPPSW.length > 0)
{
sendZipFile(vS1, aAppSW, vFilesToExcludeFromAPPSW);
}
else
{
sendFile(vS1, aAppSW);
}
// Send FSP
sendZipFile(vS1, aFSP, vFilesToExcludeFromFSP);
setFlashStartupShutdownFlagFinished(vS1);
showSendingDataTextDone();
showFinalizingText();
vS1.closeDataArea();
vS1.shutdownDevice(ShutdownMode.DISCONNECT);
storeSoftwareAfterStatistics();
}
catch (ServiceException pEx)
{
aLogger
.error(
"Exception when executing SOFTWARE UPDATE CONTENT REFRESH service.",
pEx);
throw pEx;
}
return ServiceResult.SUCCESSFUL;
}
/**
* Private help method to get DID data from device, if available.
*
*/
private void readDID(S1Protocol pS1)
{
byte[] vEmptyUnit = new byte[0];
List<TAUnit> vUnits = new ArrayList<TAUnit>();
aLogger.debug("Reading diagnostic data.");
final int vLastUnit = 10009;
final int vFirstUnit = 10000;
for (int vUnit = vFirstUnit; vUnit <= vLastUnit; vUnit++)
{
try
{
byte[] vData = pS1.readDataArea(vUnit);
if (vData != null && vData.length > 0)
{
pS1.writeToDataArea(vUnit, vEmptyUnit);
vUnits.add(new TAUnit(vUnit, vData));
}
}
catch (ServiceException vServiceException)
{
}
}
if (vUnits.size() > 0)
{
byte[] vDiagnosticData;
try
{
aLogger.debug("Diagnostic data found, sending diagnostic data.");
vDiagnosticData = aDiagnostics.createDiagnosticData(vUnits);
aDiagnostics.storeDiagnostic(aIdentifiers.getIMEI(), aIdentifiers
.getApplicationSoftwareID(), aIdentifiers
.getApplicationSoftwareRev(), vDiagnosticData, "06");
}
catch (ServiceException pEx)
{
}
}
}
/**
* Private help method to tamper the simlock data.
*
*/
private void tamperSimlockData(S1Protocol pS1) throws ServiceException
{
int vTaSimlockData = Integer.parseInt(aStrTaSimlockData);
// Read the SIMlock data from TA_SIMLOCK_DATA
byte[] vSIMlockData = pS1.readDataArea(vTaSimlockData);
if (vSIMlockData != null && vSIMlockData.length > 0)
{
// Tamper 20 first bytes (set to 0)
// Make sure enough data is read
if (vSIMlockData.length >= 20)
{
for (int vI = 0; vI < 20; vI++)
{
vSIMlockData[vI] = 0;
}
}
else
{
throw new ServiceRuntimeException(
"Data read, but not enough to tamper.");
}
// Write back the tampered SIMlock data to TA_SIMLOCK_DATA
pS1.writeToDataArea(vTaSimlockData, vSIMlockData);
}
else
{
throw new ServiceRuntimeException("Could not read data.");
}
}
/**
* Private help method to get S1 SIMlock signature input data from device.
*
*/
private SECSUnitData[] getS1SIMLockSignatureInputData(S1Protocol pS1)
throws ServiceException
{
SECSUnitData[] vSECSUnitData = new SECSUnitData[7];
int vTaSimlockData = Integer.parseInt(aStrTaSimlockData);
int vTaLooseTemp = Integer.parseInt(aStrTaLooseTemp);
int vTaApplicationBufferDataArray3 =
Integer.parseInt(aStrTaApplicationBufferDataArray3);
byte[] vEmpty = new byte[1];
vEmpty[0] = 0x00;
vSECSUnitData[0] =
new SECSUnitData(aTaApplicationBufferDataArray0Name, vEmpty);
vSECSUnitData[1] =
new SECSUnitData(aTaApplicationBufferDataArray1Name, vEmpty);
vSECSUnitData[2] =
new SECSUnitData(aTaApplicationBufferDataArray2Name, vEmpty);
byte[] vInputUnitData = pS1.readDataArea(vTaApplicationBufferDataArray3);
vSECSUnitData[3] =
new SECSUnitData(aTaApplicationBufferDataArray3Name, vInputUnitData);
vInputUnitData = pS1.readDataArea(vTaSimlockData);
vSECSUnitData[4] = new SECSUnitData(aTaSimlockDataName, vInputUnitData);
vInputUnitData = pS1.readDataArea(vTaLooseTemp);
vSECSUnitData[5] = new SECSUnitData(aTaLooseTempName, vInputUnitData);
VersionResponse vVersionResponse = pS1.getVersionResponse();
byte[] vVersionResponseArray =
vVersionResponse.getVersionResponseAsBytes();
vInputUnitData = vVersionResponseArray;
vSECSUnitData[6] = new SECSUnitData(aVersionResponseName, vInputUnitData);
return vSECSUnitData;
}
/**
* Parses the specified file for a xml metadata file and the parses the xml
* file for the tags defined. Tag values are then returned as a string array.
*
*/
private String[] parseFile(TessFile pFile, String[] pTags)
throws ServiceException
{
ArrayList<String> vResult = new ArrayList<String>();
Document vUpdateXML =
aZipFileUtil.getXMLFile(pFile, UPDATE_XML_FILE_NAME);
if (vUpdateXML != null)
{
if (pTags != null)
{
for (String vTag : pTags)
{
String[] vFilesFound =
aZipFileUtil.getXMLTextContentByTagName(vUpdateXML, vTag);
if (vFilesFound != null && vFilesFound.length > 0)
{
aLogger.debug("Found files to exclude from "
+ pFile.getFileName()
+ " from tag "
+ vTag
+ " in "
+ UPDATE_XML_FILE_NAME
+ ":");
for (String vFileName : vFilesFound)
{
aLogger.debug(vFileName);
}
vResult.addAll(Arrays.asList(vFilesFound));
}
}
}
}
else
{
aLogger.debug("No " + UPDATE_XML_FILE_NAME + " found");
// throw new
throw new ServiceRuntimeException("Could not find a "
+ UPDATE_XML_FILE_NAME
+ " in the zip file, abort.");
}
return vResult.toArray(new String[vResult.size()]);
}
private void updateMartinKey(S1Protocol pS1) throws ServiceException
{
int vTaMarlinDRMKeyUpdateFlag =
Integer.parseInt(aStrTaMarlinDRMKeyUpdateFlag);
byte[] vFlagValue = null;
pS1.openDataArea(DataArea.MISC_TA);
// check the flag
try
{
vFlagValue = pS1.readDataArea(vTaMarlinDRMKeyUpdateFlag);
if (vFlagValue != null
&& aStringUtil
.convertByteArrayToString(vFlagValue)
.equalsIgnoreCase("01"))
{
// updated already
return;
}
}
catch (ServiceException vServiceException)
{
// exception indicates no update has been done
}
// check if update is available for this unit
if (marlinCertUpdate.isNewCertificateAvailable())
{
// update the cert
InputStream vTAFileInputStream =
marlinCertUpdate.getCertificateTAInputStream();
pS1.sendTAFileFromStream(vTAFileInputStream);
aLogger.debug("Marlin key updated.");
}
// set the flag as updated
pS1.writeToDataArea(vTaMarlinDRMKeyUpdateFlag, aStringUtil
.convertStringToByteArray("0x01"));
return;
}
/**
* Private help method to set the flash ongoing flag to ongoing.
*
* @throws ServiceException
*
*/
private void setFlashStartupShutdownFlagOngoing(S1Protocol pS1)
throws ServiceException
{
int vTaFlashStartupShutdownResult =
Integer.parseInt(aStrTaFlashStartShutdownResult);
int vTaEDreamFlashStartupShutdownResult =
Integer.parseInt(aStrTaEDreamFlashStartShutdownResult);
// Set the TA_FLASH_STARTUP_SHUTDOWN_RESULT (2227) flag to 0xA0000000 to
// indicate
// flash ongoing
pS1
.writeToDataArea(
vTaFlashStartupShutdownResult,
aStringUtil
.convertStringToByteArray(aTaFlashStartupShutdownResultOngoingValue));
// Set the 10100 flag specific for eDream
// Set the TA_EDREAM_FLASH_STARTUP_SHUTDOWN_RESULT (10100) flag to 0x01 to
// indicate
// flash ongoing
pS1
.writeToDataArea(
vTaEDreamFlashStartupShutdownResult,
aStringUtil
.convertStringToByteArray(aTaEDreamFlashStartupShutdownResultOngoingValue));
}
/**
* Private help method to set the flash ongoing flag to finished.
*
* @throws ServiceException
*
*/
private void setFlashStartupShutdownFlagFinished(S1Protocol pS1)
throws ServiceException
{
int vTaFlashStartupShutdownResult =
Integer.parseInt(aStrTaFlashStartShutdownResult);
int vTaEDreamFlashStartupShutdownResult =
Integer.parseInt(aStrTaEDreamFlashStartShutdownResult);
// Set the TA_FLASH_STARTUP_SHUTDOWN_RESULT (2227) flag to 0xAA000000 to
// indicate
// flash finished
pS1
.writeToDataArea(
vTaFlashStartupShutdownResult,
aStringUtil
.convertStringToByteArray(aTaFlashStartupShutdownResultFinishedValue));
// Set the 10100 flag specific for eDream
// Set the TA_EDREAM_FLASH_STARTUP_SHUTDOWN_RESULT (10100) flag to 0x00 to
// indicate flash finished
pS1
.writeToDataArea(
vTaEDreamFlashStartupShutdownResult,
aStringUtil
.convertStringToByteArray(aTaEDreamFlashStartupShutdownResultFinishedValue));
}
/**
* Private help method to store software and CDF ids and versions.
*
*/
private void storeSoftwareAfterStatistics()
{
String vAPPSWId = aAppSW.getProperty("Id");
String vAPPSWVer = aAppSW.getVersion();
String vCDFId = aFSP.getProperty("CDFId");
String vCDFVer = aFSP.getProperty("CDFVer");
if (vAPPSWId != null)
{
aStatistics.storeSoftwareAfter(
SoftwareComponent.SW1,
vAPPSWId,
vAPPSWVer);
}
if (vCDFId != null)
{
aStatistics.storeCustomizationAfter(vCDFId, vCDFVer);
}
}
private void sendZipFile(
S1Protocol pS1,
TessFile pFile,
String[] pFilesToExclude) throws ServiceException
{
aLogger.debug("Sending "
+ pFile.getFileName()
+ ", "
+ pFile.getVersion());
pS1.sendZipFile(pFile, pFilesToExclude);
}
private void sendFile(S1Protocol pS1, TessFile pFile)
throws ServiceException
{
aLogger.debug("Sending "
+ pFile.getFileName()
+ ", "
+ pFile.getVersion());
pS1.sendFile(pFile);
}
/**
* Private help method to display start sending data text.
*
*/
private void showSendingDataText()
{
aUI.showText(aSendDataText);
}
/**
* Private help method to display start sending data done text.
*
*/
private void showSendingDataTextDone()
{
aUI.showText(aSendDataDoneText);
}
/**
* Private help method to display start up and initialization text.
*
*/
private void showInitServiceText()
{
aUI.showText(aServiceInitializationText);
aUI.showText(aServiceInitializationDoneText);
aUI.showText("");
}
/**
* Private help method to display please wait text.
*
*/
private void showFinalizingText()
{
aUI.showText("");
aUI.showText(aServiceFinalizingText);
aUI.showText(aServiceFinalizingDoneText);
}
}
Reserved for future use.
wow seems u done some packet sniffing...
may be u should contact Bin4ry regarding this... he is involved in FreeXperia Project for Arc/Play...
i am sure he can shed some more light on this matter...
Figured out the *.bin files is the actual files that also goes in the blob_fs folder:
Code:
%programfiles%\Sony Ericsson\Update Service\db\
So they are decryptable using the known method.
Tampered Device Service does in fact check for Root and custom software.
Don't know if this will have an effect in the updating process from SEUS.
So, it's a bad news huh. Keep looking. Thanks for the info.
Sent from my X10i using XDA App
Confirmed that devices that has been rooted and modified in software will not be eligible for 2.3.3 update. You will have to flash back a stock unrooted firmware before updating to 2.3.3
Of course. SE said that in their blog. Better backup all data in SD Card and format it too. I don't think the SEUS' intelligent enough to check out that the SD Card contains CyanogenMod folder as busybox and xRecovery
EDIT: I tried to find the update 2.1 package in my computer after repaired my phone for several times and I can't find it. It's of course that it's deleted as soon as the update completed.
I believe SEUS works like the Flash Tool and Pay-Per-Update service through fastgsm.com and davince.
Flash Tool requires you to provide the firmware and place the sin files in the correct location.
Pay service requires a fee to install the correct sin files/firmware.
SEUS requires a CDA to determine which sin files/firmware to install.
I beg that the FlashTool works like SEUS cause without SEUS and other update services, where is FlashTool come from?
But what if SEUS change its method? Well, i still want to update and we will see how it goes.
Sent from my X10i using XDA App
Whatever method they choose, they can't close the door behind them. They need the access too. Flash Tool can be updated.
Nor would google allow that. JMHO
Yes, FT can be updated but it's development is kinda dead as of now, and we don't even have its source codes, so the other developers can't update it. Unless if Androxyde and Bin4ry want to work on FT again.
Hzu said:
Yes, FT can be updated but it's development is kinda dead as of now, and we don't even have its source codes, so the other developers can't update it. Unless if Androxyde and Bin4ry want to work on FT again.
Click to expand...
Click to collapse
Why are the devs acting like this is an issue? The Flash Tool already works on the ARC, so what are you worried about?
Work on Arc no mean it can work on X10, just like Arc has bootloader unlocked but no mean X10 can when update to 2.3.3
silveraero said:
Work on Arc no mean it can work on X10, just like Arc has bootloader unlocked but no mean X10 can when update to 2.3.3
Click to expand...
Click to collapse
You totally missed the point. The bootloader or root has NEVER mattered. When the NEVER has happened, then start your *****ing.
agentJBM said:
Why are the devs acting like this is an issue? The Flash Tool already works on the ARC, so what are you worried about?
Click to expand...
Click to collapse
What I mean is that IF SE changed their flashing method for the GB firmware and FT won't work for those who upgraded their X10 to GB. But another user has said that they won't since it requires them to start all over again.
Who knows, we're not the one who are developing the firmwares and we all should stop making assumptions(but some people aren't making assumptions, they are so sure they are right).
Hzu said:
What I mean is that IF SE changed their flashing method for the GB firmware and FT won't work for those who upgraded their X10 to GB. But another user has said that they won't since it requires them to start all over again.
Who knows, we're not the one who are developing the firmwares and we all should stop making assumptions(but some people aren't making assumptions, they are so sure they are right).
Click to expand...
Click to collapse
I am not pretending to know. However, you are failing to acknowledge that the Flash Tool is a modification of Update Service. The same method is used. Quit acting like this is nuclear science.
I told you, what IF they CHANGE the flashing method, then SEUS will also be updated with the new method.
Why am I repeating this anyway? Silly me.

stranges with android mediaservice

I've got nexus 4 and have some issue with media servicem cause my MS could not find music on my internal SD card; So I make an app;
Code:
public class SingleMediaScanner implements MediaScannerConnectionClient {
private MediaScannerConnection mMs;
private File mFile;
public SingleMediaScanner(Context context, File f) {
mFile = f;
mMs = new MediaScannerConnection(context, this);
mMs.connect();
}
[user=439709]@override[/user]
public void onMediaScannerConnected() {
Log.v("MS", "connected");
mMs.scanFile(mFile.getAbsolutePath(), "audio/*");
Log.v("MS-file", mFile.getAbsolutePath());
}
[user=439709]@override[/user]
public void onScanCompleted(String path, Uri uri) {
mMs.disconnect();
}
}
Code:
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File (root.getAbsolutePath()+"/Music/");
for (int i=0;i<dir.listFiles().length;i++)
{
if (dir.listFiles()[i].isFile()==true&&dir.listFiles()[i].getName().endsWith(".mp3"))
{
new SingleMediaScanner(this, dir.listFiles()[i].getAbsoluteFile());
}
Log says that MS was connected and tried to scan media file, but file doesnt appear in Media library , what's the problem? by the way I have CM ROM

How to copy file from SDCARD to /data/data/...

Hello everyone, I developed an app which utilizes database.
I implemented a method for backing up the database from /data/data/package_name/databases to the SDCARD wiith the following code
Code:
try {
File path_to_sd = Environment.getExternalStorageDirectory();
File path_to_data = Environment.getDataDirectory();
String current_db_path = "//data//" + getPackageName() + "//databases//";
String path_to_database = path_to_data.getAbsolutePath() + current_db_path;
String backup_name = "backup.db";
File current_db = new File(path_to_database, database_name);
File db_backup = new File(path_to_sd, backup_name);
FileChannel src = new FileInputStream(current_db).getChannel();
FileChannel dst = new FileOutputStream(db_backup).getChannel();
if(!db_backup.exists()){
try {
db_backup.createNewFile();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
Toast.makeText(getApplicationContext(), "Exporting database done successfully!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
the thing is that the above code did the job but created a file with the following permissions ---rwxr-x
so my method for importing the database file from the SDCARD back to the /data/data/pachage_name/databases fail at the line
FileChannel src = new FileInputStream(current_db).getChannel();
and the error is that, no read permission for this file.
How can I fix this issue?
thanks a lot.
needed root
shakash3obd said:
Hello everyone, I developed an app which utilizes database.
I implemented a method for backing up the database from /data/data/package_name/databases to the SDCARD wiith the following code
Code:
try {
File path_to_sd = Environment.getExternalStorageDirectory();
File path_to_data = Environment.getDataDirectory();
String current_db_path = "//data//" + getPackageName() + "//databases//";
String path_to_database = path_to_data.getAbsolutePath() + current_db_path;
String backup_name = "backup.db";
File current_db = new File(path_to_database, database_name);
File db_backup = new File(path_to_sd, backup_name);
FileChannel src = new FileInputStream(current_db).getChannel();
FileChannel dst = new FileOutputStream(db_backup).getChannel();
if(!db_backup.exists()){
try {
db_backup.createNewFile();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
Toast.makeText(getApplicationContext(), "Exporting database done successfully!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
the thing is that the above code did the job but created a file with the following permissions ---rwxr-x
so my method for importing the database file from the SDCARD back to the /data/data/pachage_name/databases fail at the line
FileChannel src = new FileInputStream(current_db).getChannel();
and the error is that, no read permission for this file.
How can I fix this issue?
thanks a lot.
Click to expand...
Click to collapse
since u r trying to copy files to /data/data which is only read only mode ... so u need root access to do your job.....
i have attached a a zip file that contains 4 java files and can be included in your project...
it gives you root access... but writing to /data/data must be implemented by u...
Thank you so much anurag.dev1512.
I will take a look at the files you provided.
I will not be able to get back to you about the result soon since it's almost finals time so I will be busy until December
again, thanks a lot.:good:

[Library] Cmd library: Execute Your Java Codes With Root Access Privileges

Synopsis:
Have you ever wanted as root apps developer to use your favourite Java codes instead of bash/shell commands?
Have you grown tired of Runtime.getRuntime.exec("su") and ProcessBuilder("su").start()?
I did and still do, that's why I've been searching for a solution for my problem until I found out in AOSP source code that some of *.java files run with root access, tracking the way they execute them with root access led me to make this simple library.
Description:
Cmd library -short for Command- is an open source (licensed under Apache licence V2) that allows you to execute java commands with root access privileges by passing package name, full class name and whether your app is a system app or not in just two lines of codes.
For instance, suppose you want to flash a *.img recovery image, the first thing comes to your mind is this code:
Code:
busybox dd if=/path/to/recovery.img of=/path/to/recoveryPartition
lets say /sdcard/recovery.img is the file path and /dev/block/mmcblk0p12 is the partition (Samsung GALAXY Ace Plus GT-S7500)
Here is how to implement it:
Code:
...
Proccess proc = Runtime.getRuntime().exec("su");
OutputStream stream = proc.getOutputStream();
stream.write("busybox dd if=/sdcard/recovery.img of=/dev/block/mmcblk0p12".getBytes());
stream.flush();
...
Pretty simple isn't it, now suppose you don't know anything about bash codes, what will you do?
Let me answer this question:
1) Learn some bash.
2) Use Cmd library with java codes.
Here is the same implementaion with Cmd library:
Code:
...
JavaRoot root = JavaRoot.newInstance(getPackageName(), RootCommands.class.getName(), false);
root.execute("/sdcard/recovery.img", "/dev/block/mmcblk0p12")
...
And in RootCommands.java file (should not be an inner class):
Code:
package com.bassel.example;
import com.bassel.cmd.Command;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Main extends Command
{
private byte[] buffer;
private File recovery, partition;
private FileInputStream in;
private FileOutputStream out;
//static main method implementation is a must
@Override
public static void main(String[] args)
{
//required to start
new Main().run(args);
}
//the begging just like onCreate
@Override
public void onRun()
{
if(argsCount() < 2) showUsage();
System.out.println(String.format("Flashing %s to %s", getArg(0), getArg(1)));
recovery = new File(nextArg());
partition = new File(nextArg());
buffer = new byte[1024 * 1024];
try
{
in = new FileInputStream(recovery);
out = new FileOutputStream(partition);
while(in.read(buffer) > 0)
{
out.write(buffer);
out.flush();
}
in.close();
out.close();
System.out.println("Flashed successfully!");
}
catch (Exception e)
{e.printStackTrace(System.err);}
}
//called upon calling showUsage()
@Override
public void onShowUsage()
{
System.err.println("Two args are needed!");
}
//called once an exception is caught
@Override
public void onExceptionCaught(Exception exception)
{
exception.printStackTrace(System.err);
}
}
Quite lengthy but sometimes we prefer using Java codes to bash ones, don't we?
Here is another example for listing /data files:
Code:
package com.bassel. example;
import java.io.File;
//Without extending Command.class
public class Main
{
@Override
public static void main(String[] args)
{
String[] files = new File("/data").list();
for(String file : files)
{
System.out.println(file);
}
}
}
Usage in depth:
Check root access:
Cmd.root();
No root:
Cmd.SH.ex(String command, String... args);
Cmd.SH.ex(String[] commands);
Cmd.SH.ex(List commands);
With root access:
Cmd.SU.ex(String command, String... args);
Cmd.SU.ex(String[] commands);
Cmd.SU.ex(List commands);
JavaRoot java = JavaRoot.newInstance(String packageName, String className, boolean isSystemApp);
java.execute(String... args);
java.executeInBackground(String... args);
All previous methods aside of the last one:
java.executeInBackground(String... args);
return an instance of type Output that has the following methods:
Code:
boolean success() //returns true if process exit value = 0 else false
String getString() //returns output in String format
String[] getArray() //returns output in String Array format
List getList() //returns output in String List format
int getExitValue() //returns process exit value
String toString() //returns process status and output in String format
Converting:
String string = ...;
String[] array = ...;
List list = ...;
String s1 = Convert.array2string(array);
String s2 = Convert.list2string(list);
String[] a1 = Convert.list2array(list);
String[] a2 = Convert.string2array(string);
List l1 = Convert.array2list(array);
List l2 = Convert.string2list(string);
Library GitHub link:
Cmd (licensed under Apache License, Version 2.0)
Examples:
Window Manipulator

Java&WinRAR-(dirthack) to get files >4GB to USB-Disk for Kodi

Hi together,
last year I've installed a 1st-Gen FireTV with Kodi in combination with a 4TB USB HDD for my parents RV. Don't exactly remember how I got the 4TB disk to fat32, but google should provide the answer, since it did for me than. The bigger issue anyway was to get files bigger than 4GB on the disk. The trick for my was to find out, that Kodi can access *.rar archives as if it was a file. So I wrote a java "dirtyhack": It uses a combination of java and WinRAR. Java to determine if a file is bigger than 4GB or not. If it is smaller, just copy the file, if it is bigger, call WinRAR with the right parameters to create a splittet archive consisting of parts smaller than 4GB on the HDD.
So first you choose a source-folder, than select a destination-folder (should be the Disk ) and all files get copied recursively.
As I'm currently updating the HDD and have unsuccessfully searched for an easier way (after I've installed all updates on the ftv *doh!*) I thought I could share my Code, so here you go:
Code:
import javax.swing.*;
import java.io.IOException;
import java.io.*;
/**
* @author der-gee
*
*/
public class Copy {
static int amountFiles = 0;
static long limit = 4294967295L;
/**
* Lists all files from a given folder, recursively
*
* @param dir
* Prints a list of files > 4GB and sums them up
*/
public static void listDir(File dir) {
File[] files = dir.listFiles();
if (files != null) {
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
listDir(files[i]); // calls itself
} else {
if (files[i].length() > limit) {
System.out.println(files[i].getAbsolutePath());
amountFiles++;
}
}
}
}
}
/**
* Shows a select file dialog and returns the choosen one ^^
*
* @param title
* Title to be shown by the "choose file dialog"
* @return The directory as file
*/
static public File getFolder(String title) {
JFileChooser chooser;
chooser = new JFileChooser();
chooser.setCurrentDirectory(File.listRoots()[0]);
chooser.setDialogTitle(title);
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
return chooser.getSelectedFile();
} else {
System.out.println("No Selection ");
return null;
}
}
/**
* Copies directories and files smaller than 4GB
*
* @param src
* @param dest
* @throws IOException
*/
public static void copyFolder(File src, File dest) throws IOException {
if (src.isDirectory()) {
// if directory not exists, create it
if (!dest.exists()) {
dest.mkdir();
System.out.println("Directory copied from " + src + " to "
+ dest);
}
// list all the directory contents
String files[] = src.list();
for (String file : files) {
// construct the src and dest file structure
File srcFile = new File(src, file);
File destFile = new File(dest, file);
// recursive copy
copyFolder(srcFile, destFile);
}
} else {
// if file, then copy it
// Use bytes stream to support all file types
// If file is t large for Fat32 -> rar it
if (src.length() >= limit)
rarThis(src, dest);
else {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
// copy the file content in bytes
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.close();
System.out.println("File copied from " + src + " to " + dest);
System.out.println("Size from: " + src + ":" +src.length());
}
}
}
/**
* Should use a combination of cmd and winrar to create splitted archives,
* so that they can be stored to a fat32 drive.
*
* @param src
* @param dest
*/
public static void rarThis(File src, File dest) {
String[] command = {
"\"" + "C:\\Program Files\\WinRAR\\rar.exe" + "\"",
"a", "-m0", //a = Archive, -m0 = compressionMode store
"-v3.999g", "-y", //v = VolSize, y = always answer yes
"-ep", //ep = noPath in archive
"\"" + dest.getAbsolutePath().replace("mkv", "rar") + "\"",
"\"" + src.getAbsolutePath() + "\"" };
Runtime rt = Runtime.getRuntime();
try {
Process rar = rt.exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(rar.getInputStream()));
String line;
while ((line = reader.readLine()) != null)
System.out.println("WinRAR: " + line);
rar.waitFor();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println(e);
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
System.out.println(e);
e.printStackTrace();
}
}
/**
* Main program. Initiates the whole thing :)
*
* @param s
* @throws IOException
*/
public static void main(String s[]) throws IOException {
System.out.println("Size limit: " + limit);
File sourcePath = getFolder("Source");
if (sourcePath != null) {
listDir(sourcePath);
System.out.println("Amount files > 4GB: " + amountFiles);
}
File targetPath = getFolder("Destination");
copyFolder(sourcePath, targetPath);
System.out.println("Finished!");
}
}
I wrote this for Windows, using the x64 Version of WinRar, so if you are using the 32-bit version, you have to adjust the rar folder in the rarThis function. Feel free to use and share. If you have improvements, please share
Interesting. When I came to this problem of HD files larger than 4 GB I decided to use the NTFS format and then use Paragon to mount the external HDD on my rooted Fire TV.
PhoenixMark said:
Interesting. When I came to this problem of HD files larger than 4 GB I decided to use the NTFS format and then use Paragon to mount the external HDD on my rooted Fire TV.
Click to expand...
Click to collapse
Hehe, I would have done the same, but I checked for root after upgrading to the very last fw version
PhoenixMark said:
Interesting. When I came to this problem of HD files larger than 4 GB I decided to use the NTFS format and then use Paragon to mount the external HDD on my rooted Fire TV.
Click to expand...
Click to collapse
Was this on the latest rooted firmware? I have a AFTV2 running the latest prerooted rom from rbox
deanr1977 said:
Was this on the latest rooted firmware? I have a AFTV2 running the latest prerooted rom from rbox
Click to expand...
Click to collapse
I'm using 5.0.5 because I like using FireStarter, but I don't see why you can't still do this on 5.0.5.1 as well as there is a pre rooted rom for it. Only difference is you need the A to A USB cable to root 5.0.5.1.

Categories

Resources