Update EditText outside of an View Pager by button click - Java for Android App Development

Hello everyone,
I'm trying to develop an calculator app and for this purpose I'm using the ViewPager to create 3 panels with different options.
My main layout looks like this:
========================
| |
| EditText |
| |
========================
| |
| |
| ViewPager |
| |
| |
| |
========================
Every panel has its own fragment and my problem is that i can't edit or update the edit text from the fragment. I have tried creating a static method in the main activity and run it on the ui thread without any luck.
I also tried this code:
mainLayout=inflater.inflate(R.layout.activity_main, container, false);
output = (EditText) mainLayout.findViewById(R.id.outputView);
output.setText("someText");
With the same result.
Wich is the appropiate way to do this?
Thank you!

alex-p690 said:
Hello everyone,
I'm trying to develop an calculator app and for this purpose I'm using the ViewPager to create 3 panels with different options.
My main layout looks like this:
========================
| |
| EditText |
| |
========================
| |
| |
| ViewPager |
| |
| |
| |
========================
Every panel has its own fragment and my problem is that i can't edit or update the edit text from the fragment. I have tried creating a static method in the main activity and run it on the ui thread without any luck.
I also tried this code:
mainLayout=inflater.inflate(R.layout.activity_main, container, false);
output = (EditText) mainLayout.findViewById(R.id.outputView);
output.setText("someText");
With the same result.
Wich is the appropiate way to do this?
Thank you!
Click to expand...
Click to collapse
Just create a public method in your activity which sets the text:
Code:
public void setEditText(CharSequence text) {
EditText output = (EditText) mainLayout.findViewById(R.id.outputView);
output.setText(text);
}
Then, in your Fragment, call that method on the activity object you get from getActivity():
Code:
((YourActivity) getActivity()).setEditText("Some text");
If you aim to use your fragment across different activities, you'll need to use an interface which must be implemented by every activity.

SimplicityApks said:
Just create a public method in your activity which sets the text:
Code:
public void setEditText(CharSequence text) {
EditText output = (EditText) mainLayout.findViewById(R.id.outputView);
output.setText(text);
}
Then, in your Fragment, call that method on the activity object you get from getActivity():
Code:
((YourActivity) getActivity()).setEditText("Some text");
If you aim to use your fragment across different activities, you'll need to use an interface which must be implemented by every activity.
Click to expand...
Click to collapse
This is just awesome!! Thank you very much. I have tried something similar to this but I was getting the "cannot reference non-static method from static context".

alex-p690 said:
This is just awesome!! Thank you very much. I have tried something similar to this but I was getting the "cannot reference non-static method from static context".
Click to expand...
Click to collapse
Change the setEditText to a static method then
From:
public void setEditText(CharSequence text) {
to:
public static void setEditText(CharSequence text) {
Edit: Also the method does not need to be public - you are providing much more access to that method than is needed by defining it as public, and for the sake of doing it properly and good practices you should rename it to a package-local method like below:
static void setEditText(CharSequence text) {

Jonny said:
Change the setEditText to a static method then
From:
public void setEditText(CharSequence text) {
to:
public static void setEditText(CharSequence text) {
Edit: Also the method does not need to be public - you are providing much more access to that method than is needed by defining it as public, and for the sake of doing it properly and good practices you should rename it to a package-local method like below:
static void setEditText(CharSequence text) {
Click to expand...
Click to collapse
Good to know! Thanks a lot!

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.

Interested in toggling a value in the build.prop

So in my toolkit, id like to design an activity where I could point it towards certain lines in the build.prop to allow a user to easily toggle, for instance this line
qemu.hw.mainkeys=0
So, in the layout xml, lets say it had "Enable Nav Bar" and a "Toggle Button" for on/off
Where would i start in developing such a feature?
You create a ToggleButton and whenever it is clicked, you change the line.
What is your problem?
nikwen said:
You create a ToggleButton and whenever it is clicked, you change the line.
What is your problem?
Click to expand...
Click to collapse
My concerns are wouldnt I need to add ro permissions on the prop before toggling and a reboot action to apply
I think your device needs to be rooted to be able to write to the build.prop file. You do not need root access to read it though
I'm from mobile and i can't post some code but i will give you some hints
To edit build.prop programmatically first you ne ed to be rooted then you can use the shell command "sed" to exchange values. Take a look at AOKP settings source on github and look for density changer class
If you want to import various build properties you can use fileinputstream and read the file line by line then let the app create listview custom items for every line in the file (you need a custom adapter) .
Sorry if this post it's not really useful but i will edit this when at PC
Sent from my HTC One X using Tapatalk 4 Beta
Thankyou for the tip! The answer might of been infront of my face possibly...
Sent from my 9300 using xda app-developers app
xcesco89 said:
I'm from mobile and i can't post some code but i will give you some hints
To edit build.prop programmatically first you ne ed to be rooted then you can use the shell command "sed" to exchange values. Take a look at AOKP settings source on github and look for density changer class
If you want to import various build properties you can use fileinputstream and read the file line by line then let the app create listview custom items for every line in the file (you need a custom adapter) .
Sorry if this post it's not really useful but i will edit this when at PC
Sent from my HTC One X using Tapatalk 4 Beta
Click to expand...
Click to collapse
I Wrote something up but I keep getting force closes "Not a java code monkey yet, still learning" and Ill post here what I have when I get to my pc later. Maybe you can see what Im missing or did wrong. What I did is I have a preference screen similiar to AOKP density changer class. What Im going for is a PreferenceList that you click and your values are Enable or Disabled and another preference to reboot to apply settings. Im wanting to allow the user to enable and disable the Navigation Bar by toggling it through the build.prop. If this works, I want to add more toggles custom values like change your phone model, Screen Density, build number, ect; but figured Id start with something simpler first and see if it works.
Sent from my Alps9300 using Tapatalk
Nx Biotic said:
I Wrote something up but I keep getting force closes "Not a java code monkey yet, still learning" and Ill post here what I have when I get to my pc later. Maybe you can see what Im missing or did wrong. What I did is I have a preference screen similiar to AOKP density changer class. What Im going for is a PreferenceList that you click and your values are Enable or Disabled and another preference to reboot to apply settings. Im wanting to allow the user to enable and disable the Navigation Bar by toggling it through the build.prop. If this works, I want to add more toggles custom values like change your phone model, Screen Density, build number, ect; but figured Id start with something simpler first and see if it works.
Sent from my Alps9300 using Tapatalk
Click to expand...
Click to collapse
this is the method you need:
Code:
private void setLcdDensity(int newDensity) {
Helpers.getMount("rw");
new CMDProcessor().su.runWaitFor("busybox sed -i 's|ro.sf.lcd_density=.*|"
+ "ro.sf.lcd_density" + "=" + newDensity + "|' " + "/system/build.prop");
Helpers.getMount("ro");
}
( method took from here : https://github.com/TeamBAKED/packag...aked/romcontrol/fragments/DensityChanger.java )
newDensity is the int/string you let the user set ( you can use a seekbar or a dialog or what you prefer)
you have also CMDProcessor().su.runWaitFor : just use the classes you can find here : https://github.com/TeamBAKED/packag...11bca71808c9143/src/com/baked/romcontrol/util
just add these classes in your project ( these are to simplify your life when you need to use android terminal [ remember to give credits on your app! ] )
Now, you can use various types of views and methods to show to the user all the available props:
- manually add every view for every line in your build.prop ( this will probably limit the compatibility with other devices and make your app "laggy" due to "gazilions" views )
- use a blank linearLayout and inflate a "row view" for every line in build.prop:
read file line by line and import every line in an ArrayList:
Code:
ArrayList<String> Tokens = new ArrayList<String>();
try {
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("/system/build.prop");
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
// Read File Line By Line
while ((strLine = br.readLine()) != null) {
strLine = strLine.trim();
if ((strLine.length()!=0)) {
String[] names = strLine.split("\\s+");
Tokens.add(names[0]);
}
}
for (String s : Tokens) {
//System.out.println(s);
//Log.d("NNNNNNNNNNNNNNNNNN", s);
}
// Close the input stream
in.close();
} catch (Exception e) {// Catch exception if any
System.err.println("Error: " + e.getMessage());
}
names = new String[Tokens.size()-1];
names = Tokens.toArray(names);
ArrayList<String> value = new ArrayList<String>();
try {
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("/sys/devices/system/cpu/cpu0/cpufreq/UV_mV_table");
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
// Read File Line By Line
while ((strLine = br.readLine()) != null) {
strLine = strLine.trim();
if ((strLine.length()!=0)) {
String[] val = strLine.split("\\s+");
value.add(val[1]);
}
}
for (String s : value) {
//System.out.println(s);
//Log.d("NNNNNNNNNNNNNNNNNN", s);
}
// Close the input stream
in.close();
} catch (Exception e) {// Catch exception if any
System.err.println("Error: " + e.getMessage());
}
values = new String[value.size()-1];
values = value.toArray(values);
LineNumberReader lnr = null;
try {
lnr = new LineNumberReader(new FileReader(new File("/sys/devices/system/cpu/cpu0/cpufreq/UV_mV_table")));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
lnr.skip(Long.MAX_VALUE);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int num = lnr.getLineNumber();
Log.d("LINES", ""+num);
int i = 0;
//now inflate a specific view for every line
// you can also filter every item for example by reading the string and inflating a different layout using an if statement
for (String s : names) {
LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View v = inflater.inflate(R.layout.uvrow, null, true);
TextView text0 = (TextView) v.findViewById(R.id.text0);
ImageButton back0 = (ImageButton) v.findViewById(R.id.back0);
final EditText edit0 = (EditText) v.findViewById(R.id.edit0);
ImageButton fwd0 = (ImageButton) v.findViewById(R.id.fwd0);
text0.setText(s);
parentGroup.addView(v);
edit0.setText(values[i]);
/*
* if you need to set listeners and actions insert them inside this loop!
*/
}
if you need more informations, take a look at my code on github ( was my first "really useful" app ): https://github.com/cesco89/CustomSettings/blob/master/src/com/cesco/customsettings/UVTable.java
it's not perfect, could be tricky, but i can't post all the code here
This Is what I put together...Excuse any errors in java...Im new at this. When I start this fragment, I get a force close. What did I do?
Code:
package com.bionx.res.catalyst;
import android.content.Context;
import android.os.Bundle;
import android.os.PowerManager;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceFragment;
import com.bionx.res.R;
import com.bionx.res.helpers.CMDProcessor;
import com.bionx.res.helpers.Helpers;
public abstract class Navbar extends PreferenceFragment implements OnPreferenceChangeListener {
Preference mReboot;
ListPreference mStockValue;
int newStockValue;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.navbarchanger);
mStockValue = (ListPreference) findPreference("stock_value");
mStockValue.setOnPreferenceChangeListener(this);
mReboot = findPreference("reboot");
}
public boolean onPreference(Preference preference) {
if (preference == mReboot) {
PowerManager pm = (PowerManager) getActivity()
.getSystemService(Context.POWER_SERVICE);
pm.reboot("Setting Navbar");
}
return false;
}
[user=439709]@override[/user]
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference == mStockValue) {
newStockValue = Integer.parseInt((String) newValue);
setNavbarValue(newStockValue);
mStockValue.setSummary(getResources().getString(R.string.navbar_changer) + newStockValue);
return true;
}
return false;
}
private void setNavbarValue(int newNavbar) {
Helpers.getMount("rw");
new CMDProcessor().su.runWaitFor("busybox sed -i 's|qemu.hw.mainkeys=.*|"
+ "qemu.hw.mainkeys" + "=" + newNavbar + "|' " + "/system/build.prop");
Helpers.getMount("ro");
}
}
Code:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<Preference
android:title="System Properties"
android:summary="User System Tweaks" />
<ListPreference
android:entries="@array/navbar_stock_entries"
android:entryValues="@array/navbar_stock_values"
android:key="stock_value"
android:title="NavBar Enabler"
android:summary="Toggle the system navbar" />
<Preference
android:key="reboot"
android:title="Reboot"
android:summary="Applies tweaks and reboots" />
</PreferenceScreen>
Where I launch the fragment.
Code:
...
<header
android:fragment="com.bionx.res.catalyst.Navbar"
android:icon="@drawable/ic_changelog"
android:title="System Ui Tweaks"
android:summary="Developers soup of the week" />
...
Nx Biotic said:
This Is what I put together...Excuse any errors in java...Im new at this. When I start this fragment, I get a force close. What did I do?
Code:
package com.bionx.res.catalyst;
import android.content.Context;
import android.os.Bundle;
import android.os.PowerManager;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceFragment;
import com.bionx.res.R;
import com.bionx.res.helpers.CMDProcessor;
import com.bionx.res.helpers.Helpers;
public abstract class Navbar extends PreferenceFragment implements OnPreferenceChangeListener {
Preference mReboot;
ListPreference mStockValue;
int newStockValue;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.navbarchanger);
mStockValue = (ListPreference) findPreference("stock_value");
mStockValue.setOnPreferenceChangeListener(this);
mReboot = findPreference("reboot");
}
public boolean onPreference(Preference preference) {
if (preference == mReboot) {
PowerManager pm = (PowerManager) getActivity()
.getSystemService(Context.POWER_SERVICE);
pm.reboot("Setting Navbar");
}
return false;
}
[user=439709]@override[/user]
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference == mStockValue) {
newStockValue = Integer.parseInt((String) newValue);
setNavbarValue(newStockValue);
mStockValue.setSummary(getResources().getString(R.string.navbar_changer) + newStockValue);
return true;
}
return false;
}
private void setNavbarValue(int newNavbar) {
Helpers.getMount("rw");
new CMDProcessor().su.runWaitFor("busybox sed -i 's|qemu.hw.mainkeys=.*|"
+ "qemu.hw.mainkeys" + "=" + newNavbar + "|' " + "/system/build.prop");
Helpers.getMount("ro");
}
}
Code:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<Preference
android:title="System Properties"
android:summary="User System Tweaks" />
<ListPreference
android:entries="@array/navbar_stock_entries"
android:entryValues="@array/navbar_stock_values"
android:key="stock_value"
android:title="NavBar Enabler"
android:summary="Toggle the system navbar" />
<Preference
android:key="reboot"
android:title="Reboot"
android:summary="Applies tweaks and reboots" />
</PreferenceScreen>
Where I launch the fragment.
Code:
...
<header
android:fragment="com.bionx.res.catalyst.Navbar"
android:icon="@drawable/ic_changelog"
android:title="System Ui Tweaks"
android:summary="Developers soup of the week" />
...
Click to expand...
Click to collapse
please post the Log you get on Eclipse !
the log will tell you exactly where the error is

Push notifications between devices

Hello!
Sorry for my bad english.
I'm trying to develop an app that send a push notification from device A (android) to device B (android).
How can I make this app?
I can't use GCM/Parse server, 'cause a push notification is sent ONLY from server to device!
I must use a DB that save MY contacts? And then, with a query (?), sent a push notif. to user B (B have downloaded the app, of course!)?
Thanks!
Venus88 said:
I can't use GCM/Parse server,
Click to expand...
Click to collapse
Yes you can, you would just need to create an API that would capture a message sent to the server from device A then send it to device B.
Jonny said:
Yes you can, you would just need to create an API that would capture a message sent to the server from device A then send it to device B.
Click to expand...
Click to collapse
Thanks a lot!
And how I can do that? The code for GCM server, i.e. gcm.php:
PHP:
<?php
class GCM {
//put your code here
// constructor
function __construct() {
}
/**
* Sending Push Notification
*/
public function send_notification($registatoin_ids, $message) {
// include config
include_once './config.php';
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $message,
);
$headers = array(
'Authorization: key=' . GOOGLE_API_KEY,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
// Execute post
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
echo $result;
}
}
?>
and
PHP:
<?php
// response json
$json = array();
/**
* Registering a user device
* Store reg id in users table
*/
if (isset($_POST["name"]) && isset($_POST["email"]) && isset($_POST["regId"])) {
$name = $_POST["name"];
$email = $_POST["email"];
$gcm_regid = $_POST["regId"]; // GCM Registration ID
// Store user details in db
include_once './db_functions.php';
include_once './GCM.php';
$db = new DB_Functions();
$gcm = new GCM();
$res = $db->storeUser($name, $email, $gcm_regid);
$registatoin_ids = array($gcm_regid);
$message = array("product" => "shirt");
$result = $gcm->send_notification($registatoin_ids, $message);
echo $result;
} else {
// user details missing
}
?>
allows send notification from server page to one/a group of devices.
Can i "reverse" the direction? from Device A to server (and then from server to device B) automatically?
Up :\

[Tutorial] Developing Cloud Base App [GoogleCloud][Android]

{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
​ In this Tutorial I try to explain general aspects of Cloud Computing & Cloud Concepts & Authentication You will learn What is Cloud & If already know basics of Android Programming, you will be able to develop your Cloud Base App after reading carefully this guide.
Featured By XDA
Aamir Siddiqui | May 19, 2016
XDA Senior Member Geeks Empire has posted an extensive tutorial on developing a cloud based app.
The tutorial teaches users how to make use of Google Cloud and Firebase to achieve their goals.
Click to expand...
Click to collapse
Why are so many businesses moving to the cloud? It’s because cloud computing increases efficiency, helps improve cash flow and offers many more benefits…Here's ten of the best.
1. Flexibility
2. Disaster recovery
3. Automatic software updates
4. Capital-expenditure Free
5. Increased collaboration
6. Work from anywhere
7. Document control
8. Security
9. Competitiveness
10. Environmentally friendly
READ MORE
Click to expand...
Click to collapse
If you want to design & develop cloud service for your business it is better to understand What you Know & Need.
Cloud Services categorized into 3 basic models:
- Infrastructure-as-a-Service (IaaS)
- Platform-as-a-Service (PaaS)
- Software-as-a-Service (SaaS)
Click to expand...
Click to collapse
Try to read again carefully All descriptions & Link above to get reach knowledge of Cloud.
In This Tutorial I used All Alphabet Services. Google Cloud, Firebase, Google Play Services & etc.
I prefer Alphabet cause It is Google
“Firebase — a powerful platform for building iOS, Android, and web-based apps, offering real-time data storage and synchronization, user authentication, and more.”
Click to expand...
Click to collapse
INDEX
* Data Transferring *
- FireBase Cloud Service
* Authentication *
- Google Account By GoogleSignIn API
- Twitter By Fabric API
- Email/Pass By Firebase API
# Let Start #
What you Need to Continue is;
1. Google Account
2. Ability to Create Hello World! Project in Android Studio
Click to expand...
Click to collapse
* Application Configuration
Run Android Studio & Create New Project with Blank Activity. (Set Proper AppName & Package)
After Gradle Building finished go to File > Project Structure > Cloud & Enable Firebase.
Go to Manifest > Add Get_Account & Internet Permissions above the <application />
Code:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
then Inside Application tag add Google_Play_Service <meta-data />
Code:
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
Then Open build.gradle (Module: App) & Add these excludes to prevent errors during test process inside android{}
Code:
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE-FIREBASE.txt'
exclude 'META-INF/NOTICE'
}
Also Add this library for auth-process into dependencies{}
Code:
compile 'com.google.android.gms:play-services-auth:8.4.0'
Now your App is Ready to Add Codes for Cloud API But your Need to Configure Cloud Side too.
* Google Cloud & Firebase Configuration
Here some parts doesn't need for beginning Android Coding But It can be tricky & easy for you to do everything on Browser for Google Section and then Focus on Coding. At End you can Review All Parts & Test it by yourself. I will explain more about each part.
Generate your Sign APK to Get SHA-1 Key
Code:
keytool -list -v -keystore '/PATH/TO/kEY_STORE'
To Transfer Data to Cloud you need to Have a Cloud Service. Here I am using Firebase.
Go to www.Firebase.com & Login with your Google Account.
Firebase will automatically Create a Project for you named 'MY FIRST APP' that you can delete or modify it.
Firebase has Free Plan for Small Business, Testing & etc. So after you learn more about cloud you can upgrade your plan for existing projects.
The URL of Firebase for your Project is Like this​
HTML:
https://YOUR_APP_NAME.firebaseio.com/
Every task with Firebase API needs this URL.
Go to https://Console.Gloud.Google.com Sign-Up & Get 60 Days Trial Period & 300$ to spend on Google Cloud Platform.
So Feel Free to Create Projects & Enabling APIs.
After Creating Google Cloud Project go to Project Dashboard & from Left Panel navigate to API Manager > Credentials. Click on Create Credential & Select OAuth client ID After Loading New Page Select Android Then Create. Now Set Carefully your SHA-1 key & Android App PackageName then Save.
Go to https://Developers.Google.com/ First of All If you are new to Developing Spend some times in this page & Enjoy All Google Services for Everything. :good:
Then Navigate to Google Service for Mobile > Android > Sign-In with Google > Click Get Start > Scroll Down > Click Get Configuration File.
Again Type your Android App PackageName then Click Continue & Type SHA-1 Key & Click ENABLE GOOGLE SIGN-IN after that Scroll Down and Click on Generate Configuration File and Download the File.
Copy google-service.json File & Paste it to App Level Project.
Code:
To do this Now Open Android Studio Change View of Project Explorer from Android View to Project View.
Expand Project and Paste JSON file under the APP Level.
http://dl-1.va.us.xda-developers.co....jpg?key=fJhht_mZE9VqhL4UuJvbow&ts=1464144452
Now you are ready to use Firebase Services & Login with Google.
Next Post is About Working with Firebase Send/Receive Data.
Oo. DOWNLOAD .oO
SOURCE.CODE
APK.FILE
​
Thanks for Supporting GeeksEmpire projects
​Don't Forget To Hit Thanks
​
Google Cloud & Firebase [Data Transferring]
​Now It is time to Focus on Coding. It is not difficult to understand Firebase API But Using URL carefully to Create New User, Data, Section & etc is important.
Open MainActivity.Java
At First the Class must extended from Fragment that required for Firebase API (& later for Google Sign-In). In this case I use AppCompatActivity.
Code:
public class MainActivity extends AppCompatActivity{}
To work with Firebase API you have to define it like other objects.
You can do it when you need it Or define it at first part of app onCreate(Bundle){}
Code:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
[B]Firebase.setAndroidContext(getApplicationContext());[/B]
After that you need to declare instance of your views. For Example I declare ListView that will use for showing loaded Data.
Code:
ListView listView = (ListView)findViewById(R.id.listView);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, android.R.id.text1);
//built-in adaptor
listView.setAdapter(adapter);
NOTE: Save your Firebase URL to <resource> <string /></resource> Or Save it as Universal String Object inside Class.
For Example Before onCreate(Bundle)
Code:
String FirebaseLink = "https://[B]YOUR_APP_NAME[/B].firebaseio.com/";
String FirebaseTitle = "GeeksEmpire";
String FirebaseSub = "gX";
To Get Data from User you should define input method like <EditText/>
With This methods you can Save Data Locally in Application Private Storage on System
Code:
//Save Content
try {
FileOutputStream fOut = openFileOutput(NAME, MODE_PRIVATE);
fOut.write((DATA).getBytes());
//Always Close All Streams
fOut.close();
fOut.flush();
}
catch (Exception e) {
System.out.println(e);
} finally {}
Code:
//Read-File
public String READ(String S, Context context){
File Fav = new File(S);
String Read = null;
FileInputStream fin;
BufferedReader br = null;
try{
fin = new FileInputStream(Fav);
br = new BufferedReader(new InputStreamReader(fin, "UTF-8"), 1024);
System.out.println(br);
int c;
String temp = "";
while( (c = br.read()) != -1){temp = temp + Character.toString((char)c);}
Read = temp;}
catch(Exception e)
{System.out.println(e);}
finally{try {br.close();} catch (IOException e) {e.printStackTrace();}}
return Read;
}
But to Store Data on Firebase Server you should declare instance of Firebase API, Push & setValue(DATA)
Code:
upload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String DATA = editText.getText().toString();//"[COLOR=Red][I]GeeksEmpire DataBase on FireBase[/I][/COLOR]"
new Firebase([B]FirebaseLink[/B]/*[COLOR=Red][I]https://YOUR_APP_NAME.firebaseio.com[/I]/[/COLOR]*/ + FirebaseTitle/*[COLOR=Red][I]GeeksEmpire[/I][/COLOR]*/)
.push()
.child(FirebaseSub/*[COLOR=Red][I]gX[/I][/COLOR]*/)
.setValue(DATA);
}
});
Compare red texts with image. Firebase URL is submitted but you can Modify both FirebaseTitle & FirebaseSub.
In this Case I used GeeksEmpire as Title & gX as SubTitle & then Data.
It is depend on your design.
you can set GeeksEmpire as User & gX as Title OR Whatever you need.​
Data Uploaded to Server & Now you should make an option to Download them. I created function to gather all components.
Code:
public void SetUpCloudContent(){
Firebase.setAndroidContext(this);
new Firebase(FirebaseLink/*[COLOR=Red]https://YOUR_APP_NAME.firebaseio.com/[/COLOR]*/ + FirebaseTitle/*[COLOR=Red]GeeksEmpire[/COLOR]*/).addChildEventListener(new ChildEventListener() {
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
adapter.add((String)dataSnapshot.child(FirebaseSub/*[COLOR=Red]gX[/COLOR]*/).getValue());//add each value to ListView
}
public void onChildRemoved(DataSnapshot dataSnapshot) {
adapter.remove((String)dataSnapshot.child(FirebaseSub).getValue());
}
public void onChildChanged(DataSnapshot dataSnapshot, String s) { }
public void onChildMoved(DataSnapshot dataSnapshot, String s) { }
public void onCancelled(FirebaseError firebaseError) { }
});
}
To Change Data Just Use ID you got to User (For Example GeeksEmpire > gX) and OverWrite Data.
But here is a method to Delete Data.
// Delete items when clicked
Code:
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
new Firebase([COLOR=Red]FirebaseLink [/COLOR]+ [COLOR=Red]FirebaseTitle[/COLOR])
.orderByChild([COLOR=Red]FirebaseSub[/COLOR])
.equalTo((String) listView.getItemAtPosition(position)/*[I]get data from ListView[/I]*/)
.addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChildren()) {
DataSnapshot firstChild = dataSnapshot.getChildren().iterator().next();
firstChild.getRef().removeValue();
}
}
public void onCancelled(FirebaseError firebaseError) { }
});
return false;
}
});
Sending & Receiving Data to Firebase Cloud Service is Done.
Again It depends on you How to define Users & Create Individual ID for each one.
Next Posts Will Show How to Create Sign-In Options for your App. That Also Help a lot to create Individual ID.
Thanks for Supporting GeeksEmpire projects
​Don't Forget To Hit Thanks​
Google Account [Authentication]
​I used Google API for Google Account Auth cause you can get more info about Google Account to use and customize your App. Info that you cannot retrieve by Firebase.Auth("google"). For Example Account Pic to Use inside your app for user.
(Set Google Account Pic as Pic of Account on your App)
In First Post Google Sign-In Setup Completed.
Sign-In API Enabled & Configuration file add to Project.
Another modification needed to apply on build.gradle (Module: App)
Add this plugin at end of your gradle file.
Code:
apply plugin: 'com.google.gms.google-services'
& Also for build.gradle (Project)
Add this classpath under dependencies {}
Code:
classpath 'com.google.gms:google-services:2.0.0-alpha5'
You should Implement you class to GoogleApiClient.ConnectionCallbacks & GoogleApiClient.OnConnectionFailedListener.
& Add required methods.
Code:
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {}
@Override
public void onConnected(@Nullable Bundle bundle) {}
@Override
public void onConnectionSuspended(int i) {}
Define GoogleApiClient as universal variable (Outside of any Function).
Get instance of GoogleApiClient & GoogleSignInOptions onCreate(Bundle).
Code:
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, this)//FragmentActivity
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
To perform Sign Action normally button used If you don't want to do it at start up of app.
For this Google Service has its own button design that used in sample. However you can design your own view.
Code:
<com.google.android.gms.common.SignInButton />
Like other Android system function calling we should use Intent to Invoke Google Account Chooser and Get Result on CallBack.
Code:
google.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, [COLOR=Red]7[/COLOR]);
}
});
On result CallBack you should declare GoogleSignResult
Code:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == [COLOR=Red]7[/COLOR]){
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if(result.isSuccess()){
//[B]Handle Security Inside App[/B]
GoogleSignInAccount acct = result.getSignInAccount();
Toast.makeText(getApplicationContext(), "getEmail >> " + [B]acct.getEmail()[/B], Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), "getDisplayName >> " + [B]acct.getDisplayName()[/B], Toast.LENGTH_LONG).show();
//Can get more Info by using GoogleSignInAccount
}
}
NOTE: You can use Google Account as UserName for your Users on Firebase & By Calling Sign-In Process at App Start Provide Security for your App.
Thanks for Supporting GeeksEmpire projects
​Don't Forget To Hit Thanks​
Twitter Account [Authentication]
​ Authentication by Twitter has Complex aspect.
First you should Create Twitter Account, Then Create Web App through www.twitter.com (to get Public & Secret Key), Enable Twitter on Firebase (Not Required But I recommend it) & Install 3rd-Party Plugin on Android Studio (Fabric API).
Go to https://twitter.com/ & Sign Up then go to https://apps.twitter.com/ & Create App.
Name the App & Write Description & WebSite.
In App Page > Keys & Access Token
. Consumer Key (API Key) = XXXXX
. Consumer Secret (API Secret) = XXXXX
Save these value to resources of your app. res > values > string
Code:
</resources>
<string name="twitter_consumer_key">[B]API Key[/B]</string>
<string name="twitter_consumer_secret">[B]API Secret[/B]</string>
</resources>
- Go to Login & Auth on Firebase Select Twitter & Paste API Key + API Secret.
On Android Studio navigate to File > Setting > Plugin& Search for Fabric (Click Browse)
After Plugin Downloaded It will ask for Restart to Complete Installation.
Then Fabric Plugin icon will appear on toolbar & maybe Right-Panel. ​
​Click on Plugin & Sign Up. Then you will see your current project on Fabric list. Select it & click Next.
From List of All Kits select Twitter & click Install. It will ask for API Key + API Secret
Fabric will Apply All Modification it needs to your project & after that you project will be ready for Twitter Auth.
But for Developer It is always important points to understand every part of tools and apps.
* Fabric Inside build.grade (Module: App)
before Android Plugin
Code:
apply plugin: 'com.android.application'
Add this Script
Code:
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'io.fabric.tools:gradle:1.+'
}
}
after Android Plugin set up fabric plugin
Code:
apply plugin: 'io.fabric'
after android{} functions add Fabric Repositories
Code:
repositories {
mavenCentral()
maven { url 'https://maven.fabric.io/public' }
}
& Inside dependencies{} add
Code:
compile('com.twitter.sdk.android:twitter:[email protected]') {
transitive = true;
}
* Fabric Inside Manifest
in <application/> add
Code:
<meta-data
android:name="io.fabric.ApiKey"
android:value="API_KEY" />
* Fabric Inside MainActivity Class
before setContentView(VIEW) under onCreate(Bundle)
Code:
TwitterAuthConfig authConfig = new TwitterAuthConfig([COLOR=Red]API_KEY[/COLOR], [COLOR=Red]API_SECRET[/COLOR]);
Fabric.with(this, new Twitter(authConfig));
Fabric Also provides Button design for Twitter with custom features to handle Auth CallBack.
Code:
<com.twitter.sdk.android.core.identity.TwitterLoginButton/>
You define it in layout.xml & then Declare it like normal views on activity.
But performing action is different.
Code:
/*TWITTER Sign-In*/
twitterButton.setCallback(new Callback<TwitterSession>() {
@Override
public void success(Result<TwitterSession> result) {
Toast.makeText(getApplicationContext(), [COLOR=Red][B]result[/B][/COLOR].data.getUserName(), Toast.LENGTH_LONG).show();
}
@Override
public void failure(TwitterException exception) {}
});
without any extra Intent it will redirect you to Twitter Auth Page.
Also By using this button you can handle CallBack Result.
Code:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
twitterButton.onActivityResult(requestCode, resultCode, [COLOR=Red][B]data[/B][/COLOR]);
}
Also I used Fabric for Twitter Auth cause I can retrieve more Info than Firebase.Auth("twitter").
Fabric Plugin Developed by Twitter Developers So It really works smoothly & really best way to Auth with Twitter Account.
Thanks for Supporting GeeksEmpire projects
​Don't Forget To Hit Thanks​
Email/Password Account [Authentication]
Auth with Email/Password Using Firebase API is so simple.
Go to Firebase Project Dashboard > Login & Auth & Enable Email & Password Authentication
Define 2 <EditText /> for Email & Password in layout.xml Don't forget to set inputType
Code:
[CENTER][LEFT]Email
<EditText
android:id="@+id/email"
android:inputType="textEmailAddress" />
[/LEFT]
[/CENTER]
Password
<EditText
android:id="@+id/password"
android:inputType="textPassword" />
Declare Firebase & then Set Auth method.
Code:
//Remember from first post
Firebase ref = new Firebase(FirebaseLink/*[COLOR=Red]https://FIREBASE_PROJECT_NAME.firebaseio.com/[/COLOR]*/);
Define Login/SignUp Button and onClick setup Email/Pass Auth
Code:
//E-MAIL SignUp
signup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "User Created", Toast.LENGTH_LONG).show();
String email = user.getText().toString();
String pass = password.getText().toString();
Firebase ref = new Firebase([COLOR=Red]FirebaseLink[/COLOR]);
ref.createUser([COLOR=Red][B]email[/B][/COLOR], [COLOR=Red][B]pass[/B][/COLOR], new Firebase.ValueResultHandler<Map<String, Object>>() {
@Override
public void onSuccess(Map<String, Object> result) {
System.out.println("Successfully created user account with uid: " + result.get("uid"));
}
@Override
public void onError(FirebaseError firebaseError) {
// there was an error
}
});
}
});
Code:
//E-MAIL Login
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String email = user.getText().toString();
String pass = password.getText().toString();
Firebase ref = new Firebase([COLOR=Red]FirebaseLink[/COLOR]);
ref.authWithPassword([COLOR=Red][B]email[/B][/COLOR], [COLOR=Red][B]pass[/B][/COLOR], new Firebase.AuthResultHandler() {
@Override
public void onAuthenticated(AuthData authData) {
System.out.println("User ID: " + authData.getUid() + ", Provider: " + authData.getProvider());
Toast.makeText(getApplicationContext(), "User Authenticated", Toast.LENGTH_LONG).show();
}
@Override
public void onAuthenticationError(FirebaseError firebaseError) {}});
}}
});
For this everything provided simply by Firebase API. You completely Handle all process.
Here are more helpful Functions.
Code:
public void [B]ResetPassword[/B](String [COLOR=Red]E_MAIL_ADDRESS[/COLOR]){
Firebase ref = new Firebase("https://[COLOR=Red]<YOUR-FIREBASE-APP>[/COLOR].firebaseio.com");
ref.resetPassword([COLOR=Red]E_MAIL_ADDRESS[/COLOR], new Firebase.ResultHandler() {
@Override
public void onSuccess() {
// password reset email sent
}
@Override
public void onError(FirebaseError firebaseError) {
// error encountered
}
});
}
Code:
public void [B]ChangePassword[/B](String [COLOR=Red]E_MAIL[/COLOR], String [COLOR=Red]oldPass[/COLOR], String [COLOR=Red]newPass[/COLOR]){
Firebase ref = new Firebase("https://[COLOR=Red]<YOUR-FIREBASE-APP>[/COLOR].firebaseio.com");
ref.changePassword([COLOR=Red]E_MAIL[/COLOR], [COLOR=Red]oldPass[/COLOR], [COLOR=Red]newPass[/COLOR], new Firebase.ResultHandler() {
@Override
public void onSuccess() {
// password changed
}
@Override
public void onError(FirebaseError firebaseError) {
// error encountered
}
});
}
Code:
public void [B]RemoveAccount[/B](String [COLOR=Red]E_MAIL[/COLOR], String [COLOR=Red]Password[/COLOR]){
Firebase ref = new Firebase("https://[COLOR=Red]<YOUR-FIREBASE-APP>[/COLOR].firebaseio.com");
ref.removeUser([COLOR=Red]E_MAIL[/COLOR], [COLOR=Red]Password[/COLOR], new Firebase.ResultHandler() {
@Override
public void onSuccess() {
// user removed
}
@Override
public void onError(FirebaseError firebaseError) {
// error encountered
}
});
}
Thanks for Supporting GeeksEmpire projects
​Don't Forget To Hit Thanks
​
Info
If you find any mistake Or issue in my codes Please inform me.
Click to expand...
Click to collapse
I will try to Keep this Tutorials Up-to-Date.
Also Add Guide for Other Cloud Services.
Check Out my Open Source Android Applications & Tutorials in my Signature. :good:
Google Firebase.Storage
​
It s time to do something important with Cloud Service; Upload & Download File.
Google Cloud Service (Firebase) has lots of Useful Features + Really Straight & Manageable API.
First Read Preface Post & Firebase Basics to Prepare your Project for Cloud Services.
Now you will Understand upcoming codes.
Inside build.gradle of AppLevel declare Firebase.Storage SDK in dependencies
Code:
compile 'com.google.firebase:firebase-[B]storage[/B]:9.0.2'
compile 'com.google.firebase:firebase-[B]auth[/B]:9.0.2'
In update Sample Code I created new activity to handle Files. You can do whatever you like.
NOTE: You have to Authenticate Users with Firebase Services to Perform any Server action. For example Uploading File. check out SourceCode
In activity onCreate() declare instance of Firebase.Storage & Firebase.Auth
Code:
firebaseStorage = [B]FirebaseStorage[/B].getInstance();
firebaseAuth = [B]FirebaseAuth[/B].getInstance();
To Perform Both Upload & Download Task you need to create a Reference.
There is different method for creating StorageReference that I chose:
Code:
getReferenceFromUrl() for Uploading
& getFile() for Downloading.
Before anything do Auth Process. As Public APP I used Anonymously option & call the function when Activity Start.
Code:
private void signInAnonymously() {
mAuth.signInAnonymously().addOnSuccessListener(this, new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {}
}).addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {}
});
}
Now you can Add StorageReference & Perform Actions
UPLOAD Function check out SourceCode
Code:
private void uploadFromUri(InputStream fileUri) {
StorageReference mStorageRef = storage.getReferenceFromUrl("gs://[I][COLOR=Red][B][YOUR_FIREBASE_PROJECT_LINK][/B][/COLOR][/I]/");
StorageReference photoRef = mStorageRef.child("Dir").child("File");
UploadTask uploadTask = photoRef.putStream(fileUri);
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
System.out.println("DONE!");
//Get Download Address for Future
Uri dl = taskSnapshot.getMetadata().getDownloadUrl();
//Save Download Address in App Dir
SharedPreferences sharedpreferences = getSharedPreferences("Info", Context.MODE_PRIVATE);
SharedPreferences.Editor dlLink = sharedpreferences.edit();
dlLink.putString("path", String.valueOf(dl));
dlLink.apply();
infoFile.append("\n" + dl.getPath());
System.out.println("Download >> " + dl);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
System.out.println("!Damn!");
}
});
}
DOWNLOAD Function check out SourceCode
Code:
public void downloadFromUri(StorageReference storageRef) throws Exception {
//Create File
final File localFile = new File(Environment.getExternalStorageDirectory().getPath() + "/CloudAppTest_GeeksEmpire.jpg");
storageRef.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
@Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
System.out.println("DONE!");
//Using Downloaded File
Bitmap bitmap = BitmapFactory.decodeFile(localFile.getAbsolutePath()); System.out.println("Downloaded >> " + localFile.getAbsolutePath());
imageFile.setImageBitmap(bitmap);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle any errors
}
});
}
For Deleting & any Modification you Just Need to Declare StorageReference & Call Functions. check out SourceCode
Thanks for Supporting GeeksEmpire projects
​Don't Forget To Hit Thanks​
Firebase.RemoteConfiguration
​
The Most Interesting Features from Google Firebase is Remote Configuration.
It is not difficult to Apply & Super Helpful.
By Adding this Feature to your App you can Remotely Change Value of Defined Variable.
It can be String of InApp Texts Or Integer of InApp Color. Whatever you decide to remotely Config.
And Also Conditional Value. For Example Specific Price Tag for a Region Or even a Single User.
Google Cloud Service (Firebase) has lots of Useful Features + Really Straight & Manageable API.
Firebase Remote Config is a cloud service that lets you change the behavior and appearance of your app without requiring users to download an app update...
Click to expand...
Click to collapse
First Read Preface Post & Firebase Basics to Prepare your Project for Cloud Services.
Now you will Understand upcoming codes.
Inside build.gradle of AppLevel declare Firebase.Storage SDK in dependencies.
Code:
compile 'com.google.firebase:firebase-config:9.0.2'
Create xml folder into the res directory res/xml.
Now create remote_config_default.xml file to define all default Value & KEY for remote configuration.
For Example: check out SourceCode
Code:
<?xml version="1.0" encoding="utf-8"?>
<!-- START xml_defaults -->
<defaultsMap>
<entry>
[B]<key>[COLOR=Red]KeyToChange[/COLOR]</key>
<value>[COLOR=Red]Content To Change[/COLOR]</value>[/B]
</entry>
</defaultsMap>
<!-- END xml_defaults -->
You Should go to Firebase Console & you Project Dir & Select Remote Config from Left Panel.
Set <key>KeyToChange</key>& Create New Content.
Now go to your Activity Class that want to Handle these changes from cloud & declare FirebaseRemoteConfig & Set Default Value that defined in XML file. check out SourceCode
Code:
firebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
firebaseRemoteConfig.setDefaults(R.xml.remote_config_default);
after that you can perform to check If there is New Content & Apply it to your App. check out SourceCode
Code:
public void GetNewContent(){
mFirebaseRemoteConfig.fetch(cacheExpiration)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d("", "Fetch Succeeded");
// Once the config is successfully fetched it must be activated before newly fetched
// values are returned.
mFirebaseRemoteConfig.activateFetched();
} else {
Log.d("", "Fetch failed");
}
[B]//Handle New Content[/B]
textView.setText([B]firebaseRemoteConfig.getString([COLOR=Red]KeyToChange[/COLOR]_String)[/B]);
}
});
}
Thanks for Supporting GeeksEmpire projects
​Don't Forget To Hit Thanks
​
RESERVED 9th
RESERVED 10th
Needed
This tutorial is awesome!
complete and easy to understand
there is few guide about using cloud services
really appreciate :good:
getapp said:
This tutorial is awesome!
complete and easy to understand
there is few guide about using cloud services
really appreciate :good:
Click to expand...
Click to collapse
Thanks for Rating & Review
I am waiting for FeedBackof all users/devs
:good:
Info
James5712 said:
Really good
Click to expand...
Click to collapse
Thanks for Rating & Review :good:
I am waiting for FeedBack of all Users/Devs
Info
Featured By XDA
​
Top Forum Discussions
Aamir Siddiqui | May 19, 2016
XDA Senior Member Geeks Empire has posted an extensive tutorial on developing a cloud based app.
The tutorial teaches users how to make use of Google Cloud and Firebase to achieve their goals.
Click to expand...
Click to collapse
Thanks for Support XDA-Developer :good:
I am waiting for FeedBack of all Users/Devs
Thanks for your effort :good:
I'm newbie in android programming, but i find this tutorial is usefull :good:
Info
iprabu said:
Thanks for your effort :good:
I'm newbie in android programming, but i find this tutorial is usefull :good:
Click to expand...
Click to collapse
Thanks for Rating & Review
+ There is lots of Android Programming Tutorial by GeeksEmpire
you can find all off them in my signature Or Geeky Tutorial
Also Almost All GeeksEmpire Apps on Google Play Store is OpenSource with Full Code Comments
So you can Check them to learn more
you can find all off them in my signature Or Geeky Open Source Project
Don't Forget to hit Thanks :good:
I am waiting for FeedBack of all Users/Devs
thank you
thank you
black_host said:
thank you
Click to expand...
Click to collapse
Your Welcome.
Remember There is more to come to cover all aspect of Cloud Base Developing
+ Don't Forget to hit Thanks
I am waiting for FeedBack of all Users/Devs
Nice Tutorial will definitely recommend to new devs
Info
AonSyed said:
Nice Tutorial will definitely recommend to new devs
Click to expand...
Click to collapse
Thanks for Rating & Review :good:
These Tutorials are beginning of great lesson for Cloud Base App
I am waiting for FeedBack of all Users/Devs

[Tutorial][APP] Split Shortcuts | How to Open Two Apps in Split Screen [API 24+]

{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Split-Screen Or Multi-Window introduced on Android 7 (API 24) for All Android devices.
Samsung added new Software features on Galaxy Note 8 that allows users to select pair of apps to open in simultaneously in split screen. Check it out
This Tutorial is about How to create an app to open two apps in multi-window mode.
Click to expand...
Click to collapse
But If you want to configure your current app to support multi-window you need to read this documentation.
Android 7.0 adds support for displaying more than one app at the same time. On handheld devices, two apps can run side-by-side or one-above-the-other in split-screen mode. On TV devices, apps can use picture-in-picture mode to continue video playback while users are interacting with another app.
If your app targets Android 7.0 (API level 24) or higher, you can configure how your app handles multi-window display. For example, you can specify your activity's minimum allowable dimensions. You can also disable multi-window display for your app, ensuring that the system only shows your app in full-screen mode.
Read More
Click to expand...
Click to collapse
# Let Start #​
What do you need to get started...
- Know How to Create Hello World Project
- Basic Info about Android Apps Files (.Java, .xml)/Components (Activity, Service)
Click to expand...
Click to collapse
What will you learn...
- Create & Configure AccessibilityService
- Create with custom BroadcastReceiver
Click to expand...
Click to collapse
- Right Click on package name of app & Create a Java Class for AccessibilityService
Code:
public class [COLOR="royalblue"]SplitScreenService [/COLOR]extends [B]AccessibilityService [/B]{
@Override
protected void onServiceConnected() {
System.out.println("onServiceConnected");
//system will call this whenever you turn on Accessibility for this app
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
switch (event.getEventType()){
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
//this is a sample event that you can perform some action whenever it called
//and i will create split-screen here
[COLOR="DarkRed"]performGlobalAction(GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN);[/COLOR]
//this is how you can enter split-screen mode
break;
}
}
@Override
public void onInterrupt() {
System.out.println(">>> onInterrupt");
}
@Override
public void onCreate() {
super.onCreate();
System.out.println("onCreate");
}
@Override
public void onDestroy(){
super.onDestroy();
}
}
- Right Click on /res/... folder, create another folder and name it xml then you will have /res/xml/...
Then right click on /xml/... folder and create an xml file and choose a name (split.xml)
This xml file contains configuration of AccessibilityService.
Code:
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="[COLOR="red"]typeAllMask[/COLOR]" // all mask means to get all event which most of time you don't need it.
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagRetrieveInteractiveWindows|flagDefault"
android:settingsActivity="com.example.android.globalactionbarservice"
android:description="@string/describe_what_will_you_do" //here you must describe to user what will you do with this special permission />
- Open AndroidManifest.xml to define AccessbilityService & Add required permissions
Inside <application/> tag add this.
Code:
<service
android:name="com.example.android.split.SplitScreenService" //change it to your package name and class
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"/>
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/split"/> //add name of configuration file split.xml
</service>
Note that this app will only work when user enables Accessibility for it manually.
So first thing on Main Activity of the app must be to check this and redirect users to Accessibility Setting.
Open Main Activity of app and @oncreate() add this
Code:
final AccessibilityManager accessibilityManager = (AccessibilityManager)getSystemService(ACCESSIBILITY_SERVICE);
if([COLOR="Red"]!accessibilityManager.isEnabled()[/COLOR]){
Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
finish();
return;
}
after this app should enter split-screen & try to open another apps inside split-screen.
that s why I set BroadcastReceiver to send proper action in right time after entering split-screen mode.
So to perform this app must have proper BroadcastReceiver & AccessibilityEvent listener.
//Custom BroadcastReceiver in activity
Code:
@Override
protected void onCreate(Bundle Saved){
super.onCreate(Saved);
final AccessibilityManager accessibilityManager = (AccessibilityManager)getSystemService(ACCESSIBILITY_SERVICE);
if(!accessibilityManager.isEnabled()){
Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
finish();
return;
}
else {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("[B]open_split[/B]");
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("open_split")){
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent spliteOne = [COLOR="seagreen"]getPackageManager().getLaunchIntentForPackage[/COLOR]("com.whatsapp");// change to whatever you want
spliteOne.addCategory(Intent.CATEGORY_LAUNCHER);
spliteOne.setFlags(
Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT |
Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
final Intent spliteTwo = [COLOR="SeaGreen"]getPackageManager().getLaunchIntentForPackage[/COLOR]("com.google.android.youtube");[B]3*[/B]// change to whatever you want
spliteTwo.addCategory(Intent.CATEGORY_LAUNCHER);
spliteTwo.setFlags(
Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | [B]1*[/B]
Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
startActivity(spliteOne);
new Handler().postDelayed(new Runnable() { [B]2*[/B]
@Override
public void run() {
startActivity(spliteTwo);
}
}, 200);
}
}, 500);
}
}
};
registerReceiver(broadcastReceiver, intentFilter);
}
}
1* These are required flags to open an activity inside split-screen If the split screen already available.
Code:
.setFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
2* I set some delays for smoother performance of app and system & allow system to completely enter split-screen mode.
3* I set YouTube and WhatsApp for examples. you can set another apps or let users to select from a list. But there might be problem with some apps to enter split-screen mode cause they are not compatible. system will try to force them which is successful most of the time.
//AccessibilityEvent Listener in AccessibilityService
Code:
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
switch (event.getEventType()){
case AccessibilityEvent.[B]TYPE_WINDOW_STATE_CHANGED[/B]:
//system will call this event whenever something change open or close
//so app need to identify when to perform action to avoid lots of conflict
//event.getClassName() is name of the class that send this event which is OpenActivities for my app
if(event.getClassName().equals("com.example.android.split.OpenActivities")){
performGlobalAction([COLOR="RoyalBlue"]GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN[/COLOR]);[B]1*[/B]//this is the function to ask system to enter to split-screen
[B]sendBroadcast[/B](new Intent("[B]open_split[/B]"));[B]2*[/B]//to send action after asking system to enter split-screen
}
}
break;
}
}
1* System going to enter Split-Screen mode.
2* App will send action to activity to open other apps with proper Intent.Flags... in split-screen.
Download
Sample Source Code | Sample Apk File (WhatsApp & YouTube)
Oo. Download | Split Shortcuts .oO
Floating Shortcuts | Super Shortcut
Promo Code Available
Thanks for Support my Projects​Don't forget to Hit Thanks​
Reserved
Reserved
Please, send me a promo code
Open Pair of Apps Simultaneously from Floating Shortcuts
New Update | Floating Shortcuts​
Floating Shortcuts added Split Shortcuts for Android 7 & Higher
- Go to Floating Category
- Click on ( + )
- from apps of category, select Pair of Apps
.oO Download Oo.​Free Edition (Ads) | PRO Edition ($3.00)
Don't forget ti Hit Thanks​
Open Pair of Apps Simultaneously from Super Shortcuts
New Update | Super Shortcuts​
Super Shortcuts added Split Shortcuts for Android 7 & Higher
- Create Pair of Apps
- Select Apps Pair from list and Press Confirm Button
- Press and Hold to Add each Apps Pair to Home Screen
.oO Download Oo.​Free Edition (Ads) | PRO Edition ($1.50)​
Don't forget ti Hit Thanks​
Geeks Empire said:
Split-Screen Or Multi-Window introduced on Android 7 (API 24) for All Android devices.
Samsung added new Software features on Galaxy Note 8 that allows users to select pair of apps to open in simultaneously in split screen. Check it out
But If you want to configure your current app to support multi-window you need to read this documentation.
# Let Start #​
- Right Click on package name of app & Create a Java Class for AccessibilityService
Code:
public class [COLOR="royalblue"]SplitScreenService [/COLOR]extends [B]AccessibilityService [/B]{
@Override
protected void onServiceConnected() {
System.out.println("onServiceConnected");
//system will call this whenever you turn on Accessibility for this app
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
switch (event.getEventType()){
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
//this is a sample event that you can perform some action whenever it called
//and i will create split-screen here
[COLOR="DarkRed"]performGlobalAction(GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN);[/COLOR]
//this is how you can enter split-screen mode
break;
}
}
@Override
public void onInterrupt() {
System.out.println(">>> onInterrupt");
}
@Override
public void onCreate() {
super.onCreate();
System.out.println("onCreate");
}
@Override
public void onDestroy(){
super.onDestroy();
}
}
- Right Click on /res/... folder, create another folder and name it xml then you will have /res/xml/...
Then right click on /xml/... folder and create an xml file and choose a name (split.xml)
This xml file contains configuration of AccessibilityService.
Code:
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="[COLOR="red"]typeAllMask[/COLOR]" // all mask means to get all event which most of time you don't need it.
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagRetrieveInteractiveWindows|flagDefault"
android:settingsActivity="com.example.android.globalactionbarservice"
android:description="@string/describe_what_will_you_do" //here you must describe to user what will you do with this special permission />
- Open AndroidManifest.xml to define AccessbilityService & Add required permissions
Inside <application/> tag add this.
Code:
<service
android:name="com.example.android.split.SplitScreenService" //change it to your package name and class
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"/>
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/split"/> //add name of configuration file split.xml
</service>
Note that this app will only work when user enables Accessibility for it manually.
So first thing on Main Activity of the app must be to check this and redirect users to Accessibility Setting.
Open Main Activity of app and @oncreate() add this
Code:
final AccessibilityManager accessibilityManager = (AccessibilityManager)getSystemService(ACCESSIBILITY_SERVICE);
if([COLOR="Red"]!accessibilityManager.isEnabled()[/COLOR]){
Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
finish();
return;
}
after this app should enter split-screen & try to open another apps inside split-screen.
that s why I set BroadcastReceiver to send proper action in right time after entering split-screen mode.
So to perform this app must have proper BroadcastReceiver & AccessibilityEvent listener.
//Custom BroadcastReceiver in activity
Code:
@Override
protected void onCreate(Bundle Saved){
super.onCreate(Saved);
final AccessibilityManager accessibilityManager = (AccessibilityManager)getSystemService(ACCESSIBILITY_SERVICE);
if(!accessibilityManager.isEnabled()){
Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
finish();
return;
}
else {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("[B]open_split[/B]");
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("open_split")){
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent spliteOne = [COLOR="seagreen"]getPackageManager().getLaunchIntentForPackage[/COLOR]("com.whatsapp");// change to whatever you want
spliteOne.addCategory(Intent.CATEGORY_LAUNCHER);
spliteOne.setFlags(
Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT |
Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
final Intent spliteTwo = [COLOR="SeaGreen"]getPackageManager().getLaunchIntentForPackage[/COLOR]("com.google.android.youtube");[B]3*[/B]// change to whatever you want
spliteTwo.addCategory(Intent.CATEGORY_LAUNCHER);
spliteTwo.setFlags(
Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | [B]1*[/B]
Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
startActivity(spliteOne);
new Handler().postDelayed(new Runnable() { [B]2*[/B]
@Override
public void run() {
startActivity(spliteTwo);
}
}, 200);
}
}, 500);
}
}
};
registerReceiver(broadcastReceiver, intentFilter);
}
}
1* These are required flags to open an activity inside split-screen If the split screen already available.
Code:
.setFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
2* I set some delays for smoother performance of app and system & allow system to completely enter split-screen mode.
3* I set YouTube and WhatsApp for examples. you can set another apps or let users to select from a list. But there might be problem with some apps to enter split-screen mode cause they are not compatible. system will try to force them which is successful most of the time.
//AccessibilityEvent Listener in AccessibilityService
Code:
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
switch (event.getEventType()){
case AccessibilityEvent.[B]TYPE_WINDOW_STATE_CHANGED[/B]:
//system will call this event whenever something change open or close
//so app need to identify when to perform action to avoid lots of conflict
//event.getClassName() is name of the class that send this event which is OpenActivities for my app
if(event.getClassName().equals("com.example.android.split.OpenActivities")){
performGlobalAction([COLOR="RoyalBlue"]GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN[/COLOR]);[B]1*[/B]//this is the function to ask system to enter to split-screen
[B]sendBroadcast[/B](new Intent("[B]open_split[/B]"));[B]2*[/B]//to send action after asking system to enter split-screen
}
}
break;
}
}
1* System going to enter Split-Screen mode.
2* App will send action to activity to open other apps with proper Intent.Flags... in split-screen.
Download
Sample Source Code | Sample Apk File (WhatsApp & YouTube)
Oo. Download | Split Shortcuts .oO
Floating Shortcuts | Super Shortcut
Promo Code Available
Thanks for Support my Projects​Don't forget to Hit Thanks​
Click to expand...
Click to collapse
Dear,
Can you share please the code?
Thank you.
lebossejames said:
Dear,
Can you share please the code?
Thank you.
Click to expand...
Click to collapse
You can find it on Github https://github.com/GeeksEmpireOfficial/SuperShortcutsFree

Categories

Resources